In settings.php, the private file path is documented with "This directory must be absolute, ...". However, an absolute path does not work when drupal runs on a shared host and access to the parent directories is not possible.
Example:
• a shared host with drupal root /var/www/ud17_276/html/drupal
• web server root is /var/www/ud17_276/html
• shared host root is /var/www/ud17_276, i.e., this part is not visible for the space admin, and thus neither for drupal
• in settings.php:
$settings['file_private_path'] = '/var/www/ud17_276/files/drupal-private';
If a drupal user tries to upload a file, by creating a node of a content type having a file field with private storage configured, drupal tries to create the full parent path, /var/www/ud17_276, which obviously will fail. The error message in the log is:
"The upload directory private://2016-09 for the file field field_privimage could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled."
Configuring the shared host's users relative root, like
$settings['file_private_path'] = '/files/drupal-private';
does also not work. The only way this seems to work currently is a relative path:
$settings['file_private_path'] = '../../files/drupal-private';
Hence, either the code documentation in settings.php should be updated to include this case, or the coding has to be changed to be able to deal with shared hosting. (Unfortunately, due to lack of php knowledge, I cannot judge these options.)
Best, Tobias
Comment | File | Size | Author |
---|---|---|---|
#54 | interdiff_52-54.txt | 568 bytes | aleix |
#54 | 2799635-54.patch | 4.32 KB | aleix |
#52 | interdiff_46-52.patch | 8.64 KB | aleix |
#52 | 2799635-52.patch | 5.08 KB | aleix |
#48 | interdiff_41-48.txt | 3.8 KB | Ben Buske |
Comments
Comment #2
BoobaaRan into the same problem, and was able to track it down to
\Drupal\Core\File\FileSystem::mkdir()
. This method iterates through all the components of thefile_private_path
and checks if the component exists. Since in our case the first component is..
,file_exists()
will return FALSE, thus this method tries to create it, which will obviously fail.By the way, the same bug can be triggered by trying to download an image derivative whose directory does not exist yet. In this case, the error message is different: "Failed to create style directory: %directory" (from
\Drupal\image\Entity\ImageStyle::createDerivative()
).A patch is coming, but I don't know how to write a test case for this, as the existence of this bug highly depends on hard-to-change PHP settings.
Comment #3
BoobaaComment #4
BoobaaThe bug is still present on 8.2.5.
Comment #5
cilefen CreditAttribution: cilefen commentedComment #6
tobias-hd CreditAttribution: tobias-hd commentedThanks @Boobaa for the patch #3!
I tested it with Drupal 8.2.5 on my webhoster, and I can confirm that the patch supresses a php error message "User error: Invalid placeholder (!name) in string: The directory %directory ... could not be created..."
Strangely, the upload itself did work (as far as I can judge) with and without patch - hence to me it's not clear, what the affected functionality behind that is. (I did clear the cache between testing with and without patch...)
With the image derivatives I still have the problem reported in #2799639: Image derivative generation not working for private files on shared host - the patch seems to not change anything in that respect.
I'd propose to supplement the patch with an adjustment of the corresponding comment in /sites/default/default.settings.php - I'll try to upload a patch.
Comment #7
tobias-hd CreditAttribution: tobias-hd commentedComment #9
eithel CreditAttribution: eithel commentedMaybe relate to thus issue: https://www.drupal.org/node/2878778
Comment #10
LpSolit CreditAttribution: LpSolit as a volunteer commentedIMO, the right fix is to call createDirectory() being in core/lib/Drupal/Component/PhpStorage/FileStorage.php or to duplicate its behavior, as it already handles open_basedir correctly.
Comment #11
Boobaa@LpSolit: could you submit this idea as a patch?
Comment #12
LpSolit CreditAttribution: LpSolit as a volunteer commentedHere is what I had in mind.
Comment #15
LpSolit CreditAttribution: LpSolit as a volunteer commentedFix the error message in core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php.
Comment #16
LpSolit CreditAttribution: LpSolit as a volunteer commentedUpdating the bug summary to better reflect what the problem is. With my patch, there is no need to use relative paths. Absolute paths just work fine.
Comment #18
trungonly CreditAttribution: trungonly commentedFacing problem. Buzz for the fix.
For the #7, for the directory create, you should add
DIRECTORY_SEPARATOR
like this:Comment #19
AnybodyI just ran into the same problem and can confirm this issue.
Comment #21
capmex CreditAttribution: capmex commentedI experienced this issue on a Plesk server where paths are like:
/var/www/vhosts/domain.com/httpdocs (DocRoot)
/var/www/vhosts/domain.com/private (the private folder I created not accessible over the web, ownership domain-user:psacln, permissions 775)
With the absolute path Drupal was able to create the .htaccess correctly, but any uploads failed because it was not able to create subdirectories.
Using #7 (thanks @Boobaa and @tobias-hd) and adjusting it with #17 (thanks @trungonly) allowed the private directory to work correctly using:
For anyone on a shared host or with setups like the above this is a good solution that can be easily implemented. I spent several hours trying to figure out why private files did not work at the server level.
Comment #22
Yazzbe CreditAttribution: Yazzbe as a volunteer commentedMany thanks for the suggestion. Struggled with this for hours ...
A relative path is the answer!
Comment #23
Geolim4 CreditAttribution: Geolim4 as a volunteer commentedThanks #21 for saving me hours of debug... Much appreciated !
Comment #24
rjw CreditAttribution: rjw commentedThanks. I came up against this issue when I added a file upload field to a webform. A relative path for the private file directory made it work. I didn't apply any patches.
Comment #25
broonThanks all, I was wrapping my head about this issue as well on a Plesk-based Drupal installation. Providing the private filesystem folder with a relative path solved the issue for now without any patches applied.
Comment #26
Dries ArnoldsThis worked for me too. I had to apply the patch AND set a relative path.
I was using ISPConfig on a Debian server here.
Comment #27
robotjox CreditAttribution: robotjox commentedAlso on ispconfig - came across this patch after banging my head against the wall for hours. Thanks!
Comment #28
milopca CreditAttribution: milopca commentedThanks to all!!
After a lot of time debugging the issue on a Plesk-based Drupal installation, setting the private dir to relative solved the issue (without any patches applied).
Comment #29
jfoctober CreditAttribution: jfoctober commentedmight this patch be making its way into core soon?
Comment #31
robotjox CreditAttribution: robotjox commentedI for one still need this patch.
Comment #32
robotjox CreditAttribution: robotjox commentedLet's try that again.
Comment #33
Neslee Canil Pinto#32 applied cleanly and tests passed. Moving to RTBC.
Comment #34
jungleUnexpected leading spaces and should file against 8.9.x or other branches, not 8.8.x.
Comment #35
jungleComment #37
jungleFailures seem unrelated and the re-testing passed, and #36 is just a tiny trivial change, so setting back to RTBC as #34.
Comment #38
Neslee Canil PintoCorrected sentence from 'If the directory exists already, there's nothing to do.' to 'If the directory already exists, there's nothing to do.'
Comment #39
jungleThanks, @Neslee Canil Pinto!
Re #38 It can be either in the
mid position
or theend position
actually. But already in the mid position seems more formal than in the end position.Comment #41
neelam_wadhwani CreditAttribution: neelam_wadhwani at Valuebound for Valuebound commentedHello @jungle.
Your point was right, in mid position seems formal.
I have reroll patch #38
Kindly review it.
Comment #42
neelam_wadhwani CreditAttribution: neelam_wadhwani at Valuebound for Valuebound commentedComment #46
daften CreditAttribution: daften at Picabit commentedRerolled patch for 9.3.x-dev
Comment #48
Ben Buske CreditAttribution: Ben Buske at werk21 commentedChanged path of #46 for it to apply and added interdiff.
Comment #50
vijaycs85Comment #52
aleix CreditAttribution: aleix at Communia commentedThe only way that test is passing is increasing the sleep time...
Comment #53
aleix CreditAttribution: aleix at Communia commentedAdded note about open_basedir in docs : https://www.drupal.org/docs/8/core/modules/file/overview#s-managing-file...
Comment #54
aleix CreditAttribution: aleix at Communia commentedAttempt to make it pass the testNonWritableDestination
Comment #55
aleix CreditAttribution: aleix at Communia commentedAs it is passing right now, please consider review the patch.
Comment #57
LpSolit CreditAttribution: LpSolit as a volunteer commentedI'm using this patch for years without any problem. I needed it to make the filebrowser module work with open_basedir. Not sure if this is enough to RTBC this patch.
Comment #58
LpSolit CreditAttribution: LpSolit as a volunteer commentedaleix's patch #54 works fine with the filebrowser module and is 99% similar to what I wrote in comment #15, which I use for 5 years now. Not sure if I'm allowed to RTBC this patch.
Comment #59
smustgrave CreditAttribution: smustgrave at Mobomo commentedThis issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.
The issue summary should be updated to clearly show what the proposed solution is, remaining tasks, etc
Not sure if this is in scope?
But as a bug this will need a test case showing the issue.
Comment #61
bohemier CreditAttribution: bohemier commentedThanks for the patch, without it, it is impossible to handle securing private files outside of the webroot with the open_basedir directive. After applying it, wet can set private and tmp using relative directories, such as:
Comment #62
egfrith CreditAttribution: egfrith commentedAfter some time getting to the bottom of #3411785: Create subtheme doesn't work with open_basedir restriction, I would hope that we could get this sorted out. @smustgrave: is it possible to set up open_basedir in the testing environment? If not, I'm not clear how a test could be created for this issue.
Comment #63
apadernoI use shared hosting for a site, but I am able to use absolute paths, even when I set the file private path. Maybe the issue summary should explain when there are issues with using absolute paths.