Difference between revisions of "Reverse HTTP"

From Second Life Wiki
Jump to navigation Jump to search
(→‎COMET Fallback: The client indicates its unwillingness to upgrade by omitting the Upgrade: header)
Line 6: Line 6:


{| width="100%"
{| width="100%"
|style="background-color: red"|POST / HTTP/1.1
|style="background-color: #FFA0A0"|POST / HTTP/1.1
|
|
|-
|-
|style="background-color: red"|Host: localhost:9999
|style="background-color: #FFA0A0"|Host: localhost:9999
|
|
|-
|-
|style="background-color: red"|Accept-Encoding: identity
|style="background-color: #FFA0A0"|Accept-Encoding: identity
|
|
|-
|-
|style="background-color: red"|Upgrade: PTTH/0.9
|style="background-color: #FFA0A0"|Upgrade: PTTH/0.9
|
|
|-
|-
Line 22: Line 22:
|-
|-
|
|
|style="background-color: green"|HTTP/1.1 101 Switching Protocols
|style="background-color: #A0FFA0"|HTTP/1.1 101 Switching Protocols
|-
|-
|
|
|style="background-color: green"|Content-type: text/plain
|style="background-color: #A0FFA0"|Content-type: text/plain
|-
|-
|
|
|style="background-color: green"|Upgrade: PTTH/0.9
|style="background-color: #A0FFA0"|Upgrade: PTTH/0.9
|-
|-
|
|
|style="background-color: green"|Date: Tue, 13 May 2008 20:14:45 GMT
|style="background-color: #A0FFA0"|Date: Tue, 13 May 2008 20:14:45 GMT
|-
|-
|
|
|style="background-color: green"|Content-Length: 0
|style="background-color: #A0FFA0"|Content-Length: 0
|-
|-
|
|
Line 40: Line 40:
|-
|-
|
|
|style="background-color: red"|GET / HTTP/1.1
|style="background-color: #FFA0A0"|GET / HTTP/1.1
|-
|-
|
|
|style="background-color: red"|Host: 127.0.0.1:65331
|style="background-color: #FFA0A0"|Host: 127.0.0.1:65331
|-
|-
|
|
|style="background-color: red"|Accept-Encoding: identity
|style="background-color: #FFA0A0"|Accept-Encoding: identity
|-
|-
|
|
|style="background-color: red"|accept: text/plain;q=1,*/*;q=0
|style="background-color: #FFA0A0"|accept: text/plain;q=1,*/*;q=0
|-
|-
|
|
|
|
|-
|-
|style="background-color: green"|HTTP/1.1 200 OK
|style="background-color: #A0FFA0"|HTTP/1.1 200 OK
|
|
|-
|-
|style="background-color: green"|Content-type: text/plain
|style="background-color: #A0FFA0"|Content-type: text/plain
|
|
|-
|-
|style="background-color: green"|Date: Tue, 13 May 2008 20:14:45 GMT
|style="background-color: #A0FFA0"|Date: Tue, 13 May 2008 20:14:45 GMT
|
|
|-
|-
|style="background-color: green"|Content-Length: 15
|style="background-color: #A0FFA0"|Content-Length: 15
|
|
|-
|-
Line 69: Line 69:
|
|
|-
|-
|style="background-color: green"|rdlrow ,olleH
|style="background-color: #A0FFA0"|rdlrow ,olleH
|
|
|-
|-
Line 82: Line 82:


{|
{|
|style="background-color: red"|POST / HTTP/1.1
|style="background-color: #FFA0A0"|POST / HTTP/1.1
|
|
|-
|-
|style="background-color: red"|Host: localhost:9999
|style="background-color: #FFA0A0"|Host: localhost:9999
|
|
|-
|-
|style="background-color: red"|Accept-Encoding: identity
|style="background-color: #FFA0A0"|Accept-Encoding: identity
|
|
|-
|-
Line 95: Line 95:
|-
|-
|
|
|style="background-color: green"|HTTP/1.1 200 OK
|style="background-color: #A0FFA0"|HTTP/1.1 200 OK
|-
|-
|
|
|style="background-color: green"|Content-type: application/json
|style="background-color: #A0FFA0"|Content-type: application/json
|-
|-
|
|
|style="background-color: green"|Date: Tue, 13 May 2008 20:14:45 GMT
|style="background-color: #A0FFA0"|Date: Tue, 13 May 2008 20:14:45 GMT
|-
|-
|
|
|style="background-color: green"|Content-Length: 210
|style="background-color: #A0FFA0"|Content-Length: 210
|-
|-
|
|
Line 110: Line 110:
|-
|-
|
|
|style="background-color: green"|{'message-id': 'xxx', 'method': 'GET', 'request-uri': '/', 'http-version': 'PTTH/0.9', 'headers': [['Host', '127.0.0.1:65331'], ['Accept-Encoding', 'identity'], ['Accept','text/plain;q=1,*/*;q=0']], 'body': ''}
|style="background-color: #A0FFA0"|{'message-id': 'xxx', 'method': 'GET', 'request-uri': '/', 'http-version': 'PTTH/0.9', 'headers': [['Host', '127.0.0.1:65331'], ['Accept-Encoding', 'identity'], ['Accept','text/plain;q=1,*/*;q=0']], 'body': ''}
|-
|-
|style="background-color: red"|POST / HTTP/1.1
|style="background-color: #FFA0A0"|POST / HTTP/1.1
|
|
|-
|-
|style="background-color: red"|Host: localhost:9999
|style="background-color: #FFA0A0"|Host: localhost:9999
|
|
|-
|-
|style="background-color: red"|Accept-Encoding: identity
|style="background-color: #FFA0A0"|Accept-Encoding: identity
|
|
|-
|-
|style="background-color: red"|Content-type: application/json
|style="background-color: #FFA0A0"|Content-type: application/json
|
|
|-
|-
|style="background-color: red"|Content-length: 193
|style="background-color: #FFA0A0"|Content-length: 193
|
|
|-
|-
Line 130: Line 130:
|
|
|-
|-
|style="background-color: red"|{'message-id': 'xxx', 'http-version': 'PTTH/0.9', 'status': 200, 'reason': 'OK', 'headers': [['Content-type', 'text/plain'], ['Date', 'Tue, 13 May 2008 20:14:45 GMT']], 'body': 'rdlrow ,olleH'}
|style="background-color: #FFA0A0"|{'message-id': 'xxx', 'http-version': 'PTTH/0.9', 'status': 200, 'reason': 'OK', 'headers': [['Content-type', 'text/plain'], ['Date', 'Tue, 13 May 2008 20:14:45 GMT']], 'body': 'rdlrow ,olleH'}
|
|
|-
|-
|
|
|style="background-color: green"|HTTP/1.1 200 OK
|style="background-color: #A0FFA0"|HTTP/1.1 200 OK
|-
|-
|
|
|style="background-color: green"|Content-type: application/json
|style="background-color: #A0FFA0"|Content-type: application/json
|-
|-
|
|
|style="background-color: green"|Date: Tue, 13 May 2008 20:14:45 GMT
|style="background-color: #A0FFA0"|Date: Tue, 13 May 2008 20:14:45 GMT
|-
|-
|
|
|style="background-color: green"|Content-Length: 2
|style="background-color: #A0FFA0"|Content-Length: 2
|-
|-
|
|
Line 149: Line 149:
|-
|-
|
|
|style="background-color: green"|{}
|style="background-color: #A0FFA0"|{}
|}
|}



Revision as of 13:59, 23 June 2008

Reverse HTTP is an experimental protocol which takes advantage of the HTTP/1.1 Upgrade: header to turn one HTTP socket around. When a client makes a request to a server with the Upgrade: PTTH/0.9 header, the server may respond with an Upgrade: PTTH/1.0 header, after which point the server starts using the socket as a client, and the client starts using the socket as a server. There is also a COMET-style protocol which will work with HTTP/0.9 or 1.1 clients that do not know how to perform this upgrade.

Below is an example transcript using Reverse HTTP. Lines on the left are traffic from the client to the server. Lines on the right are traffic from the server to client. Lines with a red background are HTTP requests. Lines with a green background are HTTP responses.

The transcript was created by sniffing the traffic from running this script [1].

POST / HTTP/1.1
Host: localhost:9999
Accept-Encoding: identity
Upgrade: PTTH/0.9
HTTP/1.1 101 Switching Protocols
Content-type: text/plain
Upgrade: PTTH/0.9
Date: Tue, 13 May 2008 20:14:45 GMT
Content-Length: 0
GET / HTTP/1.1
Host: 127.0.0.1:65331
Accept-Encoding: identity
accept: text/plain;q=1,*/*;q=0
HTTP/1.1 200 OK
Content-type: text/plain
Date: Tue, 13 May 2008 20:14:45 GMT
Content-Length: 15
rdlrow ,olleH

COMET Fallback

If the client or server is incapable of upgrading from HTTP, a COMET-style protocol can be used instead. The server can maintain an event queue and require that the client repeatedly POST to the queue's resource to receive events. Below is a protocol trace using JSON as the protocol encoding.

POST / HTTP/1.1
Host: localhost:9999
Accept-Encoding: identity
HTTP/1.1 200 OK
Content-type: application/json
Date: Tue, 13 May 2008 20:14:45 GMT
Content-Length: 210
{'message-id': 'xxx', 'method': 'GET', 'request-uri': '/', 'http-version': 'PTTH/0.9', 'headers': [['Host', '127.0.0.1:65331'], ['Accept-Encoding', 'identity'], ['Accept','text/plain;q=1,*/*;q=0']], 'body': }
POST / HTTP/1.1
Host: localhost:9999
Accept-Encoding: identity
Content-type: application/json
Content-length: 193
{'message-id': 'xxx', 'http-version': 'PTTH/0.9', 'status': 200, 'reason': 'OK', 'headers': [['Content-type', 'text/plain'], ['Date', 'Tue, 13 May 2008 20:14:45 GMT']], 'body': 'rdlrow ,olleH'}
HTTP/1.1 200 OK
Content-type: application/json
Date: Tue, 13 May 2008 20:14:45 GMT
Content-Length: 2
{}

A response of {} from the server means no server-side event occurred within some timeout, and that the client should poll again if it wants to keep receiving events.

Another idea is to use text/plain encoding instead of JSON, and just have the actual text of the HTTP request in the response, and the text of the response in the next request. In this case, the message-id would be relayed in a header instead of in the body. Perhaps the message id should always be relayed in a header and never in the body?