Add a filename-terminated agent download URL - #2442
Open
urbanadventurer wants to merge 1 commit into
Open
Conversation
The download link was agents.php?download=<id>. Clients that name the saved file from the URL rather than the Content-Disposition header get it wrong, because the last path segment is agents.php, not the filename: wget (without --content-disposition) also appends the query string and saves 'agents.php?download=1', while curl -O drops the query and saves 'agents.php'. Neither yields 'hashtopolis.zip'. Accept an additional agents.php/download/<id>/<filename> form via PATH_INFO and build the UI link that way, so the filename is the final path segment and no query string is present. The existing ?download=<id> form still works. The <filename> segment is cosmetic for the client; the served file and its Content-Disposition come from the binary record, as before. The path parsing lives in a pure Util::getAgentDownloadId() helper with PHPUnit coverage in UtilTest, rather than inline in agents.php. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
wget http://host/agents.php?download=1saves the file asagents.php?download=1instead ofhashtopolis.zip.The
Content-Disposition: attachment; filename="hashtopolis.zip"header isalready sent, but clients that name the file from the URL rather than the header
still get it wrong, because the last path segment is
agents.php, not thefilename:
wget(without--content-disposition) appends the query string too, savingagents.php?download=1.curl -Odrops the query string and savesagents.php.Neither yields
hashtopolis.zip.Fix
Accept an additional, filename-terminated URL:
The id is read from
PATH_INFOvia a new pure helperUtil::getAgentDownloadId(); the trailing<filename>is the last path segmentand there is no query string, so wget/curl save
hashtopolis.zipdirectly. TheUI's download link on the "new agent" page is switched to this form. The old
?download=<id>URL still works (the new branch only triggers when?downloadis absent).
AgentHandler::downloadAgent()is unchanged — the served bytes and theContent-Dispositionfilename still come from the binary record, so the<filename>in the URL is cosmetic for the client and can't be used to serve adifferent file (the numeric id, matched as
[0-9]+, selects the binary).Testing
ci/phpunit/inc/UtilTest.phpcoverUtil::getAgentDownloadId(): the/download/<id>/<file>,/download/<id>forms extract the id;
/download/abc/x,/other,"", andnullreturnnull.php -lpasses onsrc/agents.php,src/inc/Util.php, and the test.php -S+ a router mimicking mod_phpPATH_INFO:wgetandcurl -Oonagents.php/download/1/hashtopolis.zipboth savehashtopolis.zip, and the handler receives id1.Deployment note
This relies on the web server passing
PATH_INFOtoagents.php, which theshipped
php:8.5-apache(mod_php) image does by default — nomod_rewriteorApache-config change is needed. A reverse-proxied php-fpm setup that doesn't
forward
PATH_INFOwould simply not see the new URL and fall back to thestill-working
?download=<id>form, so this is strictly additive.Alternatives considered
agents/download/<id>/<filename>URL (no.php): requires amod_rewriterule in the vhost config (000-default.conf), changing thedeployment for every install. The
PATH_INFOform gives the sameclient-visible result with no config change.
agents.php: kept it inUtilinstead so it iscovered by PHPUnit and analysed by phpstan (both scan
src/inc).Content-Length/ switchingecho file_get_contents()toreadfile()in
downloadAgent(): doesn't address the filename problem, and for a ~30 KBstatic zip the streaming change makes no practical difference. Out of scope.