D6 doesn't supports several features once private download method is selected
- they has been reported as a bug
- D7 branch is bringing support for them as a new features
- previous branch won't get new features added

this issue is ONLY for the purpose of providing a patch for D6 branch which brings this features enabled whether public or private download method is selected

also I will be providing reference to other issues marked as duplicate, or changed to head (D7 branch)
but the main aim of this issue is to provide a patch for each D6 minor version released (in case it would be needed, since the patch keeps being the same since D 6.3 without any other changes than encodings)

thus, this is a feature request that won't be fixed for D6 but provided as a patch similar to issue #7881: Add support to drupal_http_request() for proxy servers (http not https) which has happily lived since May 19, 2004 without being included in any branch

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Damien Tournoud’s picture

This is a bug, and I don't see why we shouldn't fix it in D6. You are just ranting uselessly.

arhak’s picture

please, I'm just trying to help
I understand you are doing the same

where would I be allowed to maintain that patch?

it is not a bug, since Drupal requirements state that private download method "is incompatible" with those features

arhak’s picture

@#1 may I leave this issue as a "won't fix" for D6 (which shouldn't bother any reviewer/maintainer) and provide the patch that might be needful for others?

arhak’s picture

this patch requires to manually create a misc/dynamic folder

if the site was already running with other languages set,
javascript translations might be pointing the wrong location
therefore, a cleanup might be required:
- SQL UPDATE languages SET `javascript` = '';
- PHP locale_inc_callback('_locale_invalidate_js');
EDIT: also check out a way to automatically handle lost javascript translations at #338630: Locale is unable to rebuild lost Javascript translation files
EDIT: an unobtrusive way to handle lost javascript translations might be the tweak_locale_js module which provides locale admin pages with buttons to rebuild/invalidate js translations, therefore no manual SQL neither PHP execution would be required

the patch I use was made with Mercurial, which means it won't work with -p0
use
patch -p1 < 2009.08.25-public_misc02_1.patch
or try the other version
patch -p0 < 2009.09.07-public_misc03_1.patch

both patches are equals (beside the -p# option and the encoding)

PS: tested on Drupal 6.3, 6.4 and 6.13

rewe’s picture

we tested and successfully applied this patch to a 3000+ user community - everything looks good so far!

thanks a lot!

arhak’s picture

also tested by talino 181003#comment-2017040

arhak’s picture

also tested by Geekish 547400#comment-2044310

mattis’s picture

I applied the patch to a Drupal 6.14-page. css and js folders in misc/dynamic get created and the files are loaded. The layout of the page still looks the same and the date-picker jquery feature still works. Looks good, thanks alot :)

DanilaD’s picture

Created the misc/dynamic folder as suggested. Had to change it's permissions to 777, and press 'Clear cache' - after this patches worked as they should - css and js are aggregated. Thanks a lot!

Still, is it a good idea to leave 777 on the misc/dynamic folder?

arhak’s picture

@#10 755 would be enough

EDIT: WRONG, read #13 bellow

DanilaD’s picture

I've tested it the following way:

chmod 755 dynamic
clear cache
- no css aggregation files

chmod 775 dynamic
clear cache
- no css aggregation files

chmod 777 dynamic
clear cache
- aggregation files appear

Maybe there are some config changes that I should make to assign the 'webserver' user to some group?

Regards,
Danila

arhak’s picture

@#10 & #12
I'm deeply sorry, I previously answered non-sense
the webserver needs read and write access, (therefore a 5 isn't enough)

if your webserver would be included in the group then you could use 775

since it didn't work for you it seems that your webserver is taking privileges as "others", so I wouldn't mind to leave it with 777, since it will need read, write and listing access, and the webserver might fall under "group" or "other" depending the group settings

xurizaemon’s picture

if the directory is owned by the webserver, you can chmod 755.

because file and directory perms are in relation to a user / group, saying simply "777" or "775" is not meaningful until you also specify what user and group they relate to.

tpryor’s picture

Title: make private download method support css/js aggregation, color module and js translations » thank you for the patch arhak! Where do we apply this patch?

and where do we create those directorie(s) (misc/dynamic) exactly?

I just want to confirm that this is a drupal core patch (not a module) and that I should be in my drupal root, for both the patch and the new dir path.

I would like to use it for a 6.14 system I am setting up.

Thanks again for the patch :toast:

xurizaemon’s picture

reverting issue title

tpryor’s picture

Title: thank you for the patch arhak! Where do we apply this patch? » make private download method support css/js aggregation, color module and js translations

that sounds like a core patch to me =)

