background

After a service goes online using HTTP/2, an interface fails to be accessed using curl.

The developer suspected that the operation’s HTTP/2 configuration might have caused the access failure, but other domain names that were also configured for HTTP/2 were fine, so he took a look at the problem.

screening

Step 1: capture packets without any prior information to see what has been transmitted. Wireshark is used to capture HTTPS packets because HTTP/2 requires HTTPS packets. As for doing this, I have talked about it in the previous B station share, if you are interested, you can have a look. Address here: Wireshark capture HTTPS traffic N method “www.bilibili.com/video/BV1ur…”

Grab HTTPS packets

To help Wireshark decrypt data, export premaster-secret. The wireshark SSL keylog format can be found at github.com/boundary/wi…

You can print the key to the curl file: github.com/curl/ lib/ VTLS /keylog.c

To curl, you only need to specify an environment variable to decrypt the extracted package.

export SSLKEYLOGFILE=/Users/arthur/keylog.txt
Copy the code

The result is as follows.

It looks like an HTTP2 server issue sent an error packet that caused the client to return the RST frame.

Let’s move on to what the HTTP/2 server replies. Through checking the package, as expected found some interesting.

There is a space after the Expires header, and no other header. After checking with the business, it was confirmed that this was the case. There was a space after expires, and the access was immediately normal after it was removed.

Curl was legal in the HTTP/1.1 era and there was no problem. In HTTP/2, there was a problem.

Of course, that still doesn’t directly prove the cause, unless Curl tells me himself.

Further analysis

Why is there a problem with Spaces? Curl: HTTP/2 curl: HTTP/2 Curl: HTTP/2 Curl: HTTP/2 Curl: HTTP/2 Curl: HTTP/2 Curl: HTTP/2 Curl

Use NGHTTP to visit and confirm our idea.

To explore the source

NGHTTP is an open source project that can clone source code to compile local debugging, and find that it will determine whether the header is valid when processing

Legal and illegal ASCII characters are defined here

The ASCII code value is: 32 (0x20). The corresponding value VALID is 0, indicating that the space is an invalid header character.

This is confirmed through GDB synchronization

Curl doesn’t handle headers with Spaces. Chrome and Safari have similar problems with curl.