Correct HTTP Headers for Images? - image

I'm writing a web server in C#, just for the fun of it, and I am able to serve basic text files to my browser. However, when serving up an image (say, image.png), all browsers that I test my server on (IE, Firefox, and Chrome) show some kind of placeholder thumbnail for the image, as if the image is corrupted or invalid.
The response that I am sending to the browser looks like
HTTP/1.0 200 Ok
Content-Type: image/png
Content-Length: 14580053
{image data here}
Am I using the correct HTTP headers? Or, if I am, why else would browsers not accept the image?

Ah, figured it out... my code forgot to add an extra \n before the response body. It wasn't a problem with the headers at all, just incorrect response syntax.

Related

Invalid-Content-Type error when trying to send GIF through Twilio SMS

I have this bit of code to send an MMS message with a GIF. (using Ruby with Sinatra, hosted on Heroku).
client.messages.create(
to: to,
from: phone,
body: message,
media_url: 'http://media.giphy.com/media/zl170rmVMCpEY/giphy.gif'
)
It fails, and Twilio's debug console shows a 12300 invalid content-type error. I'm certain I'm missing something simple here, but I cannot figure out what.
The URL you are using is returns a different type of content based on the Accept header of the request.
In Chrome a response with a "Content-Type" header of "text/html". Which is surprising given the .gif suffix on the URL.
Chrome accept headers look like: Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
However if I use curl -I http://media.giphy.com/media/zl170rmVMCpEY/giphy.gif I get Content-Type: image/gif
If you look at the image URL on the HTML page, in Chrome, it is actually: https://i.giphy.com/zl170rmVMCpEY.webp
webp is an alternative format to gif, I suspect it is served instead of gif if the browser supports it.
If Twilio supports webp format images you could use that instead.
Gify also seem to use mp4 format, it looks like they brand as gif, but don't actually serve gif's to clients which can accept HTML or WebP content.

No If-Modified-Since header when using ng-src (for caching)

I am trying to ensure that my images are cached. My spring controller implements a check to see if the image has changed since the last modified time ( http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-lastmodified )
The problem is that ngSrc / ng-src is not sending up the If-Modified-Since header. Is there a way to make this happen? Am I doing something wrong?
It looks like SpringMVC is adding no-cache headers to the original image, so that could be the cause of the problem - investigating how to turn them off!

Serving content depending on http accept header - caching problems?

I'm developing an application which is supposed to serve different content for "normal" browser requests and AJAX requests for the same URL requested.
(in fact, encapsulate the response HTML in JSON object if the request is AJAX).
For this purpose, I'm detecting an AJAX request on the server side, and processing the response appropriately, see the pseudocode below:
function process_response(request, response)
{
if request.is_ajax
{
response.headers['Content-Type'] = 'application/json';
response.headers['Cache-Control'] = 'no-cache';
response.content = JSON( some_data... )
}
}
The problem is that when the first AJAX request to the currently viewed URL is made strange things happens on Google Chrome - if, right after the response comes and is processed via JavaScript, user clicks some link (static, which redirects to other page) and then clicks back button in the browser, he sees the returned JSON code instead of the rendered website (logging the server I can say that no request is made). It seems for me that Chrome stores the latest request response for the specific URL, and doesn't take into account that it has different content-type etc.
Is that a bug in the Chrome or am I misusing HTTP protocol ?
--- update 12 11 2012, 12:38 UTC
following PatrikAkerstrand answer, I've found following Chrome bug: http://code.google.com/p/chromium/issues/detail?id=94369
any ideas how to avoid this behaviour?
You should also include a Vary-header:
response.headers['Vary'] = 'Content-Type'
Vary is a standard way to control caching context in content negotiation. Unfortunately it has also buggy implementations in some browsers, see Browser cache vary broken.
I would suggest using unique URLs.
Depending of you framework capabilities you can redirect (302) the browser to URL + .html to force response format and make cache key unique within browser session. Then for AJAX requests you can still keep suffix-less URL. Alternatively you may suffix AJAX URL with .json instead .
Another options are: prefixing AJAX requests with /api or adding some cache boosting query params ?rand=1234.
Setting cache-control to no-store made it in my case, while no-cache didn't. This may have unwanted side effects though.
no-store: The response may not be stored in any cache. Although other directives may be set, this alone is the only directive you need in preventing cached responses on modern browsers.
Source: Mozilla Developer Network - HTTP Cache-Control

valums file-uploader IE and #Responsebody. IE Launches download dialog.

I am using valums file-uploader to upload files. This works great if my Spring controller returns void. If I add a #Responsebody Object to my controller IE things that I am about to download instead of uploading a file and launches a dialog.
The reason I would like to have a #Responsebody Object and not void is for error handling. How can I trick IE in this case?
I'm assuming that Spring is automagically setting the content-type to application/json for you, which will not work in IE. Ensure the content-type of your response is text/plain. Some will say that text/html is correct, and that is true for most cases. However, text/html will cause you problems if your JSON response contains HTML as IE will mess with the response. So, your safest bet is to ensure the content-type of your response is text/plain.
While we are on the topic of IE quirkiness, also be sure that you only return a 200 response if you intend to also include JSON in your response. IE will, by default, replace the content of "small" non-200 responses with a "friendly" message. "Small", I believe, is defined as a response that is less than 512 (or possibly 256) bytes.
For a list of all things you should be aware of when using IE, have a peek at the "limitations of IE" section in the Fine Uploader readme.

Asian characters in IE 8 get garbled in Server; is this due to HTTP header Content-Type?

One of the request parameters in an http request made by the client contains Japanese characters. If I make this request in Firefox and look at the parameter as soon as it reaches the server by debugging in Eclipse, the characters look fine. If I do the same request using IE 8, the characters get garbled when I look at them at the same point in the server code (they are fine in both browsers, though). I have examined the POST requests made by both browsers, and they both pass the same sequence of characters, which is:
%2C%E3%81%9D%E3%81%AE%E4%BB%96
I am therefore thinking that this has to do with the encoding. If I look at the HTTP headers of the request, I notice the following differences. In IE:
Content-Type: application/x-www-form-urlencoded
Accept: */*
In Firefox:
Content-Type application/x-www-form-urlencoded; charset=UTF-8
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
I'm thinking that the IE 8 header doesn't state the UTF-8 encoding explicitly, even though it's specified in the meta tag of the HTML document. I am not sure if this is the problem. I would appreciate any help, and please do let me know if you need more information.
Make sure the page that contains the form has UTF-8 as charset. In IE's case, the best thing to make sure of this is by sending a HTTP header ('Content-Type: text/html; charset=utf-8') and adding a meta http-equiv tag with the content type/charset to your html (I've seen this actually matter, even when the appropriate header was sent).
Second, your form can also specify the content type:
<form enctype="application/x-www-form-urlencoded; charset=utf-8>

Resources