in reply to Re: Serving files without revealing their location
in thread Serving files without revealing their location

Let me clarify: Say the file is "www/docs/file.pdf" Couldn't I write a cgi that would recieve as a paramenter the file "id", obtain the filename from a db with the given id, then open a filehandle for that file, read its contents into a buffer, and print the buffer contents to the response? The user would only see "cgi-bin/get_file.cgi?id=xxx" in the url.
  • Comment on Re: Re: Serving files without revealing their location

Replies are listed 'Best First'.
Re: Re: Re: Serving files without revealing their location
by Fastolfe (Vicar) on Jan 29, 2001 at 02:16 UTC
    This is certainly possible, but I have to repeat others' questions: why?

    The solution to your problem (which, itself, is still unknown to us) is kind of odd. All resources on a web server are accessed with a URL. All you're doing is substituting one URL (that maps to a PDF filename of the document) with another (that maps to an ID representing the same PDF data). The fact that that seems kind of non-sensical makes me wonder if you're trying to solve a problem that you don't really have, or if the solution you think you want is going in completely the wrong direction. The solution you outline here is just adding another layer of complexity to the file delivery process, in the form of CGI, which will make things a bit less efficient. If you wanted to go this route, mapping an ID number to a database entry or physical document, I might consider using apache's mod_rewrite or write your own query handler to do the ID -> filename mapping. At least that way you won't be pumping all of this through a CGI script. This seems kind of odd.

    So I'm curious: what are you trying to accomplish by doing this?

      The application is a project management tool.

      I want to be able to control a user's access to project documents. If a user no longer has an association with a project, I don't want them to be able to return to that document via it's url.

      If I serve the document with the cgi script, the user won't know the path to the document, only to the cgi that served it.
      I can control access to the cgi page through the login feature of the pm tool, but the projects documents are not webpages- I can't include the login code in them.

      I hope that seems a little more clear.

        Ah, I guess this makes a little more sense.

        Still, I might suggest that you use HTTP authentication to do something like that. That way you can use the same standard URL, but allow the HTTP authentication to determine who gets access to it.

        Saving that, it looks like the technique you describe should work for you. I might extend it to put the filename in the "path_info" variable for your script.

        use CGI ':standard'; use File::Spec 'rel2abs'; my $base = '/www'; my $filename = rel2abs(path_info, $base); if ($filename =~ /^\Q$base/ && open(F, "< $filename\0") && -f F) { print "Content-type: application/pdf\n"; # or whatever print "Content-length: ", -s F, "\n\n"; print while <F>; close(F); } else { # handle errors, perhaps do a Status: 403 or 404 # along with a nice description, using $! if you want }
        Then you can call your script like this:
        http://www.example.com/cgi-bin/script.pl/path/filename.pdf
        Which will end up retrieving /www/path/filename.pdf, if it exists. Otherwise presumably you'd want to send a 404 status, for example. This would allow you to use "real"-looking URL's while pumping it through your CGI anyway.

        Your best bet is to build some kind of ACL functionality into the webserver.

        If you really can't do that, then the CGI version you're describing is doable. But I wouldn't worry about putting the URL in a database or anything like that. You're not interested in hiding the address, just restricting access to it. I'd just use the filename in the URL: http://www.tmtm.com/cgi-bin/get_file?name=foo.pdf

        Then I'd just move the documents outside the webtree, check if the user is allowed, and if so serve up the required document.

        Tony

Re: Re: Re: Serving files without revealing their location
by salvadors (Pilgrim) on Jan 29, 2001 at 02:19 UTC

    Yes. You could do that. But then that address would *be* the location of the file. Why would http://www.tmtm.com/cgi-bin/get_file.cgi?id=6 actually be any better than letting it be http://www.tmtm.com/docs/file.pdf?

    If you don't want people to be able to fetch the file more than once, then that's a slightly different question. In that case you could wrap code around the get_file command to not allow the use of the URL more than once, but that's going to be more tricky than a simple database lookup to map the ID to the location.

    Perhaps you could explain *why* you're trying to do this, and we might come up with a better solution.

    Tony