HTTP Keep-Alive Header - http

HTTP/1.1 servers default to the Keep-Alive setting of the Connection header. Why
then do most browsers include Connection: Keep-Alive in their requests even when
they know that the target server supports HTTP/1.1?

Browsers usually don't keep a cache of metadata about the servers they've contacted in the past, and even if they did, they'd have to account for server farms that have different versions of HTTP, intermediaries (especially "transparent" proxies), and so forth.
As such, they've made a judgement call that it's just easier to always send Connection: keep-alive, at least on the first request in a connection.

The question doesn't make sense. The browser doesn't know what the server supports until after it has submitted the request and obtained a response.

Related

How do I manage/work with cookies in a websocket based application?

My application uses an express server to serve a single-page-application and then the rest of the communication is handled by websockets. My issue is, how would I manage cookies if they're sent through HTTP interactions? I don't think websockets were really meant to work with cookies, but I need to use cookies for things like remembering logins. Do I need to, or is it best to, continue using HTTP for things involving cookies (and have the HTTP server run on a separate port from my websocket server)? Or is there another recommended solution?
Websockets is a communication protocol, you send data back and forth just like your TCP protocol which sends HTTP application data. Browsers know how to interpret HTTP requests and responses and infere cookie data from headers. Here is the example of cookie header: Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Now since you transfering data via Websockets all you need to do is tell browser what to do with data.
So in order to set a cookie in your browser you would use document.cookie = "username=John Doe" which sets a key pair cookie entry in your browser.
Please refer to:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie

Understanding the value of the header HTTP2-Settings used for http/2 requests and upgrade

