Provide mechanism for private downloads of release node files on sites with public file access
dww - August 1, 2009 - 08:13
| Project: | Project |
| Version: | 6.x-1.x-dev |
| Component: | Releases |
| Category: | feature request |
| Priority: | normal |
| Assigned: | dww |
| Status: | closed |
Description
I'm working with TopNotchThemes on a Project* deployment that uses OG to restrict access to projects and release. They want public file access in general, but to restrict file downloads from release nodes.
I wrote a script to do this. It's pretty thin, and written generically, so I figured I'd just commit it upstream in case anyone else wants to make use of it.
Any objections?
Thanks,
-Derek
p.s. It currently depends on mod_xsendfile. I guess I could use apache_get_modules(), see if xsendfile is available, and if not, fallback to doing the lame buffering of the file through PHP using readfile() or something... Followup issue if anyone actually cares. ;)
| Attachment | Size |
|---|---|
| project-release-private-download.php.txt | 4.7 KB |

#1
Nice work. I think this would be good to have in project, though I haven't tested the code itself.
Two thoughts:
1. What happens if someone tries to use this but mod_xsendfile doesn't exist? If that would cause bad errors or something maybe it would be a good idea to have this script just return a 404 error if mod_sendfile can't be used?
2. It occurs to me that using this script would (I think) be a pretty good way for project* users that want to track downloads of project files to do so. It has the obvious benefit of not requiring all files for the site to be done via the private download method. If there was a relatively easy way for this script to invoke a hook of some sort that someone else might write to do the actual counting of downloads, that would be cool. But perhaps that would be more appropriate as a separate feature request instead of lumping it in here.
#2
Thanks for the review:
Re #1: it just starts a download that never completes. The script itself just sets the headers. If apache doesn't know what to do with them, it doesn't do anything. ;) So yeah, it's a bit lame. But, I figure if the script says it requires it at the top (and you have no prayer of using this script without reading the install instructions in that comment), that's good enough for now.
If the script can reliably figure out if mod_xsendfile can be used or not (which seems hard, since it's not just about if mod_xsendfile exists, but also if it's configured/allowed where the script is running), it could fall back to sending the file through PHP. It's just that I don't feel like spending time on reliably testing for mod_xsendfile at this point. ;)
Re #2: Wow, I totally hadn't thought of that, but you're absolutely right! Yeah, let's do that in a follow-up.
#3
More on #1.1: Looks like other people have the same problem: http://www.apachelounge.com/viewtopic.php?t=3081 -- There appears to be no good way in PHP to test if this is available or not. There seem to be a few possible approaches:
A) The above suggests setting an environment variable in .htaccess when you enable mod_xsendfile, and then test for that in the script. Yuck.
B) http://www.dokuwiki.org/config:xsendfile suggests basically having a setting in your software where an admin specifies if xsendfile is available.
I think (B) is easier and better for our needs. I could just add another configuration constant at the top of the script like USE_XSENDFILE, and then at the bottom of the script test that setting. The docs just say "if you enable and configure mod_xsendfile properly, set USE_XSENDFILE to TRUE and your downloads will be a lot faster". That's pretty trivial, I'll do that right now.
#4
Tested heavily, more comments, etc. Should be good to go. I default USE_XSENDFILE to FALSE, so folks have to go out of their way to turn it on...
#5
Committed #4 to HEAD.
#6
For #1.2, see #537576: Invoke a hook whenever a private release file download happens.
#7
2 cents provide too late, but...
There are already several modules which provide a mixed mode for public/private files - (see #534496: clarify difference from Private Upload module or merge projects for the most recent). Ideally I'd rather use one of those, but I guess it's not possible since project puts the release tarball into it's own place rather than using the upload version? Maybe just something to consider for the future in case project eventually starts doing something like using a filefield for the tarballs.
#8
Right. See #179471: release file attachments should use drupal upload functionality. We can't use any of the existing solutions unless we're actually using upload.module. I definitely considered that route, but sadly, it just wasn't an option.
#9
Automatically closed -- issue fixed for 2 weeks with no activity.