5

I'm generating some pdfs using ReportLab in Django. I followed and experimented with the answer given to this question, and realised that the double-quotes therein don't make sense:

response['Content-Disposition'] = 'inline; filename=constant_"%s_%s".pdf'\
% ('foo','bar')

gives filename constant_-foo_bar-.pdf

response['Content-Disposition'] = 'inline; filename=constant_%s_%s.pdf' \
% ('foo','bar')

gives filename constant_foo_bar.pdf

Why is this? Is it just to do with slug-esque sanitisation for filesystems?

Community
  • 1
  • 1
nimasmi
  • 3,978
  • 1
  • 25
  • 41
  • No, I'm not really interested in having the quotes there (see that I first had the quotes from the answer to [this question](http://serverfault.com/questions/358580/django-dynamic-file-name)) just curious about what is going on and why. – nimasmi Aug 06 '12 at 21:32
  • 3
    I'm putting my money on it sanitizing clearly illegal or bad filenames – jdi Aug 06 '12 at 21:37

3 Answers3

2

It seems from the research in this question that it's actually the browser doing the encoding/escaping. I used cURL to confirm that Django itself does not escape these headers. First, I set up a minimal test view:

# views.py 
def index(request):
    response = render(request, 'template.html')
    response['Content-Disposition'] = 'inline; filename=constant"a_b".html'
    return response

then ran:

carl@chaffinch:~$ HEAD http://localhost:8003
200 OK
Date: Thu, 16 Aug 2012 19:28:54 GMT
Server: WSGIServer/0.1 Python/2.7.3
Vary: Cookie
Content-Type: text/html; charset=utf-8
Client-Date: Thu, 16 Aug 2012 19:28:54 GMT
Client-Peer: 127.0.0.1:8003
Client-Response-Num: 1
Content-Disposition: inline; filename=constant"a_b".html

Check out the header: filename=constant"a_b".html. The quotes are still there!

Community
  • 1
  • 1
supervacuo
  • 9,072
  • 2
  • 44
  • 61
0

Python does not convert double quotes to hyphens in filenames:

>>> with open('constant_"%s_%s".pdf' % ('foo', 'bar'), 'w'): pass
    $ ls
    ...
    constant_"foo_bar".pdf
    ...

Probably it's django that will not allow you to use too strange names.

Anyway I'd recommend to use only the following characters in filenames, to avoid portability issues:

  • Letters [a-z][A-Z]
  • digits [0-9]
  • hyphen(-), underscore(_), plus(+)

Note: I've excluded the whitespace in the list, because there are a lot of scripts that don't use proper quoting, and break with such filenames.

If you restrict yourself to this set of characters you probably wont ever have any problems with pathnames. Obviously other people or other programs may still not follow this "guideline" so you shouldn't assume this convention is shared by paths you obtain from users or other external sources.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
  • Repeating a similar test on Windows gives back an IOError complaining about a bad mode or filename. No auto-substitution there either. – Mark Ransom Aug 16 '12 at 19:43
-1

Your usage is slightly incorrect. You would want the quotes around the entire filename in order to account for spaces, etc.

change:

response['Content-Disposition'] = 'inline; filename=constant_"%s_%s".pdf'\
% ('foo','bar')

to:

response['Content-Disposition'] = 'inline; filename="constant_%s_%s.pdf"'\
% ('foo','bar')
randomfigure
  • 420
  • 5
  • 13
  • -1 OP specifically said "No, I'm not really interested in having the quotes there ... just curious about what is going on and why". – supervacuo Aug 16 '12 at 19:20
  • @supervacuo - matter of opinion. he seemed confused about why the quotes are necessary and it occurred to me that could be because he is using them incorrectly. – randomfigure Aug 17 '12 at 17:27
  • For the record, I first tried copying the code verbatim from [this question](http://serverfault.com/questions/358580/django-dynamic-file-name) and saw that the double-quotes appeared in the outputted filename, which wasn't what I (or I think that OP) intended. – nimasmi Aug 20 '12 at 12:30