django.views.static.serve() redirects (HTTP code 302) to the wrong location when the path to the static file is "normalized"
|Reported by:||Chris Wagner <cw264701@…>||Owned by:||nobody|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
For instance, if I have a URL hook for static files set up at /collection/, and I enter a URL like /collection//path/to/file.mp3, django.views.static.serve() will normalize the /path/to/file.mp3 path down to path/to/file.mp3 and return an HttpResponseRedirect with the redirect path set to the normalized path path/to/file.mp3; that is, it's missing the /collection/ prefix that needs to be passed back to the Web browser.
Unfortunately, I see no clean way to fix this. The most obvious solution would require passing the URL prefix (/collection/, in this case) to the django.views.static.serve() function. That would be pretty ugly. It might be best to disable the redirect feature (?).
For whatever reason, when using Firefox (I didn't try any other browsers), this leads to some odd loop, which causes Django to send 302 forward messages with continuously longer paths (e.g., /collection//path/to/path/to/path/to/...). ...Actually, I think I just figured out why: It's because Firefox is trying to do the forward, and it tacks on the path/to/file.mp3 relative to the current location, so you end up with path/to/path/to/file.mp3; then, Django normalizes that again and sends another 302. Actually, this problem of infinite redirections (it eventually stops, because of some limit, but anyway) may only occur when you're dealing with filenames that have spaces; I'm not sure, but it may be the case because the spaces will be %20's in the original path and then normalized to spaces... Yeesh!
Oh, and, I believe this is the problem that the folks on #1291 were seeing. I opened a new ticket because I thought that'd be easier to understand.
By the way, I'm not sure but, I believe I read, somewhere, that HTTP Location headers should always contain a full URL, rather than a simple path. So, instead of saying Location: /path/to, Django should say Location: http://appserver/path/to. It doesn't seem to include the full URL, judging from my Firefox Live HTTP Headers extension; I see something like Location: path/to (exactly what is specified in the creation of the HttpResponseRedirect object, I believe). Maybe I should file another bug about this (?).
Change History (7)
comment:2 Changed 9 years ago by mtredinnick
- Resolution set to duplicate
- Status changed from new to closed
comment:4 follow-up: ↓ 5 Changed 9 years ago by mtredinnick
- Resolution duplicate deleted
- Status changed from closed to reopened
comment:6 Changed 9 years ago by anonymous
- Resolution set to fixed
- Status changed from reopened to closed