Restricted access url for an image uploaded to private filesystem I have a custom content type with an image and a file field, both of which are uploaded to the private file system. 

How do I create a public url to the image that will check for user permissions so that anonymous users are prevented from being able to browse to the image?

This is the code I tried first:

$url = file_create_url($node-&gt;field_my_private_image[$node-&gt;language][0]['uri']);


It generates a url to system/files/ but that url is visible to anonymous users and it isn't being restricted by user permissions.

I saw a security patch for drupal 7.13, but it was supposedly fixed and I'm using drupal 7.22.

Is there a built-in way to do this or do I need to implement some functions in my module to respond to special urls to access these files which will check permissions and then stream the file back to the browser?
You want to implement hook_file_download in Drupal 7.


  Control access to private file downloads and specify HTTP headers.
  
  This hook allows modules enforce permissions on file downloads when
  the private file download method is selected. Modules can also provide
  headers to specify information like the file's name or MIME type.


A small example:

function mymodule_file_download($uri) {
  global $user;

  // Does the user have access based on some criteria ?
  if (!user_access('ACCESS PAY-PER-DOWNLOAD-CONTENT', $user)) {
    return -1;
  }

  // Does this module own the file given by the $uri ?
  if (db_query('
          SELECT fu.module
          FROM {file_usage} fu
          WHERE fu.module = :module_name AND fu.uri = :uri',
          array(':module_name' =&gt; 'mymodule',
                ':uri' =&gt; $uri)-&gt;rowCount() &lt; 1) {
    return NULL;
  }

  // If the above conditions fallthru then populate HTTP header arrays
  // for content download; If you need to grab the file object and work on
  // it -- say output CSV from the data, you can grab it as follows ...
  $files = file_load_multiple(array(), array('uri' =&gt; $uri));
  // If empty, $file will be false, otherwise will contain the required file.
  $file = reset($files);

  return array('Content-Type' =&gt; file_get_mimetype($uri));  
}