I'm writing a simple app to determine if certain websites support http/2.
Based on what I've read in the draft:
https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-http2-07#section-3.2
I should be able to do a get request such as
GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>
and then if they support http/2 the response should be something like:
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: HTTP/2.0
[ HTTP/2.0 connection ...
I'm trying to understand exactly what the value of the HTTP2-Settings request header should be.
I'm hoping someone can explain what information should be included with an example.
HTTP/2 has reached the status of official standard.
You will have very little luck in determining whether websites support HTTP/2 by using the cleartext upgrade mechanism.
The reason is that browsers don't support this style of upgrade to HTTP/2 (they all prefer using ALPN over TLS), and therefore neither servers do.
[Disclaimer, I am a Jetty committer and the Jetty HTTP/2 implementor].
For example, Jetty does support this style of upgrade (and even direct HTTP/2), see for example these tests, but we don't deploy it on our own website, https://webtide.com, for the reasons above.
You don't need to send something in this upgrade SETTINGS frame, you want to only send it if you want to configure the server before it gets a chance to speak back HTTP/2 to you, but typically default values are ok.
Remember that, as part of the connection preface, the client has to send another SETTINGS frame, which also can be empty or contain configuration parameters. Typically HTTP/2 client APIs such as the Jetty HTTP2Client will allow you to easily configure the SETTINGS frame that is part of the preface, because it's what will be use in both the upgrade mechanism and the ALPN mechanism.
A minimal, valid value for the HTTP2-Settings header is the empty string:
GET / HTTP/1.1
Host: host
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings:
User-Agent: whatever
Otherwise you need to create a SETTINGS frame payload (only the bytes defined here, and hence without the 9 octet frame header defined here), and then convert those bytes using base64 as defined here.
For the purpose of your tests, an empty HTTP2-Settings header will do, but as I said, you will most certainly not detecting whether a website supports HTTP/2: your upgrade will fail, but the website may well support HTTP/2 over TLS via ALPN.
This site http://nghttp2.org/ accepts non encrypted HTTP2 (h2c) connections, so doing:
GET / HTTP/1.1
Host: nghttp2.org
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings:
User-Agent: whatever
As suggested by sbordet does produce a "101 Switching Protocols" response from the server.

What HTTP client headers should I use to instruct proxies to refetch from origin, and cache the response?

I'm currently working on a system where a client makes HTTP 1.1 requests of an origin server. I control both the client and the server software, so have free reign over HTTP headers set. Between the client are multiple, hierarchical layers of web proxy / cache devices (think, Squid or similar).
The data served up by the origin is usually highly cacheable, and I intend to set HTTP response headers to indicate this. Specifically, I plan to use Cache-Control: public, max-age=<value>. I understand that this will mean that intermediate proxies will cache the response up to the specified max-age, at which point they will revalidate against the origin (presumably with a Last-Modified header, looking for a 304 response).
The problem I have is that the client might become aware that the data held by caches might now be invalid. In this case, I need the client to make a request which instructs the caches to either fetch or revalidate their response with the origin. If the origin response is now different, the cache should store this new response. In my mind, this would involve the client making the request, and each cache in the chain should revalidate its response with the next upstream device, all the way back to the origin. The new response can then be served from the closest cache which actually has it.
What's the correct HTTP headers that need to be set on the client request to achieve this? At first I thought that setting Cache-control: no-cache in the HTTP request would make this happen, but reading the RFC, it seems that this will instruct the intermediate caches to both go back to the origin (desired) but also not cache the new response (not desired). I then saw an article in which an HTTP request header of Cache-control: max-age=0 would perhaps do this, but I'm not sure.
Will max-age=0 do what I need here, or do I need some other combination of HTTP headers?
I asked a similar question here: How to make proxy revalidate resource from origin. I since learned that proxy revalidate wasn't supported by nginx at the time of writing. It is scheduled for the 1.5 release.
Sending max-age=0 from the client should trigger this revalidate mechanism in the proxy, if the original response from the origin contained the right cache control headers.
But whether your upstream server(s) will respect these headers and revalidate with their origin is clearly not something you can just assume. If you have control over your upstream servers I think it could work.
Also etag is preferred over modified since headers afaik.
I found these to be helpful articles on the subject:
caching tutorial
cache control directives
http specs on validation
section 14.9.4 on this spec
[UPDATE]
Nginx version 1.5.8 has been released since, and I can confirm that this mechanism is now working!

Setting Request header: Connection

By default Connection Header is set to Keep-Alive in browers, to make it possible to keep connection open for further requests from browser.
When I make Connection header to close, what may be the difference ?
Will that affect any performance issue ?
(one addition: I am setting header from xmlhttprequest)
When you make requests with "Connection: keep-alive" the subsequent request to the server will use the same TCP connection. This is called HTTP persistent connection. This helps in reducing CPU load on the server side and improves latency/response time.
If a request is made with "Connection: close" this indicates that once the request has been made the server needs to close the connection. And so for each request a new TCP connection will be established.
By default HTTP 1.1 client/server uses keep-alive whereas HTTP 1.0 client/server doesn't support keep-alive by default.
It affects performance, because most expensive resources create a socket between two machines. So the client needs to establish a new connection in every request.
this article has graphically demonstrated what would happen in such a when the connection header is set to closed and also keep-alive.
It helped me understand it and I hope it helps you too.
The Benefits of Connection Keep Alive

How do HTTP proxy caches decide between serving identity- vs. gzip-encoded resources?

An HTTP server uses content-negotiation to serve a single URL identity- or gzip-encoded based on the client's Accept-Encoding header.
Now say we have a proxy cache like squid between clients and the httpd.
If the proxy has cached both encodings of a URL, how does it determine which to serve?
The non-gzip instance (not originally served with Vary) can be served to any client, but the encoded instances (having Vary: Accept-Encoding) can only be sent to a clients with the identical Accept-Encoding header value as was used in the original request.
E.g. Opera sends "deflate, gzip, x-gzip, identity, *;q=0" but IE8 sends "gzip, deflate". According to the spec, then, caches shouldn't share content-encoded caches between the two browsers. Is this true?
First of all, it's IMHO incorrect not to send "Vary: Accept-Encoding" when the entity indeed varies by that header (or its absence).
That being said, the spec currently indeed disallows serving the cached response to Opera, because the Vary header does not match per the definitions in HTTPbis, Part 6, Section 2.6. Maybe this is an area where we should relax the requirements for caches (you may want to follow up on the IETF HTTP mailing list...
UPDATE: turns out that this was already marked as an open question; I just added an issue in our issue tracker for it, see Issue 147.
Julian is right, of course. Lesson: Always send Vary: Accept-Encoding when sniffing Accept-Encoding, no matter what the response encoding.
To answer my question, if you mistakenly leave Vary out, if a proxy receives a non-encoded response (without Vary), it can simply cache and return this for every subsequent request (ignoring Accept-Encoding). Squid does this.
The big problem with leaving out Vary is that If the cache receives an encoded variant without Vary then it MAY send this in response to other requests even if their Accept-Encoding indicates the client can not understand the content.

Resources