What is the right way to handle image extensions? - http

I'm looking to handle image extentions .jpg, .png, .gif, etc. Essentially, what I have is a webserver that takes an image and archives it on the basis of its SHA-1. I use the git convention a1\b2\XXXXXX... with the hex representation of the digest. My question is how is it best to store the extension in the database? Am I safest storing the MIME type? Or, the original file type? Or, should I just auto-generate the MIME each time? Should I store the mime-type the original client sent in the HTTP upload?
As a side note, does IE7+ handle images without file extensions? Is it safe to just send them out without them?
Any other advice on web servers and image types?

Screw the extension. Use libmagic to figure out what it really is and send it out like that. But of course you're going to make sure that the extension matches the file contents in the first place, right?

Related

Are file extensions necessary for Azure blobs?

I'm using an Azure storage account to store images and files as block blobs.
Browsers seem to be able to serve images correctly without an extension as long as the content type property is set. For example this will show up as a normal image: https://navhomeprod.blob.core.windows.net/facilityroomphotos/12
Would it be better for any reason to save the blob name with an extension: https://navhomeprod.blob.core.windows.net/facilityroomphotos/12.jpg
The reason I chose not to have extensions is so that I didn't need an extension field in the database, I could just use ids to serve the images.
Simple answer is no. You don't really need to specify a file extension in order to serve images. The catch here is that content type should be set properly. Content type tells browsers how to serve the content.
Even if you have the extension set but content type not set, some browsers will not be able to serve the content in that case. I have seen many questions where Chrome prompted to download an image file instead of showing the content inline if the content-type of that image file not set properly.
One use case that I could think of where the file extension will be handy is when you download these files on your local computer. Based on the file extension, your local computer would decide the application to use to view/edit these files.

Force file download in a browser using ASP.Net MVC when the file is located on a different server without downloading it on my server first

Here's what I would like to accomplish:
I have a file stored in Windows Azure Blob Storage (or for that matter any file which is not on my web server but accessible via a URL).
I want to force download a file without actually downloading the file on my web server first i.e. browser should automatically fetch the file from this external URL and prompts the user to download it.
Possible Solutions Explored:
Here's what I have explored so far (and why they won't work):
Using something like FileContentResult as described here Returning a file to View/Download in ASP.NET MVC to download the file. This solution would require me to fetch the contents on my server and then stream from my server to the browser. For this reason this solution won't work.
Using HTML 5 download attribute: HTML 5 download attribute would have worked perfectly fine however the problem is that while it is really a very neat solution, it is not supported in all browsers.
Changing the file's content type: Another thing I could do (at least for the files that I own) to change the content type property of the file to something that the browser wouldn't understand and thus would be forced to download the file. This might work in some browsers however not in all as IE is smart enough to go beyond the content type and sees the file's content to determine the content type. Furthermore if I don't own the files, then I won't have access to changing the content type of the file.
Simply put, in my controller action I should be able to specify the URL of the file and somehow browser should force download the file.
Is this something which can be accomplished? If yes, then any ideas how I could accomplish this?
Simply put, in my controller action I should be able to specify the URL of the file and somehow browser should force download the file [without exposing the URL of the file to the client].
You can't. If the final URL is to remain hidden, your server must serve the data, so your server must download the file from the URL.
Your client can't download a file it can't get the URL to.
You can create file transfer WCF service (REST) which will stream your content from blob storage or from other sources through your file managers to client browser directly by URL.
https://{service}/FileTransfer/DownloadFile/{id, synonym, filename etc}
Blob path won't be exposed, web application will be free from file transfer issues.

How to serve resx file in ASP.NET?

How can i serve a locale appropriate .resx file to a http client in ASP.NET?
e.g.
GET /App_LocalResources/MeshModdler.resx
Background
i have a client-side binary that needs to ask a web-server for the appropriate language resources (i.e. it does not have all possible translations; it asks for the one it needs).
Right now the client-side binary prefers to be given an xml file containing all the localized resources (strings, etc). This XML file has a format that looks curiously like Microsoft's resx format (one might think the format was copied - and they would not be wrong).
Ideally we can use the power of an ASP.NET web-server to locate the appropriate resx file based on the http client's Accept-Language, e.g.
GET /App_LocalResources/MeshModdler.resx
Accept-Language: az-Cyrl-AZ
Ideally the web-server would try to return, in order of preference:
MeshModdler.az-Cyrl-AZ.resx
MeshModdler.az-AZ.resx
MeshModdler.az.resx
MeshModdler.resx
But instead the server returns:
HTTP/1.1 404 Not Found
Bonus Chatter
i know this is not possible. So in addition to a cannot be done answer, i would also accept an answer that just does what i want:
harnesses the power of an ASP.NET web-server to perform resource resolution and fallback
allows new localization resx files to be dropped into a folder and have them picked up
will not require resorting to creating a dummy page that builds what looks like a resx file, but has to thunk every entry with:
<root>
<data name="TesselateMesh.Caption">
<value><%$ Resources:MeshModdler, TesselateMesh.Caption1 %></value>
</data>
...
</root>
Additional Chatter
The hack for now will be to rename the resx files to xml:
MeshModdler.az-Cyrl-AZ.xml
MeshModdler.az-AZ.xml
MeshModdler.az.xml
MeshModdler.xml
And re-invent the fallback code:
GET /MeshModdler.az-Cyrl-AZ.xml
404 Not found
GET /MeshModdler.az-AZ.xml
404 Not found
GET /MeshModdler.az.xml
200 Ok
But it would be nice to work with ASP.NET, not against it.
You can create an ASHX file that takes a resource name file and looks up the correct .ResX file on the server. (moving your current fallback logic to /GetResource.ashx?Name=MeshModeler)

