is an HTTP/1.1 request implicitly keep-alive by default? - http

Solved: pasting the bytes here made me realise that I was missing empty lines between chunks...
Does an HTTP/1.1 request need to specify a Connection: keep-alive header, or is it always keep-alive by default?
This guide made me think it would; that, when my http server gets a 1.1 request, it is keep-alive unless explicitly receiving a Connection: close header.
I ask since my the different client behaviour of ab and httperf is driving me mad enough to wonder my sanity on this one...
Here's what httperf --hog --port 42042 --print-reply body sends:
GET / HTTP/1.1
User-Agent: httperf/0.9.0
Host: localhost
And here's my server's response:
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked
Content-Length: 18
12
Hello World 1
0
httpref promptly prints out the response, but then just sits there, neither side closing the connection and httpref not exiting.
Where's my bug?

From RFC 2616, section 8.1.2:
A significant difference between HTTP/1.1 and earlier versions of HTTP is that persistent connections are the default behavior of any HTTP connection. That is, unless otherwise indicated, the client SHOULD assume that the server will maintain a persistent connection, even after error responses from the server.

Related

How to force full HTTP delivery when client requests Range?

Let's say a client makes a request like the following (pulled from iOS):
GET /test.mp4 HTTP/1.1
Host: example.com:80
Range: bytes=0-1
X-Playback-Session-Id: 3DFA3BE3-CB22-4EC5-808F-B59A735DCECE
Accept-Encoding: identity
Accept: */*
Accept-Language: en-us
Connection: keep-alive
User-Agent: AppleCoreMedia/1.0.0.11B554a (iPad; U; CPU OS 7_0_4 like Mac OS X; en_us)
There other such requests out there, I believe Chrome might test the waters by asking for blank Range.
How can the server respond to any such request so that it does not need to honor Range , but rather treat it as a standard HTTP delivery, and the client will play the file?
Sending a regular header response and the data as though the client were not asking for Range does not seem to work.
EDIT: Conversely, if the client does not request a Range, is it okay to respond with HTTP 206 with full filesize in Content-Length and also Content-Range header (which client will ignore)?
If the server does not support the Range header, it would send a normal 200 reply to send the entire file. If the server supports the Range header, it would send a 206 or 416 reply, depending on whether the requested range can be satisfied or not. This is covered in RFC 2616 Section 14.35.
It is not OK to respond with 206 if the client did not request a Range.
Try responding with HTTP 1.0 - it doesn't support range requests at all.
Maybe the client will treat such a reply more gracefully.

Why tomcat reply HTTP 1.1 respose with an HTTP 1.0 request?

Request:
POST / HTTP/1.0
Content-Type: text/xml; charset=UTF-8
User-Agent: Axis2
Host: localhost:8000
Content-Length: 539
Response from tomcat:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=UTF-8
Date: Sat, 19 Oct 2013 00:28:57 GMT
Connection: close
From tomcat website it says:
If the client (typically a browser) supports only HTTP/1.0, the
Connector will gracefully fall back to supporting this protocol as
well. No special configuration is required to enable this support.
How Tomcat gracefully fall back to HTTP 1.0? From my example it still reply HTTP 1.1. Can anyone explain to me?
The protocol version indicates the protocol capability of the sender. It does not specify the version of the response itself. So as long as the response can be understood by the HTTP 1.0 client, Tomcat is doing exactly what it should.
It's all in RFC2616...
Edit: And it's even in the Tomcat documentation itself, right after the part you quoted:
This Connector supports all of the required features of the HTTP/1.1 protocol, as described in RFC 2616, including persistent connections, pipelining, expectations and chunked encoding. If the client (typically a browser) supports only HTTP/1.0, the Connector will gracefully fall back to supporting this protocol as well. No special configuration is required to enable this support. The Connector also supports HTTP/1.0 keep-alive.
RFC 2616 requires that HTTP servers always begin their responses with the highest HTTP version that they claim to support. Therefore, this Connector will always return HTTP/1.1 at the beginning of its responses.

Can I access .info/serverTimeOffset from REST API?

I have successfully used the .info/serverTimeOffset to manage clock skew value from the Javascript library.
However when trying to access from REST I get an error.
GET https://my-firebase-name.firebaseio.com/.info/serverTimeOffset/.json HTTP/1.1
Content-Length: 0
Accept-Encoding: identity, deflate, compress, gzip
Accept: */*
HTTP/1.1 400
content-length: 32
content-type: application/json; charset=utf-8
cache-control: no-cache
{
"error" : "Invalid path."
}
Is this or any of the .info values available from REST?
The correct values for .info/connected and .info/serverTimeOffset don't really make sense from a REST call's perspective and are therefore unavailable. There isn't a reliable way to for the server to know the client's time while making a REST call to serverTimeOffset so the number cannot be calculated accurately. Similarly, there is no concept of "disconnected" since a HTTP request terminates after completion.

Is it mandatorty to keep the connection-alive property when we use chunked property?

My client sets the following headers:
Transfer-Encoding: chunked
Connection: Keep-Alive
When I retrieve responses I receive a Transfer-Encoding: chunked header but no Connection: Keep-Alive header. For this reason I believe I may only be receiving a partial response in my client.
Now my question is:
Is it mandatory to set the Connection: Keep-Alive property in HTTP/1.1 ?
In short, no. In the absence of a Connection header for messages adhering to HTTP/1.1 the default is a persistent Keep-Alive connection. If a connection header is present both parties should act accordingly given that header's value.
As stated by RFC 2616 Section 8.1.2:
A significant difference between HTTP/1.1 and earlier versions of HTTP
is that persistent connections are the default behavior of any HTTP
connection. That is, unless otherwise indicated, the client SHOULD
assume that the server will maintain a persistent connection, even
after error responses from the server.
Of course, this doesn't prevent you from explicitly setting a Connection: close header if you wish to close the connection once the transfer completes.

Is persistent HTTP with HTTP/1.0 possible?

I am using a 3G UMTS connection. I am trying to implement HTTP tunneling to a server of mine
which listens on port 80 (this is done in order to bypass client's firewall). The problem is that the ISP's proxy server supports HTTP/1.0 which doesn't support persistent HTTP connection.
As a result, after one http request/response iteration between my client/server the ISP's proxy tears down the underlying TCP connection.
my client receives the following HTTP response:
HTTP/1.0 200 OK
Content-Type: application/octet-stream
Content-Length: yyy
X-Cache: MISS from ipmr5
Proxy-Connection: close
Content data
while my server actually sends:
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Type: application/octet-stream
Content-Length: yyy
Content data
Is there any workaround?
You could always use HTTPS. You will lose any benefits offered by the proxies (such as caching), but all of your HTTP headers will arrive at the server exactly as you sent them.
HTTP 1.0 proxies (which it seems your ISP uses) shouldn't be used in connection with Connection: Keep-Alive for persistent connections. The reasons for this are outlined in RFC-2068 (section 19.7.1). The short version, basically, is that your server is sending an invalid header for the kind of proxy you are using.

Resources