Looking at file_download(), it appears that the file_download hook only gets called on the first module in module_list() that defines it. In my case, user_file_download is getting called, and my custom module's file_download hook isn't getting called anymore.

I'm not sure if the regression is:
1. user_file_download has been added
or
2. file_download has changed somehow
or
3. there is no regression -- just that my module previously showed up before user.module in the return value for module_list()

In the third case, feel free to change the priority. But this still seems like a bug to me because the behavior of most other hooks is that all modules defining the hook get called, and the results get combined somehow. That's not happening here.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wesley Tanaka’s picture

Status: Active » Needs review
FileSize
808 bytes

this patch makes file_download() do what I thought it was supposed to be doing.

dopry’s picture

In what cases would you want to send multiple headers before a file download?

Could module weighting be used to solve your problem instead?

Wesley Tanaka’s picture

I have cache control headers I want to set, since the defaults seem to force images to download anew every single time you view a page in firefox.

I don't know what headers get set in user.module, but I don't want to have to learn just so that I can duplicate them in my own module.

Wesley Tanaka’s picture

Title: regression from 4.6: hook_file_download doesn't get called anymore. » regression from 4.6: hook_file_download gets called on at most one module

Could module weighting be used to solve your problem instead?

I don't know what module weighting is, but it sounds like a workaround to this bug might exist if you only have one module whos hook_file_download you want to call.

dopry’s picture

Hmm thats a plus one, because I can definately think of places I would like caching for files and not for the rest of drupal.org, and allowing other modules to set headers would be cool.

Some behavior to note that you are modifying...

1) allowing/denying of file downloads...
Before your patch, which ever module answered first with an allow or deny won...

Now we either need to select a defaul behavior, allow, deny or deny,allow
You patch is exhibits a deny, allow behavior...

ie) if any module denies the download, it won't be sent, where as before if a module returned headers before another module could deny the transfer was allowed.

2) You also introduce the possibility of several contribs adding conflicting headers, or duplicate headers....

A simpler approach may be to....

1) add allow,deny && deny,allow behavior settings
2) add private files cache control settings
3) modify file_download to just be a permissions check(false blocks access, true allows access)
4) augment file_transfer to send the mime content type and the appropriate cache setting.

As it is file_download looks badly broken... fortunately there is only one hook_download in core so the problems that can arise from this probably aren't noticed often...

dopry’s picture

FileSize
1.72 KB

He's another patch with an explicit deny,allow that will allow multiple headers to be passed to file_transfer.

dopry’s picture

Assigned: Unassigned » dopry

I'm gonna go ahead and assign this to myself... I've got the rest of the rc file isssues anyway.

Dries’s picture

Code looks good to me. Needs some testing.

sime’s picture

I can test this with the standard modules. But to be comprehensive I should also install a module which also uses that hook.

wtanaka, would it be feasible for you to provide a stable version of your custom module for testing?

Wesley Tanaka’s picture

FileSize
538 bytes

here you go

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
2.42 KB

I testd this one with organic groups module and upload module. attachments to protected nodes were blocked as expected. i rerolled with a tweak to upload_file_download() so that it takes advantage of the new API and shows an access denied message instead of 404.

RTBC

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to HEAD. Thanks.

Anonymous’s picture

Status: Fixed » Closed (fixed)
bramb’s picture

Version: x.y.z » 5.7
Assigned: dopry » bramb
Category: bug » feature
Status: Closed (fixed) » Needs review
FileSize
1.88 KB
2.64 KB

While your patch addresses the issue of your module's hook getting ignored, it still leaves a fundamental weakness in file_download() that has persisted until at least the latest version of Drupal 5 and even exacerbates it by indiscriminately piling up all headers returned.

It seems to me that a critical core function such as this should at least allow modules greater control over handling file downloads, instead of leaving it to, well, to chance almost, how a file's headers are set.

Attached is a patch that solves the problem by allowing the situation you introduced, i.e. calling module_invoke_all for hook_file_download, to coexist with a weighted solution (as proposed earlier in this thread) that at least allows module developers to keep control over such an essentially straightforward thing as setting file headers without having it messed up by other modules.

Also attached an example module that implements the new proposed hook_file_download_weight.

bramb’s picture

Assigned: bramb » Unassigned
FileSize
2.72 KB

After some more testing, another patch with a small addition (setting of $headers to an empty array if none of the modules with lowest weight returned anything).

drumm’s picture

Version: 5.7 » 7.x-dev
Status: Needs review » Needs work

New features should be added to the development version, currently 7.x. I would recommend opening a new issue for this.

catch’s picture

Version: 7.x-dev » 5.x-dev
Status: Needs work » Closed (fixed)

Yes, please post the patch in a new issue from http://drupal.org/node/add/project-issue/drupal