Project

General

Profile

Bug #12946

net-http is breaking valid http headers like HTTP2-Settings

Added by chucke (Tiago Cardoso) almost 3 years ago. Updated almost 3 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:78159]

Description

The Net::HTTPHeader can't process the HTTP2-Settings header, which is a valid header destined to pass base64-encoded settings to a soon-to-be-upgraded-to-http2 connection.

req=Net::HTTP::Get.new
req["Upgrade"] = "h2c"
req["HTTP2-Settings] = "base64encoded=="

req.to_hash #=> "... Http2-Settings => ..."

Although one could say that net-http doesn't support to-http2-upgraded connections and even doesn't provide access to the raw socket, it's still a valid HTTP1.1 header, and the headers current MO "force to downcase and store; capitalize on fetch" works against custom Upgrade headers.

As of now, net-http can't upgrade. I'd suggest an API for such things, in that after a successful Upgrade request (101 switch protocols), the http connection "gives up" the socket to something else.

I had to monkey-patch my way out of this to make my code work: https://github.com/TiagoCardoso1983/jaguar/blob/master/test/test_helper.rb#L16-L25 .

History

Updated by phluid61 (Matthew Kerwin) almost 3 years ago

Tiago Cardoso wrote:

The Net::HTTPHeader can't process the HTTP2-Settings header, which is a valid header destined to pass base64-encoded settings to a soon-to-be-upgraded-to-http2 connection.

Aren't HTTP header names case-insensitive? What specifically breaks because the string is "Http2-Settings"?

Updated by chucke (Tiago Cardoso) almost 3 years ago

It breaks because it sends the wrong-cased http header over the wire. From plaintext upgrade-to-http2:

https://hpbn.co/http2/#upgrading-to-http2

If you tcpdump the sent payload from a net-http client, it is sending "Http2-Settings". HTTP2 servers will reject that.

Updated by phluid61 (Matthew Kerwin) almost 3 years ago

Tiago Cardoso wrote:

It breaks because it sends the wrong-cased http header over the wire. From plaintext upgrade-to-http2:

https://hpbn.co/http2/#upgrading-to-http2

If you tcpdump the sent payload from a net-http client, it is sending "Http2-Settings". HTTP2 servers will reject that.

No they won't. From RFC 7231 (i.e. HTTP/1.1):

Each header field consists of a case-insensitive field name followed
by a colon (":"), optional leading whitespace, the field value, and
optional trailing whitespace.

In HTTP/1.1 header field names are case-insensitive.

(In HTTP/2 they must be lower-case: https://tools.ietf.org/html/rfc7540#section-8.1.2 ; but that only applies after the upgrade dance has completed and you're encoding into HEADERS frames using HPACK.)

Updated by chucke (Tiago Cardoso) almost 3 years ago

You are right. I just tried with http://nghttp2.org, which supports upgrade-to-http2 http1 requests, and it worked well also with "Http2-Settings". I guess we can close this.

Updated by duerst (Martin Dürst) almost 3 years ago

  • Status changed from Open to Closed

Tiago Cardoso wrote:

I guess we can close this.

Done.

Also available in: Atom PDF