thanks

arhak’s picture

yes, it is a core patch
the directory misc/dynamic goes on the Drupal's root directory, just a sub-directory dynamic under the existing Drupal's misc directory

BTW: the dynamic directory can be named differently if the proper variable is set up
for clearance I always say misc/dynamic but it might be configured

matt2000’s picture

subscribe

tomgf’s picture

Subscribe

yang_yi_cn’s picture

subscribe

matt2000’s picture

Status: Closed (won't fix) » Needs work

Confirming that this works nicely on Pressflow 6.15 also.

FYI, I made a slight change from 'misc/dynamic' -> conf_path() . '/dynamic' for better support of upgrades and multi-site.

matt2000’s picture

Status: Needs work » Closed (won't fix)

whoops, didnt mean to change status, although I would love to see this in D6, and tend to agree with Damien that it is a bug with a bubble gum solution at the present.

arhak’s picture

@#22 that's ok, but not required at all
I meant you can change the value of the variable file_directory_path:public_misc, either directly on the {variable} table or through variable_set('file_directory_path:public_misc', 'some/desired/path');

for better support of upgrades and multi-site

There shouldn't be any trouble with any of them with the current patch either.
Every time the hash of a JavaScript file changes it is generated, so several upgrades and/or sites (multi-site) can perfectly share the same directory (the same way the directory misc is shared) and files will co-exists.
It seems to me better to share the same directory, since all of those files are public and insignificant/smalls or even dispensable since they can be re-created.
Besides, we are talking here about some private policy, which makes sense to keep fewer rules for public folders, misc have to be public already, therefore, nothing makes more sense than a sub-directory of it.
If for some reason you need to "move" your public directory elsewhere then I provided the configurable variable file_directory_path:public_misc (the same way Drupal provided a file_directory_path variable)

arhak’s picture

forgot..
also settings.php would be a nice place to set the value of file_directory_path* variables

404’s picture

subscribing

arhak’s picture

rerolled for D6.15

izmeez’s picture

This patch looks interesting. I have a couple of questions.

1. If this patch is applied and used on a site that is using the public download method will it be ok or will it cause problems?

2. Does this patch then eliminate the performance hit that many posts suggest is inherent with the private download method?

3. Is it sufficient to just apply this patch and switch to private download method or is it important to consider other private file modules?

Thanks in advance,

Izzy

arhak’s picture

R1/ will be ok, it hacks/tweaks the core a little, but doesn't brakes anything, since it only adds an optional argument to core's functions, which by default behaves as core use to do

R2/ not related at all

R3/ it seems to me, that any "private file module" will have this "issues" (or bugs, call them as you prefer) since they are not supported by core. Whatever a "private file module" does, if you pick "private download method" then you'll have the issues addressed (and solved) by this patch.
Note that this patch doesn't address special case issues like gmap module (which has its own ongoing/stuck issue regarding something "similar")
Neither provides any feature or extra support that "private file modules" might bring.

izmeez’s picture

@arhak, thanks for the answers.

In reference to gmap, it appears that there is a solution for gmap markers involving setting the path to another directory and one could use /misc as this patch does. http://drupal.org/node/402260 http://drupal.org/node/352273#comment-1174871

Izzy

FiNeX’s picture

Is this patch planned for being included in D6?

arhak’s picture

@#31 absolutely NO, this is marked as "won't fix"
(more details in the original post at the top)

kewlguy’s picture

I can't seem to run this patch from #27 on my unix host because of the "(unix)" in the file name especially the brackets part of the file name. Foolishly I uploaded it as it is named and now I cannot remove it. #$#%&#&?

The SSH error is: -bash: syntax error near unexpected token `('

Thanks

arhak’s picture

a renamed version to avoid newcomers to run into #33

izmeez’s picture

I also came across the xsend module http://drupal.org/project/xsend which appears very interesting.

I am sorry to be cross-posting but I have been wondering what happens to css and js optimization under that module and started an issue http://drupal.org/node/691122

I appreciate the discussions in this thread and I am still struggling to understand the simplest way to enable private file handling in Drupal that is efficient and user friendly. While also developing an understanding of how Drupal 7 is approaching it.

I must admit I am finding it quite challenging to understand all the issues private v. public entails and have not found a good summary. I imagine this is because of the work people are still doing in these areas and I appreciate the work and discussions.

Thanks,

Izzy

arhak’s picture

answers are within file.inc

function file_directory_path() {
  return variable_get('file_directory_path', conf_path() .'/files');
}

conf_path() is one of:
- your public directory
- your private directory

can't be both
therefore, other core features requiring public web access get disabled when private download method is detected
that's why you can't do anything about it (in contrib mods) without:
- hacking the core
- or alternatively providing those functionalities

there is a fence option (which wouldn't be the most recommended):
- set private download method
- but leave the directory be sites/default/files (being under the webserver, not recommended)
- and tweak the .htaccess generated by Drupal to read like this:

SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006

Options None
Options +FollowSymLinks

# Don't show directory listings for URLs which map to a directory.
Options -Indexes

# Protect files and directories from prying eyes.
Order allow,deny
#Allow from None

# Enable JavaScript and StyleSheet FULL FREE download
# so js translation and js/css compression don't brake
<FilesMatch "\.(css|js)$">
  Allow from all
</FilesMatch>

- but haven't finished yet: features remain disabled
- now you can temporally switch to "public" download method, use the feature you want and set it back to "private" download method
- and surprise:
-- color module will work with generated color schemas
-- css/js aggregation will work until a file re-generation is required (in which case you'll need to switch to public again and back to private afterwards)
-- etc

it would be "the hard way"
otherwise...
that's why this patch becomes so handy, it saves you all that trouble

EDIT: typo

izmeez’s picture

@arhak Thanks so much for the detailed answer.

It leads me to the question of using the core hack in this thread in conjunction with the xsend module or if using the core hack removes the need for the xsend module?

arhak’s picture

2nd answer at #39: this patch won't improve performance, it makes some desirable features available (i.e. compatible with private download method), but it doesn't "improve" anything (besides bringing those features on)

when a file is downloaded through private download method it isn't Apache the one transferring the file, the transfer is proxied thought Drupal and therefore you loose performance in favor of gaining fine grained access control
the proposal of xsend (don't know if achieved, just read the project description) seems reasonable, and it does aims to improve performance taking core out of the way (regarding file transference) but leaving it in regarding access control, it might help a lot (just be aware that bugs out of core may open security holes and their detection process is slower that core's)

heltem’s picture

Here is the #34 patch ported to D6.16

arhak’s picture

@#39 thanks for re-rolling it

arhak’s picture

@#39 thanks for re-rolling it

brianmercer’s picture

subscribe

Souvent22’s picture

subsribe

404’s picture

@#39 works like a charm! Thank you!

FiNeX’s picture

So, isn't this patch be intended to be officially applied in the D6 branch?

arhak’s picture

@#45 according to the original post

thus, this is a feature request that won't be fixed for D6

arhak’s picture

off-topic

since many of you are using private download method, I'm gonna use this thread to warn all of you that have ImageCache enabled that there is a huge security hole that won't be handled by the security team
I should be disclosing details next week #796384: ImageCache makes private filesystem straightforward accesible (security issue #1172)
for more info on why it won't be handled by the security team refer to:
#791044: What would the role of the Security Team precisely be?
PSA-2010-001: Policy on release versions and permissions

Note that this has nothing to do with this patch, it will affect every site with ImageCache enabled AND using private download method (whether having this patch or not)

izmeez’s picture

Thanks. I finally had the opportunity to test out private file systems with this patch. I applied the patch in #39 on Drupal 6.16 without any difficulties and it works great.

Izzy

jm.federico’s picture

Hum, I tried it against 6.17 and although it applied the patch, and the options were enabled, CSS and JS files weren't being optimised.
Anyone else has tested on 6.17?

jm.federico’s picture

FileSize
12.74 KB

Attaching patch against 6.17

arhak’s picture

@#50 thanks for re-rolling it
@#49 I see you found what was your problem about #547400-4: Compatibility with private download method, good for you!

jm.federico’s picture

FileSize
13.14 KB

So, patch againts 6.19 :D

If anyone has issues, remember to create the folder!!!
drupal/misc/dynamic

and make sure your server has write access. (If you are on a shared account, you might just need to create it, write access comes by default)

J0keR’s picture

Assigned: arhak » J0keR
arhak’s picture

Assigned: J0keR » arhak

@#53 I guess you made a mistake
in any case it is jm.federico the one doing the last re-rolls

izmeez’s picture

@jm.federico Thanks for re-rolling the patch for 6.19 The only issue I noticed was that the patch does not apply from the Drupal root directory. It applies when the patch is placed in a folder higher up that itself contains the folder \drupal-6.19

arhak’s picture

#55 you're right
that can be solved using -p1 (instead of usual -p0)

nevertheless, I'll try to re-roll it again soon

jm.federico’s picture

FileSize
12.8 KB

@izmeez: I missed that, re-rolling.

heltem’s picture

Well, several other modules need a patch too, to be compatible with it.
I maintain a patch for CSS Tidy and one for Chaos Tools but I don't know where is the best place to share them.

jbm’s picture

sorry im really new to this i dont understand nothing of what you say..
When i try to download the patch it brings me a page of code. I dont know what to do with it..
Could you explain me how to do?

matt2000’s picture

@soundcooker

A patch file IS code. Save it to your Drupal directory. Instructions for using patches are here: http://drupal.org/patch/apply

matt2000’s picture

@soundcooker

A patch file IS code. Save it to your Drupal directory. Instructions for using patches are here:

http://drupal.org/patch/apply

jm.federico’s picture

Guys, back here agin

I gave up on using this patch (patching core gave me headaches, updating core was a nightmare, too many installations), and moved to using what http://drupal.org/project/private_download does. More info on where it comes from here:

http://www.drupalcoder.com/story/406-mixing-private-and-public-downloads...

I chose the DIY approach, this is more or less the same as the article, but note that you do not need to implement hook_menu:

All you need (using apache)

Select your private folder and put this inside the .htaccess

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteBase /system/files/YOURFOLDERNAME
  RewriteRule ^(.*)$ $1 [L,R=301]
</IfModule>

Implement hook_file_download() on your own module. Depending on your needs you can make it fancier.
In my case all my files are being uploaded using a modules that use Drupal File API (like cck file field), and all the files are meant to be downloaded, I can then send better headers:

/**
 * Implementation of hook_file_download().
 */
function your_module_name_file_download($ffilepathile) {
  if ($file = db_fetch_object(db_query("SELECT * FROM {files} WHERE filepath = '%s'", file_create_path($filepath)))) {
    // Check access
    if (user_access('THE PERMISSION GOES HERE')) {
      $headers[] = 'Content-Description: File Transfer';
      $headers[] = 'Content-type: ' . $file->filemime;
      $headers[] = 'Content-Disposition: attachment; filename="'. $file->filename .'"';
      $headers[] = 'Content-Transfer-Encoding: binary';
      $headers[] = 'Cache-Control: must-revalidate, post-check=0, pre-check=0';
      $headers[] = 'Expires: 0';
      $headers[] = 'Pragma: public';
      $headers[] = 'Content-Length: '. $file->filesize;
      return $headers;
    }
    else {
      return -1;
    }
  }
}

And all without one single core patch.

Credit to Davy Van Den Bremt http://www.davyvandenbremt.be/

Cheers

geerlingguy’s picture

Subscribing to this issue. For my Intranet site, I have 32 stylesheets, and I'll need to use this patch to allow aggregation (for performance reasons as well!).

dkinzer’s picture

subscribe.

John Pitcairn’s picture

Subscribing for future reference. Not really sure I want to be patching core, but I do have a couple of D6 sites using private filesystems and css/js aggregation may become highly desirable as traffic builds. I'm also running multisite so would much prefer that aggregated files reside in the relevant /sites/xxx directory rather than under core. Hm.

geerlingguy’s picture

Anybody have an updated patch for 6.20 yet? Haven't had time to roll one myself.

geerlingguy’s picture

FileSize
12.8 KB

Patch updated and tested in production against 6.20.

Again, warning/suggestion from #52:
If anyone has issues, remember to create the folder: drupalroot/misc/dynamic

jim.phelan’s picture

In case this helps, these are the steps I did to change from public to private files on an existing 6.19 drupal install using the ie_css_optimizer module, with gmap installed and running under IIS7.

1. Put the Website in maintenance mode
2. Backup the database and take a snapshot backup of the server
3. Disable CSS/JS optimization on the 'Performance' page.
4. Create a new directory sites/misc/dynamic and make writeable
5. GMap marker javascript did not seem to like being in sites/misc/dynamic directory so I gave it its own /sites/default/misc/js
6. Copy gmap_marker.js from sites/default/files/js to sites/default/misc/js
7. Add and enable module ie_css_optimizer
8. Enable CSS/JS optimization on the 'Performance' page (once files set to private this option will not be changeable without temporarily changing back to public files)
9. Apply patches (see above)
10. Move sites/default/files outside of webroot, eg: to E:inetpub/files
11. Go to admin/settings/file-system and set file system path to '../../files. and 'Download Method' to private
12. If you go to the gmap settings page, admin/settings/gmap, you will now see a new field into which you put the path for the new gmap directory you created in step 6. Save this and then click on 'Regenerate'
13. You now must logon to mysql as root or privileged user and update the file settings for links to files by running these separate SQL statements:
* UPDATE files SET filepath = REPLACE(filepath,'sites/default/files','../../files');
* UPDATE node_revisions SET body = REPLACE(body,'/sites/default/files','/system/files');
* UPDATE node_revisions SET teaser = REPLACE(teaser,'/sites/default/files','/system/files');
* UPDATE boxes SET body = REPLACE(body,'/sites/default/files','/system/files');
14. If your logo and favicon were uploaded then you will need to copy them on the server to the default logo and favicon and set the theme to use the default
15. Flush caches
16. Confirm new 'css' and 'js' folders have been created under sites/misc/dynamic
17. Test site (and make sure unpublished document may not be directly accessed by anonymous users) and if all seems OK, put back online.

arhak’s picture

@#68 thanks menapia for sharing

5. GMap marker javascript did not seem to like being in sites/misc/dynamic directory so I gave it its own /sites/default/misc/js

also note that it is not mandatory to use sites/misc/dynamic directory,
it can reside wherever you want, since it is base on variable_get('file_directory_path:public_misc', 'misc/dynamic');
there is not user interface to configure such variable, but you can set it yourself manually (in your case it could be sites/default/misc/js and that way you have them all in one place)

spacereactor’s picture

I got a question on #68 step 13. I have two site running on drupal 6, both is private. one is default and another is the domain name. How do update sql? Or can i skip this step?

jim.phelan’s picture

The steps in #68 are only if you are moving from Public to Private, step 13 in particular. So you can skip step 13 if your sites were always set to private.

If they have been running under the Public setting and you are switching to Private the sites are probably running on two separate databases, in which case you could simply run the SQL queries in both databases, if they are running on a shared database (not common in my experience) you would need to be very familiar with the tables in the database before running the queries, you may have to adapt them to your local configuration.

z7’s picture

FileSize
1.23 KB

Some time ago I created a module that does basically 2 things: allows including 3rd party libraries, like Zend Framework easily and enables dynamically generated CSS and JS while using private download mode. It is all done through Drupal hooks, so no core patch is required and should work in any environment. The only thing to consider is that you'll need some .htaccess files to disallow access to private files in the download folder.

Just thought someone may need this, so I shared it here.

spacereactor’s picture

#72 work with Nginx X-Sendfile. http://groups.drupal.org/node/130134
NICE, no more hacking core... :)

christiaan_’s picture

#72 - Thank you very much - This works perfectly, please release as a module.

izmeez’s picture

How does the module in #72 compare with http://drupal.org/project/advagg

linksunten’s picture

FileSize
13.13 KB

Here is the patch against Drupal 6.22

Remember to create drupal/misc/dynamic with write access for the apache user

(cf. #572516-52: make private download method support css/js aggregation, color module and js translations)

iva2k’s picture

Status: Closed (won't fix) » Reviewed & tested by the community

z7Tools maybe an acceptable bandaid to some, but I think crippled private upload functionality is an oversight in D6.

There is great interest to have that patch being part of D6 core. It is the only patch that I routinely apply to core on a number of active websites EVERY time there is a core update. Very annoying.

Are there any objections as to why it should not be accepted into D6? Earlier statement ("Drupal requirements state that private download method "is incompatible" with those features") is not cutting it for me. Requirements cannot have "shall not support" statements.

The patch works fine for about 12 months on 3 active websites, it makes a combination of very desirable features useful, while breaking absolutely nothing (very nicely done 100% backward-compatible code).

dkinzer’s picture

I agree, this was one of the more annoying facts re: D6. I finally decided to go another route and turn on public file download but make some subdirectories private by using apache mod_rewrite to rewrite access to the private URL to go via the 'system/files' directory.

The details for implementing this method may be found
@ http://www.drupalcoder.com/blog/mixing-private-and-public-downloads-in-d...
@ http://drupal.org/node/189239
@ http://success.grownupgeek.com/index.php/2010/11/23/drupal-change-from-p...

Now we don't need to worry about running patches or not having JS/CSS caching. And we have the added benefit that non private files have a much faster access time because Drupal does not need to be fully boot-strapped for each file download as before.

jm.federico’s picture

Status: Reviewed & tested by the community » Closed (won't fix)

Please do not ask for this functionality. D6 stays as it it, D7 has this functionality. There are solutions that do not require patching core.

See comment #78 for more info

Marking as won't fix.