Content-Length: 0 with OWIN - owin

What is the correct way to handle Content-Length when writing body content in an Owin middleware?
Currently we're using
context.Response.Write(data); // data is a string.
In most cases it works, but in some (IIS host on Win 2012 R2) the Content-Length gets a value of 0.
I thought that setting the Content-Length header, or the option to use Transfer-Encoding: chuncked was up to the host to handle, but it looks like I'm missing something.
What is the correct way to handle the Content-Length when writing body content to an OWIN Response stream?
We've also discussed the bug in a github issue.

It is primarily a host concern. The application may choose to set content-length if it knows exactly what it will be, but otherwise the app should let the server choose to set content-length or chunked.

Related

Is Strict-Transport-Security needed in error pages (400, 401, 403, 500...)?

I have a doubt related to the hsts response header. I'm developing a web application and currently I covered all the endpoints (with 200 ok responses)... this means that all the endpoints will return the hsts header when the response is 200. I don't know if it is needed for the server errors too. Thanks!
We usually include the HSTS header in all server responses no matter which HTTP status code is provided. In most cases this is easier to implement than everything else (either through config or one dedicated filter to rule them all). On the other hand there is no reason not to do it this way - the TLS channel has been opened successfully.
EDIT: Oh, and there are some other opinions on this too: https://security.stackexchange.com/questions/122441/should-hsts-header-be-sent-on-an-error-response

"Accept-Language" header missing in http request from the browser

We have come across an issue in production logs where "Accept-Language" is missing in the http request from the browser. Although I am not able to replicate it so I want to understand any valid use case where any specific browser may send a request without "Accept-Language" header.
Even GET / HTTP/1.0 is a valid HTTP request. You can create one from the telnet client if you wish and it will still return a result from the server!
Accept-Language is a header to aid in content negotiation and is optional. The most widely used browsers send the correct headers, but there may be corporate proxies who may be filtering such headers. You should not rely on this header being present.

304 Not Modified When If-None-Match is valid

I am optimizing an Express JSON API for consumption by iOS & Android Apps and do not seem to be able to get Express to respond with the correct 304 header when the Apps specify an etag within the If-None-Match header.
I needn't setup Etag generation as Express was already providing those; however when the Apps specify that etag again in a second request; Express' response is still a 200 with the data, as you can see in my tests in Postman:
How can I enable this functionality?
Update: The iOS dev is seeing the correct 304 Not Modified responses from the Express server but I don't understand why I am not seeing them within Postman - Does Postman support such actions?
I just stumble across this today, you need to disable Postman default behaviour of sending Cache-Control as none. To do this just go to settings change Send no-cache header to No.

HTTP Headers - Cache Question

