Subject: Re: HTTP/2.0 Magic

From: "Roy T. Fielding" <[email-masked]>
Date: Fri, 1 Feb 2013 00:38:04 -0800

On Jan 31, 2013, at 11:34 PM, James M Snell wrote:

> +1 ... sending a simple "HTTP20<CRLF>" seems it would be sufficiently effective. The 20 is the major and minor version. The preamble for http/2.1 would be "HTTP21<CRLF>"

I suggest "spdy" is a more interesting prefix, and less likely to
be misinterpreted by parsers looking for "HTTP/1.1".  I am not sure
that having a minor version is useful in a binary protocol.

....Roy

---

From: "Roy T. Fielding" <[email-masked]>
Date: Fri, 1 Feb 2013 01:29:51 -0800

On Jan 31, 2013, at 11:46 PM, David Morris wrote:
> It seems to me that including CRLF is more likely to result in the string
> being ignored then if it is an unterminated sequence which would get
> catenated with the payload by a parser which didn't know about it.

The goal is to have a fast response, and most decently written
text-based protocol servers won't process the input (and see
that it is invalid) until a line is received, a timeout occurs,
or the receive buffer is full.  That is doubly so when the kernel
is asked to do line buffering before accept.

I think it is fair to say we could continue bike-shedding this
for a long time and end up with a fair number of polarized yet
irrelevant designs.  I suggest folks just code it up and see
which ideas break the best on the most networks.

....Roy

---

From: Amos Jeffries <[email-masked]>
Date: Fri, 01 Feb 2013 23:07:25 +1300

On 1/02/2013 2:24 p.m., Martin Thomson wrote:
> The conclusion that we reached in the interim was that no matter how
> HTTP/2.0 was started, there would be some magic that started the
> session.

I have been working on this for a while now in the background. Lets just 
say that utilizing the first 16 bits of any connection it is possible to 
uniquely identify HTTP/1, SPDY v2 and SPDY v3 and WebSockets clients. I 
am still investigating the TLS, SSH and SNI bit patterns to see whether 
we can fold port 443 and port 80 together for HTTP/2-enabled servers.

Magic will not be a big issue and we can avoid worrying about generating 
some BOM magic octets just yet. The SPDY style of versioning still being 
used in the HTTP/2 Draft document provides sufficient binary variation 
to detect sub-versions as things progress and to become the magic octet 
if future framing versions require one.

Amos

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 19 Feb 2013 16:21:01 +1100

