Skip to content

Instantly share code, notes, and snippets.

@markjlorenz
Last active August 29, 2015 14:02
Show Gist options
  • Save markjlorenz/cfb5d0e15ddc5dee08fa to your computer and use it in GitHub Desktop.
Save markjlorenz/cfb5d0e15ddc5dee08fa to your computer and use it in GitHub Desktop.
Sending two HTTP responses to one request

Sending Two HTTP Responses to One Request

The Several Million Dollar Bug by Jacques Mattheij claims that while HTTP is designed to be synchronous, it is actually possible to send the response before the request has been made. I wanted to try that out. Here's a proof of concept in ruby:

#! /usr/bin/env ruby

require "socket"

server = TCPServer.new 3999
client = server.accept

client.puts <<-HEREDOC
HTTP/1.1 200 OK
Content-Length: 7

HI YOU
HEREDOC

client.puts <<-HEREDOC
HTTP/1.1 200 OK
Content-Length: 11

HI YOU TWO
HEREDOC

client.close

Then I point the browser at http://localhost:3999, and the result is dissapointing:

I am dissapoint

It looks like chrome totally ignored the second request. What am I doing wrong?

@skpy
Copy link

skpy commented Jun 11, 2014

curl's output may be illuminating?

* Adding handle: conn: 0x7fada9803a00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fada9803a00) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 3999 (#0)
*   Trying ::1...
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3999 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:3999
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 7
<
* Excess found in a non pipelined read: excess = 47, size = 7, maxdownload = 7, bytecount = 0
HI YOU
* Connection #0 to host localhost left intact

@skpy
Copy link

skpy commented Jun 11, 2014

$ curl -v --ignore-content-length localhost:3999
* Adding handle: conn: 0x7fb6ea803a00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fb6ea803a00) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 3999 (#0)
*   Trying ::1...
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3999 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:3999
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 7
* no chunk, no close, no size. Assume close to signal end
<
HI YOU
HTTP/1.1 200 OK
Content-Length: 11

HI YOU TWO
* Closing connection 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment