When the file download method is set to Private, files containg a "+" in their filename cannot be downloaded.
Drupals url() function incorrectly translates a "+" in a the filename to a space, this causes the file to not be found on the file system and in turn causes file_transfer() to return a 404.
When the download method is set to public, the same file can be downloaded without any problems.
I've had a half-hearted attempt at a patch that uses rawurlencode() to encode the filename passed to the url() function, but that causes the file that is to be saved to contain a "%2B" instead of a "+" when the download method is Public.
Comments
Comment #1
mikeparker CreditAttribution: mikeparker commentedHi, I'll have a look into this problem and see what I can find.
Comment #2
mikeparker CreditAttribution: mikeparker commentedHaving replicated the problem on a test system, I worked back from the url on the page.
Everything's fine in the database and file system (so, that's not where the problem is). When I got to the call to url() in file.inc, I got the same error returning a string with a + in it as I did calling the url function. (So, it doesn't look like it's the url function causing the bug).
I worked back to modules/upload/upload.module and the function theme_upload_attachments() which sets $href by calling file_create_url(), (using the url() function).
replacing $href with some dummy urls, containing a '+', the problem still comes up.
So the conclusion is that the code that's calling theme_upload_attachments from upload.module seems to be formatting the url incorrectly.
Comment #3
cafuego CreditAttribution: cafuego commentedI suspect it assumes a + is an encoded space and will treat it as such, so by the time the browser requests the file, it effectively asks for "This file name.pdf" rather than "This%2Bfile%2Bname.pdf".
I'm pretty sure I've worked around it by asking my client to not upload files with a + in their name and I'm also pretty sure I enabled transliteration on the filename.