Download a file stored in database

I have file content in sql database as binary format and also saved the file with its extension .
I want to have pop up for save as ,so that client can save the file on her system in the same document format.
i.e if it .doc then it should get save in .doc format only.
Please provide the code for the same.
You need to
Set up IIS to to handle files of the types you want. For example, you need to map .pdf, .jpg, etc, to be handled by the ASP.net dll. Also is important to make sure "Verify file exists" is off: http://msdn.microsoft.com/en-us/library/bb515343.aspx
Create a HTTP Handler for the files to retrieve the binary from the database and .BinaryWrite it out to the output stream: http://www.developer.com/net/asp/article.php/3565541/Use-Custom-HTTP-Handlers-in-Your-ASPNET-Applications.htm
Set up your web.config file to map the file types required to the handler you created (this is detailed in the url provided for point 2)
You say that you want it to open as a download box, and not just open in the browser. To do this you have to use the content-disposition HTTP header. So in your custom handler you write, make sure to add a header specifiying the content-disposition as attachment. http://support.microsoft.com/kb/260519 will tell you what you need.
I want to have pop up for save as ,so
that client can save the file on her
system in the same document format.
i.e if it .doc then it should get save
in .doc format only.
You take care of this when you write out the content disposition HTTP header. Refer to the MS link I provided and make sure you specify a filename with the correct extension.
Also note the comments above. If this helps you, you need to accept it as the answer. Also go back and accept some answers on your older questions. Otherwise people are not inclined to help you. I will help you again if you mark this as answer, or leave me a comment about why it does not answer your question.
Good luck
bgs264

Getting an incorrect file extension and content type when uploading file

I have an asp.net application where the users can upload files to our database.
Sometimes when they upload the files, the content-type is set as "application/octet-stream" which is a binary file.
When I ask the user, they say that they uploaded they say it was a .tif file. Somehow the upload control sets it as "application/octet-stream".
When I upload the same .tif file from my computer it uploads with the correct content type (application/octet-stream).
I am using the following code to get the file extension
fileExtension = filUpload.PostedFile.FileName.Substring(filUpload.PostedFile.FileName.LastIndexOf(".") + 1)
sometimes it returns the file extension as "c:\documen" or "j:\testing" etc. I know that windows doesn't allow special characters in the filename.
You simply can't rely on the browser to submit a usable MIME media type. The client machine may not have any media type information set up for a particular filetype (which is likely the case for TIFF here), or it may not support sending media types at all, or there may be bugs in it (as there have been in the past with IE).
You also can't rely on the browser to submit a usable filename extension. The client machine may not use file extensions to determine the type of the file. (Indeed, Macs and modern Linux use multiple mechanisms to determine type, so any filename extension may be misleading, if one is present at all.)
For that matter, you can't even rely on the browser to submit a usable filename in the first place! Not every OS uses backslash character and dot for directory and extension separators; the submitted filename is effectively an opaque string which you can use for guessing some of the common cases, but you can't consider to be definitive.
So the only reasonable ways to determine the type of an uploaded file are:
Ask the user explicitly what type they're uploading.
Try to guess what type it might be from media type and trailing filename, falling back to asking the user what type it is.
If the types you want to allow are all ones with sniffable headers (as TIFF and most other image formats are), you can work out the type by looking at the contents of the file.
Use functions in the System.IO namespace to parse it out instead.
To get the extension, you would do this:
fileExtension = System.IO.Path.GetExtension(filUpload.PostedFile.FileName);
I believe that the user's browser sends a declared MIME type along with the file. It's then up to the browser to declare the type of the file. Different browsers may have different ability to infer the best MIME type from a file. When you get the file on your server, you might just check for the .tif[f] extension -- that's probably all the checking that the uploading browser will do anyways.

Resources