Django: disable APPEND_SLASH for certain URLs - django

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/, use some-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-Disposition header:
response = HttpResponse(mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
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.

Related

Always serve unversioned files raw?

I'm serving unversioned files via fossil's uv function. Now, this works fine for files without file extension and for archives. But I need to serve a .txt file. The problem now is that it gets delivered as a HTML page including the fossil web layout around it.
Is there a way to tell fossil to not do that, and instead deliver it as a raw .txt file?
You can specify a mimetype parameter on the URL. For example, mimetype=application/octet-stream will cause it to be offered as download.
For example, instead of https://www.fossil-scm.org/index.html/uv/download.html, you’d put https://www.fossil-scm.org/index.html/uv/download.html?mimetype=application/octet-stream.
Fossil reacts to the following mimetypes by putting headers around them:
text/x-fossil-wiki
text/x-markdown
text/html
text/plain
Unfortunately, all other mimetypes appear to lead to the browser downloading the unversioned file instead of displaying it.
If that's a problem, you could try a mimetype of text with no suffix.
Otherwise, you can post on Fossil's support forum. Either as a question or as a feature request. :-)

How to serve a text file at root with Django

I got a site, say it's "www.site.com". I need to serve a text file at the root, so that "www.site.com/text.txt" will show up.
I read through this answer: Django download a file, and I used the "download" function.
However I am at a loss how to configure the URL. Can someone help me out?
Say I put this this into my url.py,
url('^(?P<path>.*)/$', san.views.FileDownload.as_view()),
This then supersedes all my other url patterns and render them useless. How do I make this work? Thanks!
Put it as the last urlpattern in your urls.py to ensure it doesn't sccop up everything. It should not have the trailing / either, i.e.
url('^(?P<path>.*)/?$', san.views.FileDownload.as_view()),
This will match the request "/YOUR_FILE.txt", and is also case-insensitive.
url(r'^(?i)YOUR_FILE.txt$', san.views.FileDownload.as_view()),

How does one determine the filetype on an AWS S3 hosted file without the extension?

As an example, I'm currently uploading items directly to an S3 bucket using a form. While I was testing, I didn't specify any expected filenames or extensions.
I uploaded a .png which produced this direct link:
https://s3-us-west-2.amazonaws.com/easyhighlighting2/2015-07-271438019663927upload94788
When I place this inside an img tag, it displays on a web page properly.
My question is, without an extension, how would my browser know what type of file it's loading? Inside the bucket, the file's metadata isn't even filled out.
Is there any way to get that file extension, programmatically?
I'm ready to try any clientside methods available; my server-side language is ColdFusion which is somewhat limiting, but I'm open to suggestions for that as well.
Okay, so after some more extensive digging, I found a method of retrieving the file's type that was only added since CF10 was released; that would explain the lack of documentation.
The answer lies in the FileGetMimeType function.
<cfset someVar = "https://s3-us-west-2.amazonaws.com/easyhighlighting2/2015-07-271438019663927upload94788">
<cfset FileType = FileGetMimeType(someVar)>
<cfoutput>#FileType#</cfoutput>
This code would output image/png - which is correct and has worked for every filetype I have tested thus far.
I'm surprised this kind of question hasn't popped up before, but this appears to be the best answer, at least for users of CFML.
Edit:
ColdFusion accomplishes this by either reading the contents of a file, or by trusting its extension. An implicit attribute, 'strict', is used in this function. If true, it reads the file's contents. If false, it uses the provided extension.
True is the default.
Link:
https://wikidocs.adobe.com/wiki/display/coldfusionen/FileGetMimeType
Check the Content-Type HTTP response header returned by Amazon S3.
For example, curl -I https://s3.amazonaws.com/path/to/file fetches only the headers.

In Sitecore 7.2 file upload ,the path is coming as media\test\abc.pdf instead of media/test/abc.pdf

I am trying to add one file from file directory in directory.
While I am clicking on +(insert file) the and selecting a file from directory the path is formed as media\test\abc.pdf instead of media/test/abc.pdf.
Even though chrome is able to resolve the url Firefox is not.
I believe it's because you're using a physical file path that you're getting the backslash. One of the simplest things you can do is a string.Replace() expression to make every backslash a forward slash.
Not sure what your specific use case is, or how much work it would be, but if you're going to use the path on the web and your PDF is located in the MediaLibrary, it might be worth looking into using the URL property of the Sitecore.Data.Items.MediaItem object.

Is there a "clean URL" (mod_rewrite) equivalent for iPlanet?

I'm working with Coldfusion (because I have to) and we use iPlanet 7 (because we have to), and I would like to pass clean URL's instead of the query-param junk (for numerous reasons). My problem is I don't have access to the overall obj.conf file, and was wondering if there were .htaccess equivalents I could pass on the fly per directory. Currently I am using Application.cfc to force the server to look at index.cfm in root before loading the requested page, but this requires a .cfm file is passed, so it just 404's out if the user provides /path/to/file but no extension. Ultimately, I would like to allow the user to pass domain.com/path/to/file but serve domain.com/index.cfm?q1=path&q2=to&q3=file. Any ideas?
You can mod_dir with the DirectoryIndex directive to set which page is served on /directory/ requests.
http://httpd.apache.org/docs/2.2/mod/mod_dir.html
I'm not sure what exists for iPlanet, haven't had to work with it before. But it would be possible to use a url like index.cfm/path/to/file, and pull the extra path information via the cgi.path_info variable. Not exactly what you're looking for, but cleaner that query-params.