I am making a a request to an image and the response headers that I get back are:
Accept-Ranges:bytes
Content-Length:4499
Content-Type:image/png
Date:Tue, 24 May 2011 20:09:39 GMT
ETag:"0cfe867f5b8cb1:0"
Last-Modified:Thu, 20 Jan 2011 22:57:26 GMT
Server:Microsoft-IIS/7.5
X-Powered-By:ASP.NET
Note the absence of the Cache-Control header.
On subsequent requests on Chrome, Chrome knows to go to the cache to retrieve the image. How does it know to use the cache? I was under the impression that I would have to tell it with the Cache-Control header.
You have both an ETag and a Last-Modified header. It probably uses those. But for that to happen, it still needs to make a request with If-None-Match or If-Modified-Since respectively.
To set the Cache-Control You have to specify it yourself. You can either do it in web.config , IIS Manager for selected folders (static, images ...) or set it in code. The HTTP 1.1 standard recommends one year in future as the maximum expiration time.
Setting expiration date one year in future is considered good practice for all static content in your site. Not having it in headers results in If-Modified-Since requests which can take longer then first time requests for small static files. In these calls ETag header is used.
When You have Cache-Control: max-age=315360000 basic HTTP responses will outnumber If-Modified-Since> calls and because of that it is good to remove ETag header and result in smaller static file response headers. IIS doesn't have setting for that so You have to do response.Headers.Remove("ETag"); in OnPreServerRequestHeaders()
And if You want to optimize Your headers further You can remove X-Powered-By:ASP.NET in IIS settings and X-Aspnet-Version header (altough I don't see in Your response) in web.config - enableVersionHeader="false" in system.web/httpRuntime element.
For more tips I suggest great book - http://www.amazon.com/Ultra-Fast-ASP-NET-Build-Ultra-Scalable-Server/dp/1430223839

IIS website is sending multiple content-type headers for zip files

We have a problem with an IIS5 server.
When certain users/browsers click to download .zip files, binary gibberish text sometimes renders in the browser window. The desired behavior is for the file to either download or open with the associated zip application.
Initially, we suspected that the wrong content-type header was set on the file. The IIS tech confirmed that .zip files were being served by IIS with the mime-type "application/x-zip-compressed".
However, an inspection of the HTTP packets using Wireshark reveals that requests for zip files return two Content-Type headers.
Content-Type: text/html;
charset=UTF-8
Content-Type:
application/x-zip-compressed
Any idea why IIS is sending two content-type headers? This doesn't happen for regular HTML or images files. It does happen with ZIP and PDF.
Is there a particular place we can ask the IIS tech to look? Or is there a configuration file we can examine?
I believe - and i may be wrong that the http 1.1 header sends multiple headers definitions and the most specific has precedence .
so in your example here it is sending 2 text/html and then application/x-zip-commercial so the second one would be the most specific - if that cant be handled on the client then the more general one is used (the first one in this case ) -
I have read through this http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html and that sort of points to what you are saying - not sure if this is what is actually happening though.
Of course i may be totally wrong here
Make sure that you don't have any ISAPI filters or ASP.net HTTP modules set up to rewrite the headers. If they don't check to see if the header already exists, it will be appended rather than replaced. We had issues a while ago with an in-house authentication module not correctly updating the headers so we were getting two Authorization headers, one from IIS and one from our module.
What software has been installed on the server to work with .zip files?
It looks like IIS picks up MIME translations from the registry, perhaps zip-software you use has registered the MIME-type. This doesn't explain why IIS would respond with two content-type headers, so any ISAPI filter and other Mime-table is suspect.
This may be related to this knowledge base article. It is suggesting that IIS may be gzipping the already zipped file, but some browsers just buck pass straight to a secondary application giving you bad data (as it has been zipped twice). If you change the mime type of the zip extension to application/octet-stream this may not happen.
It sounds like there may be a issue with your configuration of IIS. However that is not possible to tell from your post if this is the case.
You can have mime types configured on several levels on your IIS. My IIS 5 knowledge is a bit rusty, as far as I can remeber this behavior is the same for IIS 6. I tried to simulate this on a IIS 6 enviroment, but only ever received one mime type depending on the accepted header
I have set the the header for zip files on the site to application/x-zip-compressed and for the file I have explicity set it to
tinyget -srv:dev.24.com -uri:/helloworld.zip -tbLoadSecurity
WWWConnect::Connect("server.domain.com","80")
IP = "127.0.0.1:80"
source port: 1581
REQUEST: **************
GET /helloworld.zip HTTP/1.1
Host: server.domain.com
Accept: */*
RESPONSE: **************
HTTP/1.1 200 OK
Content-Length: 155
Content-Type: text/html
Last-Modified: Wed, 29 Apr 2009 08:43:10 GMT
Accept-Ranges: bytes
ETag: "747da786a6c8c91:0"
Server: Microsoft-IIS/6.0
Date: Wed, 29 Apr 2009 10:47:10 GMT
PK??
? ? ? helloworld.txthello worldPK??ΒΆ
? ? ? ? helloworld.txtPK?? ? ? < 7 ? hello world sample
WWWConnect::Close("server.domain.com","80")
closed source port: 1581
However I dont feel this prove much. It does however raise a few questions:
What is all the mime maps that have been setup on the server (ask the server admin for the metabase.xml file, and then you can make sure he has not missed some setting)
Is those clients on a network that is under your control? Probably not, I wonder what proxy server might be sitting inbetween your server and the clients
How does the IIS log's look like, for that request, I am spesifically intrested in the Accept header.
I wonder what fiddler will show?
I've encountered a similar problem. I was testing downloads on IIS 6 and couldn't figure out why a zipped file called test.zip was displaying as text in IE8 (it was fine in other browsers, where it would download).
Then I realised that for the test I'd compressed a very small text file. My guess is that IE sniffed the file, saw the text (which was pretty much uncompressed because of the small size) and decided it was plain text.
I tried again with a larger file and the download prompt appeared OK in IE8.
May not be relevant to your case, but thought I'd mention it.
Tim

Resources