Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Files accessed via 'file/FID/download' are saved with the name 'download' rather than a meaningful file name. File Entity sets it's headers and then runs a module_invoke_all() to let other modules modify the headers. Nginix Accel Redirect breaks the value of content-disposition.
File downloads should be delivered to the browser with a descriptive file name. This module needs to respect the name of the file inside the headers during download.
Using latest 7.x-2.x-dev of File Entity and Media.
Again, please note that this bug only exists if you use both File Entity and Nginx Accel Redirect.
Comment | File | Size | Author |
---|---|---|---|
#5 | dl_names-2278625-5.patch | 1.63 KB | sheldonkreger |
Comments
Comment #1
sheldonkreger CreditAttribution: sheldonkreger commentedI've isolated this to a bug with another module (nginx_accel_redirect). When FE executes
module_invoke_all('file_transfer', $file->uri, $headers);
The headers can obviously be broken by other modules. I'm going to dig deeper and perhaps move this over to the nginx_accel_redirect module issue queue.
Comment #2
sheldonkreger CreditAttribution: sheldonkreger commentedComment #3
sheldonkreger CreditAttribution: sheldonkreger commentedComment #4
sheldonkreger CreditAttribution: sheldonkreger commentedThis is a bit tricky.
Inside nginx_accel_redirect.module, we look for any implementations of hook_file_download() to gather headers. That makes good sense. This code is taken from nginx_accel_redirect_file_transfer() :
However, for files accessed via /file/FID/download . . . File Entity has implemented a menu callback with a custom function that *isn't* hook_file_download() :
(file_entity.module line 232)
(file_entity_pages.inc)
As you can see, the headers are set inside this function. THEN, module_invoke_all() is executed. This is when nginx_accel_redirect_file_transfer() is finally executed. So, this function doesn't respect the headers which file_entity set earlier up the ladder.
I see two options for fixing this.
1. Move the code from file_entity_download_page() to file entity's hook_file_download() file_entity_file_download(). It seems reasonable to put the code responsible for file downloads inside hook_file_download(). However, I'm not sure of the implications of this (perhaps this hook was avoided intentionally).
2. Modify the logic which gathers headers inside nginx_accel_redirect_file_transfer() to check for both hook_file_download() and the custom file entity implementation of file_entity_download_page().
It's probably safer to modify nginx_accel_redirect rather than file_entity. But, it does seem logical to do #1.
Thoughts?
Comment #5
sheldonkreger CreditAttribution: sheldonkreger commentedThis patch applies to File Entity 7.x-2.x-dev so I have moved the issue back to File Entity. Please see comments above for an explanation of the problem.
This patch moves the declaration of headers for File Entity into its own function. This was being done inside the File Entity custom function file_entity_download_page() but now it stands alone (I did not change the code at all).
By moving it into its own function, I was able to use it inside file_entity_file_download() rather than file_get_content_headers(). This allows the hook system that Nginx Accel Redirect utilizes to work correctly, because it gathers ALL header modifications which happen inside any hook_file_download(). Setting headers with file_entity_get_content_headers() inside file_entity_file_download() solves the problem by ensuring that all required headers are set via the hook system other modules expect.
Using file_get_content_headers() leaves out critical headers for file entities (which is why it was basically over-ridden by File Entity already).
Comment #7
sheldonkreger CreditAttribution: sheldonkreger commentedHmm . . . not sure if the failing tests are a consequence of my code. I didn't modify anything relating to file access, so I suspect this problem is caused elsewhere.
Comment #8
sheldonkreger CreditAttribution: sheldonkreger commentedI re-submitted a test on another issue and that one passed. So I think it's safe to assume that my patch actually does break some access stuff. I'll take a look.
Comment #9
sheldonkreger CreditAttribution: sheldonkreger commented5: dl_names-2278625-5.patch queued for re-testing.
Comment #11
_KASH_ CreditAttribution: _KASH_ commentedI also need to have the file names instead of download. It would be nice to see this patch pass testing
Comment #12
Dave ReidI feel like we should address the *actual* issue here. nginx_accel_redirect_file_transfer is not meant to be a hook, but File entity invokes hook_file_transfer(). That is what is actually unexpected here and should be fixed. I would propose that nginx_accel_redirect rename this function, especially in light of hook_file_transfer() being a proposed core hook: #233997: New hook triggered on file download.
Comment #13
Dave ReidI just committed a temporary workaround for now in file_entity. I still think this should be addressed in this module's issue queue.
Comment #14
sheldonkreger CreditAttribution: sheldonkreger commented@Dave Can you post a link to that commit? I agree we should address the underlying issue.
Comment #15
Dave ReidCommit was http://drupalcode.org/project/file_entity.git/commit/a8809d2 - guess Drupal.org was confused since I changed projects on this issue right after I made the commit.
Comment #16
srclarkx CreditAttribution: srclarkx commentedMaybe I'm mistaken, but wouldn't it be fairly safe to rename the nginx_accel_redirect_file_transfer function something else? Shouldn't the function only be called from within that module? From what I've read above, the function was not intentionally meant to be a hook.