[ Now: https://github.com/http2/http2-spec/issues/25 ]

On 01/02/2013, at 6:17 PM, Roy T. Fielding <[email-masked]> wrote:

> Umm, sending high bit characters is far more likely to be ignored
> or trigger parsing bugs than simple ascii.
> 
> The best way to a quick and safe end (actually tested in
> practice 10 years ago) is to send something that looks like a method
> and ends with CRLF.  Hence, waka sends a 64bit value
> 
>   wakaVV<CRLF>
> 
> where the first V is the version being sent and the second V is the
> highest version accepted.  Both are a variant of base64 that starts
> at 0, so the beginning of each message is
> 
>  77 61 6b 61 30 30 0d 0a

I like the general approach. A few questions:

* Should it end with CRLFCRLF? Seems to me this _might_ fast fail on a few more implementations.

* Is the magic identifying the underlying framing layer in use (what we're now calling HTTP/2, but I suspect we might want to start calling it something else), the profile in use over it, or both? My sense is that both is perhaps best.

* Is the magic sent by a client upon connect, by a server upon connect, or both?

Cheers,

--
Mark Nottingham   http://www.mnot.net/

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 19 Feb 2013 07:21:00 +0100

> * Should it end with CRLFCRLF? Seems to me this _might_ fast fail on a few

Indeed it should. For example I have an old crappy test server which waits
for the empty line whatever the request line looks like. Similarly, mini_httpd
did this (and I've seen it used in several embedded devices).

However, I remember that when the same approach was proposed on hybi, one
of the concerns that was raised was that some servers will happily return
a valid response and may corrupt intermediary caches. I remember that about
all intermediary implementations authors explained that no cache will ignore
the method in the request, but still that was a concern that plagued the
design.

> * Is the magic identifying the underlying framing layer in use (what we're
> now calling HTTP/2, but I suspect we might want to start calling it something
> else), the profile in use over it, or both? My sense is that both is perhaps
> best.

I personally don't understand what it's about :-/

> * Is the magic sent by a client upon connect, by a server upon connect, or both?

We should absolutely not have a "banner protocol". It causes two major pains :
  - adds a round trip
  - is not SYN cookies-friendly, making it much harder to protect many
    web sites

So the client must speak first. If we decide that it's desirable that
the server responds, we must use a different pattern to avoid false
positives on echo servers or those which would return a message such
as "FOO CRLF unknown method".

Just my two cents.
Willy

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 19 Feb 2013 17:24:02 +1100

> the method in the request, but still that was a concern that plagued the

I'm not convinced it's a concern.

> We should absolutely not have a "banner protocol".

Definitely not; question is whether the server prepends something to the start of the framing layer.

> as "FOO CRLF unknown method".

Yes.

Cheers,

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 19 Feb 2013 07:57:56 +0100

> I'm not convinced it's a concern.

I'm convinced it's not. But I mentionned this so that we get prepared
to see such comments come back again.

> start of the framing layer.

I'm only seeing two valid reasons for prepending something :
  1) if the frame encoding is compact enough to use all bits and make
     an HTTP/1 response look like a possibly valid frame which the
     client must parse, we'd prefer to avoid this useless work ;
  2) if the frame can be tailored to look like an HTTP/1 response,
     we'd prefer to avoid the possibility that this is triggered from
     the client.

So maybe something looking like an HTTP/1 error may be useful then
(eg: "HTTP/1.0 505 V2ONLY CRLF CRLF").

Willy

---

From: Martin Thomson <[email-masked]>
Date: Tue, 19 Feb 2013 12:02:11 -0800

We almost certainly don't need to indicate the protocol version in this magic.

>      we'd prefer to avoid the possibility that this is triggered from

I think that an 8 byte frame header is small enough that it is
conceivable that it would be ignored, leading to the possibility that
the frame *body* could be made to look like an HTTP/1.x something.

> (eg: "HTTP/1.0 505 V2ONLY CRLF CRLF").

What we have suggest to me that it be *like* an HTTP/1.x response, but
be clearly NOT valid.  Making the response a valid HTTP/1.1 header is
only more likely to be passed as valid.  The goal is to die horribly
in as many clients and intermediaries as possible.

So, in the interest of concreteness, and in the spirit of Roy's suggestions:
  client-magic = %x73.6c.6f.77 CRLF CRLF
  server-magic = %x53.50.44.59 CRLF CRLF

Making sure to enforce case-sensitivity.  Then require either peer to
sever the connection if it sees anything else.

Note that this is followed immediately by a settings frame, which is
at least another 8 bytes.

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 17:12:56 +1100

So, I decided to explore this a bit more. 

I have a list of about 760,000 IP addresses running Web servers, so I put together a quick script to see how they reacted to various magic strings.

For the source, see:
  https://github.com/http2/http2-probe

Below are my notes from some preliminary experimentation today.

Just sending FOO\n\n to ~760,000 servers gives:

FOO\n\n
 641481 CLOSE
  85855 CONN_ERR
  35148 TIMEOUT

"CLOSE" means that the server closed the connection; "CONN_ERR" was various connection errors, 
and "TIMEOUT" means it hangs (5 seconds, in this case).

Let's try adding \r before the \n (all of the following runs are on the TIMEOUTs above).

FOO\r\n\r\n
   1602 CLOSE
    303 CONN_ERR
  33243 TIMEOUT

A bit of help. What if we give it HTTP syntax?

FOO * HTTP/2.0\r\n\r\n
  30082 CLOSE
    396 CONN_ERR
   4670 TIMEOUT

Much better. What if we add Connection: close?

FOO * HTTP/2.0\r\nConnection: close\r\n\r\n
  30310 CLOSE
    337 CONN_ERR
   4501 TIMEOUT

Not significantly better. What if we do Content-Length: 0 instead?

FOO * HTTP/2.0\r\nContent-Length: 0\r\n\r\n
  30072 CLOSE
    369 CONN_ERR
   4707 TIMEOUT

Not helping. What if we add a second "request"?
  
FOO * HTTP/2.0\r\n\r\nBAR * HTTP/2.0\r\n\r\n
  31212 CLOSE
    306 CONN_ERR
   3630 TIMEOUT

Significantly better. Can we save the \r?

FOO * HTTP/2.0\n\nBAR * HTTP/2.0\n\n
  27101 CLOSE
    312 CONN_ERR
   7735 TIMEOUT

Ouch. Does it need the full second request, or just some bits?

FOO * HTTP/2.0\r\n\r\nBAR\r\n\r\n
  31132 CLOSE
    427 CONN_ERR
   3589 TIMEOUT
   
Not bad; our best candidate. About 175 out of the 3589 remaining TIMEOUTs on the do send some text (most often, a HTTP status code), but that's not the majority; most of them well and truly hang.

The distribution of latency on CLOSE (factoring out the round trip) is very heavy towards 0; see  the list at the end (some are negative because of jitter; connect time is used to estimate latency). Note the bumps at 1 and 3 seconds; I suspect these are timeouts in some load balancer or other middlebox, because their Server headers are pretty diverse.

Just to see, what if we truncate the first one too?

FOO\r\n\r\nBAR\r\n\r\n
   1042 CLOSE
     86 CONN_ERR
  11766 TIMEOUT
  
Nope (stopped run when this became obvious). What about some binary?

\xff * HTTP/2.0\r\n\r\n\xff\r\n\r\n
  30271 CLOSE
    342 CONN_ERR
   4535 TIMEOUT
   
Huh. Not as good as text. 

Distribution of CLOSE latency on best candidate:

   4135 -0.00
   6664 0.00
   3579 -0.01
   4243 0.01
   1998 -0.02
   1600 0.02
   1399 -0.03
    664 0.03
    867 -0.04
    445 0.04
    541 -0.05
    398 0.05
    469 -0.06
    322 0.06
    342 -0.07
    280 0.07
    306 -0.08
    175 0.08
    285 -0.09
    178 0.09
    237 -0.10
    227 0.10
    154 -0.11
     80 0.11
    106 -0.12
     42 0.12
     30 -0.13
     39 0.13
     16 -0.14
     38 0.14
      1 -0.15
     37 0.15
      3 -0.16
     44 0.16
      2 -0.17
     37 0.17
     22 0.18
      1 -0.19
     27 0.19
      1 -0.20
     26 0.20
      1 -0.21
     24 0.21
     15 0.22
     16 0.23
      1 -0.24
     30 0.24
      8 0.25
      1 -0.26
     15 0.26
     18 0.27
     11 0.28
      1 -0.29
     10 0.29
      5 0.30
      3 0.31
      1 -0.32
      5 0.32
      2 0.33
      1 0.34
      2 0.35
      6 0.36
      4 0.37
      3 0.38
      4 0.39
      2 -0.40
      5 0.40
      8 0.41
      3 0.42
      1 -0.43
      2 0.43
      4 0.44
      1 -0.45
      3 0.45
      4 0.46
      3 0.47
      1 -0.48
      4 0.48
      9 0.49
      3 0.50
      3 0.51
      3 0.52
      3 0.53
      2 0.54
      1 0.55
      1 0.56
      1 -0.58
      2 0.58
      3 -0.59
      2 0.59
      2 0.60
      3 0.61
      4 0.62
      7 0.63
      1 0.64
      2 -0.65
      1 0.65
      2 0.66
      3 0.68
      2 0.69
      1 -0.70
      2 0.70
      3 0.71
      2 0.72
      2 0.73
      1 0.74
      1 -0.75
      1 0.75
      3 0.76
      2 0.77
      2 0.78
      4 0.79
      2 0.80
      6 0.81
      1 -0.82
      2 0.82
      1 -0.83
      1 0.83
      1 0.84
      2 0.85
      2 0.86
      3 0.88
      2 0.89
      3 0.90
      1 -0.91
      4 0.91
      1 0.92
      1 -0.93
      3 0.93
      2 -0.94
      2 0.94
      1 -0.95
      3 0.95
      2 -0.96
      1 0.96
      6 0.97
      1 -0.98
      1 0.98
      8 -0.99
      1 0.99
     81 -1.00
      6 1.00
      6 -1.01
      1 1.01
      8 -1.02
      2 1.02
      1 -1.03
      2 1.03
      3 1.04
      3 1.05
      2 1.06
      2 1.08
      1 1.09
      2 1.10
      5 1.11
      7 1.12
     30 1.13
      3 1.14
      9 1.15
      3 1.17
      3 1.18
      2 1.19
      9 1.20
      1 1.21
      4 1.23
      2 1.26
      5 1.27
      3 1.29
      2 1.31
      1 1.32
      1 1.37
      2 1.39
      1 1.40
      1 1.48
      1 1.49
      1 1.52
      1 1.55
      2 1.56
      1 1.58
      1 1.59
      2 1.60
      1 1.61
      2 1.62
      2 1.63
      1 1.64
      1 1.65
      1 1.67
      2 1.68
      2 1.71
      1 1.73
      1 1.75
      1 1.79
      1 1.81
      2 1.83
      1 1.85
      2 1.87
      1 1.88
      1 -1.97
      1 2.01
      1 2.02
      1 2.03
      1 2.06
      1 2.09
      1 2.12
      1 2.17
      1 2.19
      1 2.20
      1 2.21
      2 2.22
      2 2.24
      2 2.25
      1 2.29
      1 2.37
      2 2.40
      1 2.45
      1 2.46
      1 -2.47
      1 2.47
      2 2.48
      2 2.53
      2 -2.55
      1 2.56
      1 2.60
      1 2.62
      1 -2.67
      2 2.67
      1 2.69
      1 -2.70
      1 2.72
      1 2.81
      1 2.82
      1 -2.86
      1 2.87
      1 2.88
      1 -2.89
      2 -2.90
      1 -2.91
      1 -2.92
      1 2.93
      4 -2.94
     10 -2.95
      2 -2.96
      2 2.96
     11 -2.97
      8 -2.98
      2 2.98
     10 -2.99
      4 2.99
    127 -3.00
     70 -3.01
      1 -3.02
      1 -3.03
      1 3.03
      1 3.04
      1 -3.05
      1 3.06
      1 -3.14
      1 3.15
      1 3.16
      1 3.21
      1 -3.23
      1 3.23
      1 3.24
      1 -3.26
      1 3.32
      1 3.34
      2 3.39
      1 3.46
      1 3.50
      1 3.59
      1 3.81
      1 3.84
      1 -4.00
      1 4.09
      1 4.15
      1 4.34
      1 4.46
      1 4.48
      2 4.49
      1 4.50
      1 4.52
      1 4.53
      2 4.54
      1 4.56
      2 4.57
      3 4.59
      6 4.60
      1 4.61
      1 4.62
      1 4.63
      1 4.72
      2 4.75
      1 4.85
      1 4.91
      1 4.93
      4 4.97
      2 4.98
     14 4.99
     18 5.00
     10 5.01
      5 5.02
      2 5.03
      2 5.04
      2 5.05
      2 5.06
      2 5.07
      1 5.08
      2 5.10
      1 5.12
      1 5.13
      1 5.15
      3 5.18
      1 5.23
      2 5.24
      2 5.29
      1 5.35
      1 5.40
      1 5.43
      1 5.47
      1 5.48
      1 5.50
      1 5.51
      1 5.65
      1 5.79
      1 5.80
      1 5.91
      1 5.97
      1 6.00
      1 6.38
      1 6.43
      1 6.53

Cheers,

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 21 Feb 2013 08:06:15 +0100

Hi Mark,

On Thu, Feb 21, 2013 at 05:12:56PM +1100, Mark Nottingham wrote:
> Not bad; our best candidate. About 175 out of the 3589 remaining TIMEOUTs on
> the do send some text (most often, a HTTP status code), but that's not the
> majority; most of them well and truly hang.

(...)

That's a great test, thanks for reporting this !
I think that some experiments may be pursued using :
  - valid, known methods and versions (eg: POST * HTTP/1.1)
  - Connection header

I suspect that POST will be blocked on a large number of minimal web
servers (the least compliant ones), add to that "*" which will most
often not be accepted, and HTTP/1.1 without a Host header field might
help getting a quick fail. At this point, I don't know if a Connection
header could help or not (typically Upgrade).

Cheers,
Willy

---

From: Amos Jeffries <[email-masked]>
Date: Thu, 21 Feb 2013 20:15:15 +1300

> Huh. Not as good as text.

Couple of questions.
  How do the TIMEOUT failure sets compare to each other?
  are they all the same servers or do some respond badly to one form and 
CLOSE quickly on others?
  Is there any consistency in identifiable software doing TIMEOUT on any 
particular magic?

Amos

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 18:19:12 +1100

Don't know. I looked a little bit into isolating different servers, but from what I initially saw, many servers are all over the map; it seems to have more to do with configuration / handlers installed / middleboxes in front than just the server software.

On 21/02/2013, at 6:15 PM, Amos Jeffries <[email-masked]> wrote:

> are they all the same servers or do some respond badly to one form and CLOSE quickly on others?
> Is there any consistency in identifiable software doing TIMEOUT on any particular magic?
> 
> 
> Amos
>

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 18:21:02 +1100

> header could help or not (typically Upgrade).

Hm. POST has a body, so some might try to buffer it, hanging. Anyway, that's a theory; let's look at the numbers:

POST * HTTP/1.1\r\n\r\n
  27607 CLOSE
    232 CONN_ERR
   7309 TIMEOUT

Yep, not as good.

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 21 Feb 2013 08:29:17 +0100

> Hm. POST has a body, so some might try to buffer it, hanging. Anyway, that's a theory; let's look at the numbers:

Indeedr, thanks!

Do you know if the ones which timeout in your tests respond to
anything ? And if so, maybe we'll find some patterns (eg: just
a few very specific implementations) that are worth studying ?

