I've solved this in the past by using a file-fetcher asp page and streaming the bytes of the desired file, using the correct content-type in the header. Roughly:
Create page fetchfile.aspx
Sample URL: yoursite/fetchfile.aspx?n=pdfname.pdf
In fetchfile:
- Verify user is permitted to access file.
- Check chosen directory for presence of file from query string.
- Set content-type appropriately for file type.
- Open the file and stream all bytes of it to the client.
- Close the file and end the response.
Do not send anything in the response except the bytes of the file. If an error occurs, either redirect or return error html with the content-type set correctly.
The last time I did this I was serving up images, so I found a suitable free library and wrote my error message into a new custom image that could then display. For fun, you can use this technique to serve up content that is unexpected when anyone steals your bandwidth by hot-linking like this:
Create a blacklist with unwanted referrer names, in a database table or text file.
When a request for a file comes in, if the user is not allowed, check if the referrer is in the blacklist, and if not, let the file be read.
On a regular basis, check the referring pages and decide a suitable pdf to return to punish that site.
Add the content you want to return to your blacklist for each referrer, and when the referrer IS in the blacklist, then return the alternate diddled content.
This is a great way to make people REALLY unlikely to steal your stuff. Their experience looks like this:
They find some nice content they want to "borrow."
They post it on their site and it works just fine.
The next day you see their action and add them to the blacklist table but make it so anyone trying to obtain the content instead gets a nice little message of some sort: "example.com is STEALING this content from the owners at somecoolsite.com. Please let them know that you are displeased with their actions."
You have a good laugh.
This can be especially wonderful if the content being stolen is an image. Embarrassments galore are in store for bandwidth thieves!
Some extra clever IP-address and time comparison could possibly make you show the correct content to the actual perpetrator but the wrong content to any of his site visitors... evil and delicious.