I have a view that protects certain sensitive files from public download, using nginx’ X-Accel-Redirect header. My URL looks like this:
url(r'^dl/f/(?P<pk>\d+)/(?P<filename>[^/]+)$', 'file_download.views.download', name='download-filename'),
pk is the primary key of the file object in the database, filename is the file name, which matches anything but the forward slash. It’s mainly there so that the browser knows the file name in case the user wants to save it. Note that there is no terminal slash.
When I open a matching URL in the browser, Django nevertheless redirects it to the same URL with a slash appended. The file is displayed in the browser (it’s a PDF), but if I want to save it, the browser suggests a generic “download.pdf” instead of the file name.
I don’t want to disable APPEND_SLASH for the general case, but can I somehow get around it for this single case?
/edit: unfortunately, I can’t use the Content-Disposition: attachment header, because all other files are served without that header as well, and consistent behavior for both protected and unprotected files is a requirement.
I don’t know where/if it’s in the docs, but I believe that putting an extension into the URL will prevent this behavior, so instead of
some-filename/, usesome-filename.pdf(and alter the urlpattern accordingly, of course).However, I’m not entirely sure about that. Really, your primary problem seems to be that the download’s filename is not set properly, and that can be fixed without messing with the URLs one way or another. Just store the response instead of returning it immediately, and then alter the
Content-Dispositionheader:UPDATE
Concerning the two points in your comment:
The urlpattern can accept a wildcard extension
\.\w{3,4}.‘attachment’ is what forces a download. ‘inline’ can be used to make the file load in the browser. The filename can be asserted either way.