4

After migrating a site from D6 to D7 with drush site-upgrade, I notice that some public contents in the D6 version refered to pictures with URIs like for instance /system/files/logo.png, instead of the more efficient /sites/default/files/logo.png
There's no system directory on disk and no URL rewriting that I can see, so I assume the first form goes to Drupal for routing.

The problem is that with D7 post-upgrade, such references lead to a "Page not found" error so the pictures are broken.

As a test, if I drop somefile.png into /sites/default/files/, D6 seems to be happy to serve http://example.com/system/files/somefile.png despite the fact that the file is not known anywhere in its database. But D7 apparently doesn't do that.

Is /system/files a hardcoded path component that means something to D6 and not D7? In /admin/config/media/file-system, the download method is set to "Public local files served..."

How to solve this with Drupal 7? Is there a configuration setting somewhere that I'm missing?

1

Why it happens

In D6, the system module provides the following menu entry that ties system/files to the file_download callback:

In system_menu() function:

  $items['system/files'] = array(
    'title' => 'File download',
    'page callback' => 'file_download',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );

Then in file_download(), if the file exists and no hook_file_download() objects to the download, it gets served.

On the other hand, D7 expands on that with a page argument set to private:

  $items['system/files'] = array(
    'title' => 'File download',
    'page callback' => 'file_download',
    'page arguments' => array('private'),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );

It has the effect of preprending the private:// scheme to the filename, which file_download processes by requesting the registered file stream wrapper for it.
By default (no private path set in /admin/config/media/file-system), this scheme is not registered, and that's why GET /system/files/logo.png finally fails with a 404 status.

How to fix

Setting the private file system path to sites/default/files (the same as the public path) makes it work.

However it's not a good long term fix, both because routing public static files through Drupal is much heavier than direct access by httpd, and because it precludes the use of a real private space should the site need it in the future.

The long term fix is to hunt for these /system/files/xyz references and replace them by /sites/default/files/xyz.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.