It's also possible that those are blocked by IDS/IPS in front
of them simply dropping packets, at which point trying completely
valid requests might help.

Willy

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 18:35:04 +1100

> valid requests might help.

Here's the top 50 Server strings from the 3589 TIMEOUTs from the best one so far (the tail is *long*):

    587 Microsoft-IIS/6.0
    386 Apache
    379 -
    280 Microsoft-IIS/7.5
     56 Microsoft-HTTPAPI/2.0
     49 Microsoft-IIS/7.0
     46 Apache-Coyote/1.1
     44 Apache/2.2.3 (Red Hat)
     37 Apache/2.2.3 (CentOS)
     26 IBM_HTTP_Server
     19 Microsoft-IIS/5.0
     18 nginx
     17 BigIP
     16 Apache/2.2.16 (Debian)
     15 Apache/2.2.14 (Ubuntu)
     12 Sun-ONE-Web-Server/6.1
     12 Apache/2.0.52 (Red Hat)
     10 Mbedthis-Appweb/2.4.2
     10 LiteSpeed
      9 Lotus-Domino
      8 Netscape-Enterprise/6.0
      8 Apache/2.2.15 (Red Hat)
      8 Apache/1.3.31
      7 FlashCom/3.5.7
      7 Apache/2
      7 
      6 squid/3.0.STABLE20
      6 Servidor-Web
      6 Oracle-iPlanet-Web-Server/7.0
      6 nginx/0.7.67
      6 Microsoft-IIS/6.0, 2
      6 Apache/2.2.22 (Ubuntu)
      5 Netscape-Enterprise/4.1
      5 FileMakerPro/6.0v4 WebCompanion/6.0v3
      5 FileMakerPro/6.0v4 WebCompanion/6.0v1
      5 Apache/2.2.3 (Linux/SUSE)
      5 Apache/2.2.15 (CentOS)
      5 Apache/2.2.10 (Linux/SUSE)
      4 Zeus/4.3
      4 nginx/1.2.4
      4 Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/0.9.8e-fips-rhel5 Resin/3.1.6
      4 Apache/2.2.0 (Fedora)
      3 Zope/(Zope 2.10.13-final, python 2.4.6, linux2) ZServer/1.1 Plone/3.3.6
      3 none
      3 Apache/2.4.3 (Unix)
      3 Apache/2.2.3 (Unix) mod_jk/1.2.19 mod_ssl/2.2.3 OpenSSL/0.9.8d
      3 Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8a DAV/2 PHP/5.3.2
      3 Apache/2.2.20 (Ubuntu)
      3 Apache/2.2.17 (Fedora)
      3 Apache/2.2.12 (Linux/SUSE)

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 18:37:30 +1100

