1

I have a handler (c#/asp.net) that pulls images from a database. The current format looks like foo.com/_image.ashx?querystring1&querystring2 The querystring keys are things like id, width, zoom level etc.

I can either munge this up into a filename (i.e. foo.com/id__999_w__128__h__200.jpg), or a whole url structure (i.e. foo.com/id/999/w/128/h/200/image.jpg).

Im interested to see what other people would do given this situation, as there dont seem to be any articles or discussions of this practice on the net.

maxp
  • 24,209
  • 39
  • 123
  • 201

3 Answers3

2

The easiest solution would be to base64 the filename, then you can pretty much guarantee the filename will be correct each time, and not tampered with or broken.

string filename = @"C:\images\myimage.png";

// You may need to change the Encoding type here
string converted = Convert.ToBase64String(
    System.Text.Encoding.Default.GetBytes(filename));
Chris S
  • 64,770
  • 52
  • 221
  • 239
  • Great idea, shortens the url considerably too! – maxp Dec 02 '10 at 09:37
  • Warning! Base64 is a _very_ recognisable encoding. Any tech savvy user will be able to find it out and forge new ones. You must sanitize it (look for `..` in path for exemple). You better crypt it with some xor algorithm before encoding it in base64. – Nicolas Repiquet Dec 02 '10 at 09:59
  • @Nicolas Or even easier just put to a uid in the querystring that relates to the database row – Chris S Dec 02 '10 at 18:27
1

Best practices are a tricky thing, a lot of the choices you'll want to make depend on your situation.

Today a good way to handle this, is to load the images into a server like Amazon S3 instead of storing them into your database. Amazon S3 has an api that you can program to, so the application that you've already written that is storing the images into the database can be tweaked to upload them into Amazon S3 instead. Then you will store the url to the image in your database.

This will solve a number of problems.
1. Images stored on Amazon S3 can be exposed on Amazon CloudFront which is a CDN and will help you to route the image data to your end users in the fast possible route over the internet. 2. You can apply expires headers to these images so they cache on the client browser and the user will get optimum performance while using your website. In your curren mechanism you would have to add these headers programmatically. 3. Pulling blob data in and out of databases has never been the most performant operation against a database so you would be able to get rid of this code completely. 4. You can apply a cookie-free domain name to these images so that needless cookie passing is prevented and will also have a slight performance increase for your users. For example you might host your website on www.mysite.com, for your images you could assign the name images.mysitestatic.com, and this way you know that you don't have any cookies on the mysitestatic.com domain name that your user would need to upload and download on each request.

There are many advantages to hosting you images on a server as opposed to data pass through like your _images.ashx. As far as the urls you presented above, they both are pretty much the same. Unless you are looking to get seo value out of them it doesn't really matter. The url depends on your goals for performance/caching/seo, etc.

Hope this helps. Mark

Mark At Ramp51
  • 5,343
  • 1
  • 25
  • 30
  • Thanks mark, some interesting thoughts there. You ought to start a blog! Point #2 and #4 are features of any cdn, and the point behind this querystring -> filename operation is so that images can be stored on the local filesystem rather than retrieved from the database every time (doing it on a first-run-basis is fine), so thats point #3. I think where Amazon excells are in its (international) distribution, pricing model and api (although i havent had personal experience of this. – maxp Dec 02 '10 at 09:56
0

Sorry, I'm new to this but I wanted to comment on the answer above.

I don't understand what you gain by BASE64 encoding the url? It won't make the url shorted, the base64 encoded string will usually be about 33% longer.

Here is an example: C:\images\myimage.png

Base64 encoded: QzpcaW1hZ2VzXG15aW1hZ2UucG5n

If you wanted to keep the url short, and you wanted to make sure the filename is correct per the solution above, you should just use the filename itself. The base64 encoded version isn't offering you any benefit.

Although, I'm not sure this helps you because its not related to you database solution at all. unless you were to store "images/myimage.png" in a field in your database and have your url look as follows: foo.com/images/image.jpg?h=5&w=10

With that format, the name of the resource being requested, is separated from the representation of the image at a height of 5 and width of 10.

Mark At Ramp51
  • 5,343
  • 1
  • 25
  • 30