Okay, here we go:

- Do a clean install of Drupal;
- Goto 'admin/settings' and change in 'File system settings':
'File system path' to something else as the default 'files';
'Temporary directory' to something else as default;
Set 'Download method' to 'Private - files are transferred by Drupal.';

Now, upload/attach an image/file into a node/post. Use the file inside your post, using the url which has been generated by Drupal. You'll see that in both preview and the final node the image/file isn't getting the right path..

And, - worsest of all is - I have not a clue what is causing it. I suspect file_download_private() inside file.inc, but I'm not sure at all..

Steef

CommentFileSizeAuthor
#20 55520_comments.patch.txt2.42 KBdopry
#15 55520.patch.txt2.8 KBdopry

Comments

dbs-1’s picture

We had the identical problem with a 4.6.5 installation. When talking with the developers, the answer was "Do not change the private file setting after things have already been set up. You should do it right upon installation". Unfortunately, I don't know how we solved the problem (it just sort of 'went away', and it wasn't a cache problem).

So I guess I'm saying 'this is not a new issue'.

Stefan Nagtegaal’s picture

I know that changing from private to public downloads (and the other way around) will break the files to be downloaded. Thats a logical thing.

But the reproducement says very clearly that you should do this on a fresh drupal! And, that we shouldn't change the destination where files should be kept, is IMO a very easy answer. Then there shouldn't be an option todo so..

This is very clear and obvious a bug, no matter what people say to you.. This _is_ a bug, and a damn nasty one too..

Dave Cohen’s picture

Preview does not work when private downloads are used. The upload module does some special rigging to preview public files, but not private ones. During preview they are not in the files table in the database, so they cannot be found. This may be fixable, but in my opinion is not 'critical' enough to delay 4.7 release.

As for the saved, nodes. I am unable to reproduce the problem. It works for me.

I vote to downgrade this to less than critical priority.

dww’s picture

Priority: Critical » Normal

i just tried reproducing this, and failed. i followed the suggested steps on a fresh install from CVS head, and everything appears to be working with file uploads/attachments, even when using a non-standard directoy for the "file system path" directory. i'm hereby downgrading this to "normal". stefan, can you try again and see if you can reproduce the problem? if so, please post more details on a) exactly what you did to reproduce it and b) exactly what the faulty behavior you're seeing is. at this point, i don't see any bug at all. sorry.

-derek

Stefan Nagtegaal’s picture

Okay, I updated drupal to latest HEAD. (I would have sworn I did that before testing this once again!)

And I admit that after submitting the private download path to files work. But in preview mode, it still doesn't work..

We should fix this in upload.module according yogadex' comment in this threat.

dopry’s picture

Title: Private downloads aren't working properly » upload.module does not display previews for when private files are enabled.
Assigned: Unassigned » dopry

Updating the title to reflect the actual issue. I will play with this when I get a few cycles next. It should be working for both private and non-private files. Could anyone who has their tmp folder in a non-public directory let me know the state of their file previews?

Stefan Nagtegaal’s picture

@Dopry, what do you mean by "the state of their file previews"?

Dave Cohen’s picture

The problem can be fixed by a special hook_download in upload.module. The file.inc functions store some info about files in $_SESSION, because they need it to preperly handle previews. Or at least they did at one point...

Here's a function from a module I wrote for one of my sites. Sorry it's not a real patch, I don't have time myself, but with just a little tweaking someone could make it work with upload.module. It enables the downloading of files that the current user has uploaded, but have not yet been moved from temporary to permanent storage (that is, previews).

  // this code or something like it needs to be merged in upload_file_download()

  // let the user see any files he/she is previewing
  if ($file = $_SESSION['file_uploads'][$filepath]) {
	$name = mime_header_encode($file->filename);
	$type = mime_header_encode($file->filemime);
	// Serve images and text inline for the browser to display rather than download.
	$disposition = ereg('^(text/|image/)', $file->filemime) ? 'inline' : 'attachment';
	return array('Content-Type: '. $type .'; name='. $name,
				 'Content-Length: '. $file->filesize,
				 'Content-Disposition: '. $disposition .'; filename='. $name);
	
  }
Stefan Nagtegaal’s picture

@yogadex: there are 2 of these function inside the upload.module already. Though I'm not exactly sure what they do for sure:

function upload_download() {
  foreach ($_SESSION['file_previews'] as $file) {
    if ($file->_filename == $_GET['q']) {
      file_transfer($file->filepath, array('Content-Type: '. mime_header_encode($file->filemime), 'Content-Length: '. $file->filesize));
    }
  }
}

function upload_file_download($file) {
  if (user_access('view uploaded files')) {
    $file = file_create_path($file);
    $result = db_query("SELECT f.* FROM {files} f WHERE filepath = '%s'", $file);
    if ($file = db_fetch_object($result)) {
      $node = node_load($file->nid);
      if (node_access('view', $node)) {
        $name = mime_header_encode($file->filename);
        $type = mime_header_encode($file->filemime);
        // Serve images and text inline for the browser to display rather than download.
        $disposition = ereg('^(text/|image/)', $file->filemime) ? 'inline' : 'attachment';
        return array('Content-Type: '. $type .'; name='. $name,
                     'Content-Length: '. $file->filesize,
                     'Content-Disposition: '. $disposition .'; filename='. $name);
      }
      else {
        return -1;
      }
    }
  }
  else {
    return -1;
  }
}
Dave Cohen’s picture

upload_download is a callback written sepcifically to handle previewing of files, when file access is 'public'. It does not need to change. upload_file_download is called when file access is 'private'.

upload_file_download needs code like what I posted, merged into one of it's if...else clauses. The code needs to find the file in $_SESSION['file_previews'], like upload_download does, but it needs to return the info hook_upload_download returns.
It should behave like upload_file_download currently behaves, but find the file info in $_SESSION if it fails to find it in the database.

Stefan Nagtegaal’s picture

@Yogadex: I have the feeling that this is way above my head. I tried, tried and and tried again without any glimpse to succesfully fix this issue. Could you or dopry (dopry, where are you anyway?) provide a patch for this issue?

I will happily maintain the patch once it's there and try to get it committed....

dopry’s picture

@yogadex
Actually the upload_download should handle both public and private previews.
The path is stored in the menu for all previews, set to the callback upload_download, whether
they're public or private.

upload_file_download is expressly for serving private files after they have been stored.
I'm going to try to get to this today. I still need to set up a private files site.

Dave Cohen’s picture

@dopry,

I think you'll find that if private files is set, the file path will look something like "system/files?file=suchandsuch". In this case, upload_download will not be called. But upload_file_download will.

I'll be interested to hear if I am wrong, however.

dopry’s picture

@yogadex
Yeah you are right. :)... Sort of...
file_download will be called, which will call upload_file_download for authentication. Thats only because of that stinking file= nonsense...

I should have the patch later this evening.

dopry’s picture

StatusFileSize
new2.8 KB

Ok well here goes. Let killes rain hell on me, but there is some feature creep in this fix. This patch makes clean url's work for private files... (and for the crafty might make it easier to migrate from public to private and back to public files again.... think .htaccess, -f, system/files/image.png..., domainroot/files, domainroot/public_html/system/files)

Its a little comment heavy... they can be cleaned up if the patch is acceptable.

dopry’s picture

Status: Active » Needs review

Oh yeah, update status...

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

i gave this a good exercising and it works as advertised. RTBC ... i'm not sure why those were not clean urls to begin with. i think this is an acceptable bug fix during a beta.

gerhard killesreiter’s picture

Status: Reviewed & tested by the community » Fixed

applied. Didn't see any features creeping.

Steven’s picture

Status: Fixed » Needs work

Could the comments in this patch be cleaned up? They are IMO not clear enough (and don't conform to the code guidelines either). I doubt you would still know what you meant in 6 months.

dopry’s picture

StatusFileSize
new2.42 KB

Yes, but I love trying to guess how sleep deprived I was when I wrote the comment. Its like a game :)....
Here is an update with terse comments.

dopry’s picture

Status: Needs work » Needs review

There has to be some way to make the status changes more intelligent. Or remind me that I may want to update the status when I attach a new file. It'd save us some ids.

killes@www.drop.org’s picture

Status: Needs review » Fixed

applied

pfaocle’s picture

Version: 4.7.0-beta6 » 4.7.0-rc1

Please take a look at this issue. This patch will break a lot of existing content on sites with private files enabled.

Anonymous’s picture

Status: Fixed » Closed (fixed)