Oh, and of the 3589 attempts to get a Server header, fully 1099 got some sort of HTTP (or lower layer) error; haven't dug into that yet, though.

I did, however, see some SMTP servers listening on port 80 in earlier testing...

Cheers,

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 19:02:55 +1100

> FOO * HTTP/2.0\r\n\r\nBAR\r\n\r\n

That's 25 bytes, btw; shortening to 21:

A * HTTP/2.0\r\n\r\nB\r\n\r\n
  30520 CLOSE
    682 CONN_ERR
   3946 TIMEOUT

... makes it a bit worse.

Cheers,

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 21 Feb 2013 09:24:24 +0100

On Thu, Feb 21, 2013 at 06:37:30PM +1100, Mark Nottingham wrote:
> Oh, and of the 3589 attempts to get a Server header, fully 1099 got some sort
> of HTTP (or lower layer) error; haven't dug into that yet, though.

OK, so most likely IDS/IPS are making fun of your script, which also explains
why so many server strings are valid despite the timeouts (mostly Apache and
IIS).

> I did, however, see some SMTP servers listening on port 80 in earlier testing...

Interesting! We must be in the small percentage of the totally non-
compliant servers and intermediaries!

The problem I'm seeing is that if we craft too ugly a pattern, we can
hope for early failures on transparent intercepting devices, but we can
have some dirty servers timeout, and if we craft too valid a request, we
can have the intercepting devices hang because they're not aware of the
syntax, while end servers would happily reject them.

For instance, sending "HEAD /.upgrade HTTP/1.1" with the appropriate Host
should lead to various responses from 404 to 301, 302 etc on origin servers,
but nothing there allows an intermediary to upgrade. If we send the same
thing with a "Connection: upgrade", we'll have a number of of them comply
but not all. If we send "FOO\r\n", most intermediaries will block (or
rewrite as "FOO / HTTP/1.0\r\n\r\n") but origin servers have trouble with
this.

BTW, one thing I like with the Connection Upgrade is that the new protocol
is used over the longest path, which is where it is supposed to reduce
latency. If we try to terminate the protocol on the first intercepting
proxy, it is very likely that this proxy will be located at the end user's
ISP and will rewrite as HTTP/1.1 to access the whole world, removing most
of the new protocol's value. This is not bad in 3G, but 3G operators can
already do whatever they want.

And I think it is important that we focus on achieving the longest possible
path with 2.0 (ideally, 1.1 should only be between the server-side LBs and
the servers themselves).

Regards,
Willy

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 19:46:20 +1100

One more little experiment; the "first" request, followed by something that a settings frame might look like: 

FOO * HTTP/2.0\r\n\r\n\x80\x00\x00\x04\x80\x00\x00\x00
  31177 CLOSE
    298 CONN_ERR
   3673 TIMEOUT

Not too bad.

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 20:23:19 +1100

On 21/02/2013, at 7:24 PM, Willy Tarreau <[email-masked]> wrote:

> but nothing there allows an intermediary to upgrade.

Remember, this is just the magic, NOT the upgrade dance -- the only purpose is to cause a fast fail...

Cheers,

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 21 Feb 2013 10:42:04 +0100

> Remember, this is just the magic, NOT the upgrade dance -- the only purpose is to cause a fast fail...

I agree, but if we cause the first local intermediary to fast fail, this
defeats the purpose of the new improved protocol !

Willy

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 21 Feb 2013 10:57:29 +0100

> FOO * HTTP/2.0\r\n\r\n\x80\x00\x00\x04\x80\x00\x00\x00

Mark, it would be nice to first check how many timeouts we get
from these severs using perfectly valid requests, as I suspect
some of them randomly fail because they might be overloaded.

Willy

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 20:59:28 +1100

Yep, will try to get to that tomorrow; just wanted to start driving the discussion with data today.

Of course, the source is in github, so you can do that while I sleep, if you like :)

Cheers,

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 21 Feb 2013 11:13:18 +0100

> discussion with data today.

And this worked !

> Of course, the source is in github, so you can do that while I sleep,

I'm not sure everyone has your IP address list, that's why I was
suggesting :-)

Willy

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 21 Feb 2013 21:16:36 +1100

> I'm not sure everyone has your IP address list, that's why I was

Oh, the list is scraped from a Wikipedia dump (about two months old, alas). I'll figure out how to get it to others; it's just to big to put in github.

Cheers,

---

From: "Martin Nilsson" <[email-masked]>
Date: Thu, 21 Feb 2013 14:40:17 +0100

On Thu, 21 Feb 2013 07:12:56 +0100, Mark Nottingham <[email-masked]> wrote:

> I have a list of about 760,000 IP addresses running Web servers, so I  
> put together a quick script to see how they reacted to various magic  
> strings.
>
> For the source, see:

I did something similar yesterday using 35,000 unique domains accessed by  
mobile clients. Sending "slow\r\n\r\n" I got

     CLOSED : 3038 (8.7%)
   NON_HTTP : 20650 (59.3%)
     STATUS : 10092 (29.0%)
   SUCCESS? : 1061 (3.0%)

Where CLOSED us closing without sending any data, NON_HTTP is a response  
without HTTP headers, STATUS is a HTTP error response and SUCCESS? is a  
HTTP 200 response. I recorded the time for all the requests and got this  
for the requests that were closed without any data returned.

Close response times
  0 : 1740 57.3% 57.3%
  1 : 275 9.1% 66.3%
  2 :  28 0.9% 67.2%
  3 :  10 0.3% 67.6%
  4 :   2 0.1% 67.6%
  5 :  57 1.9% 69.5%
  6 :   6 0.2% 69.7%
  7 :   8 0.3% 70.0%
  8 :   6 0.2% 70.2%
  9 :   6 0.2% 70.4%
10 :  82 2.7% 73.1%
20 : 112 3.7% 76.8%
30 :  76 2.5% 79.3%
40 :  13 0.4% 79.7%
50 : 162 5.3% 85.0%
60 : 415 13.7% 98.7%
70 :   4 0.1% 98.8%
90 :  21 0.7% 99.5%
100 :  13 0.4% 99.9%
110 :   2 0.1% 100.0%

/Martin Nilsson

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/

---

From: David Morris <[email-masked]>
Date: Fri, 22 Feb 2013 15:56:21 -0800 (PST)

As I understand this series of tests, you did an initial probe of servers 
with FOO\r\n

And continued testing with only those servers which TIMEDout in the first
test. I think that it might be a risky conclusion that every unrecognized
probe would receive the same quick CLOSE response.

---

From: Scott Schmit <[email-masked]>
Date: Sat, 23 Feb 2013 14:40:20 -0500

> Below are my notes from some preliminary experimentation today.

<snip a lot of good stuff>

Every good experiment needs a control. I'd suggest:
* A valid HTTP/1.0 request
* A valid HTTP/1.1 request
* A valid HTTP/2.0 (as currently defined) request without magic

-- 
Scott Schmit

---

From: Mark Nottingham <[email-masked]>
Date: Sun, 24 Feb 2013 12:18:56 +1100

Yes. Once things settle down a bit, I'll re-check more final candidates against the full set of servers; I just didn't want to pepper 700,000+ servers with too many requests (because that starts to look like intrusion, which in turn can skew the results as well).

Cheers,

---

From: Mark Nottingham <[email-masked]>
Date: Sun, 24 Feb 2013 12:19:16 +1100

Getting there, Thanks (see subsequent discussion).

Cheers,