In May 2021, PTS has launched HTTP2 protocol support (the bottom layer depends on httpClient5). During the test, the client will decide whether to use HTTP1.1 or HTTP2 protocol through negotiation with the server.

Akik The wind rises

PTS**[1]** is available in May 2021 with support for HTTP2 (underlying dependency on HttpClient5). The HTTP1.1 or HTTP2 protocol is determined by negotiation with the server during pressure testing.

background

The reason for this article is that a customer came to us the other day and asked if we didn’t support HTTP2 because he bought 2 domains on XX cloud, one of which enabled HTTP2, and during the PTS pressure test, the interface that supported HTTP2 kept reporting an error:

At first suspected is HTTP2 support problem, through the local force to use HTTP2 protocol, visit Taobao home page, found is no problem, suspected is the user on XX cloud configuration problem, But then I realized that it was probably a PTS engine problem when I was able to access the page when I was forced to use HTTP1.1 by local Postman, curl, and the pressure engine.

According to local debug, an exception is found because the size of the client window is larger than 2^ 32-1 when the URL is requested.

It’s a good time to see what the window size is here.

HTTP2 flow control

HTTP1.1 relies on the transport layer TCP sliding window to implement Flow Control, so why HTTP2 should implement a Flow Control in the application layer? The reason for this is that HTTP2 introduces streaming and multiplexing, which allows multiple streams to work together through flow control.

Some basic concepts of flow control:

  1. Flow control is for connections, not end-to-end, but for each hop at both ends; In the case of an agent, flow control exists between the agent and both ends
  2. Flow control is based on WINDOW_UPDATE frames and the receiver can control the speed of the sender through flow control
  3. Flow control can be applied to both streams and Connections
  4. The default flow window size is 65535 for connections and all newly opened streams, and the maximum is 2^ 32-1
  5. Flow control cannot be disabled

To make it easier to understand, let’s list the types of HTTP2 frames:

  • DATA: Carries the DATA in the request or response
  • HEADERS: Used to create a new stream (request or response) containing the corresponding HEADERS
  • PRIORITY: Used to configure the PRIORITY of the flow
  • RST_STREAM: force the end of a stream. It is only used to cancel a stream on one end, not the end of a normal stream
  • SETTINGS: H2 Configures some configurations for the connection
  • PUSH_PROMISE: the server pushes a response to the client
  • PING: sends a PING to the remote end. The remote end must return the PING
  • GOAWAY: Used when one end is about to end a connection
  • WINDOW_UPDATE: Updates the flow control window size
  • CONTINUATION: If headers is too large to carry in a single headers frame, send additional headers through that frame

Next, we focus on the flow control related frames, mainly SETTING and WINDOW_UPDATE. When the connection is established, the window size of the other party will be adjusted through the SETTINGS frame. Later, during transmission, the window size will gradually decrease as the data is sent. Until you receive a WINDOW_UPDATE frame that updates the window size. The SETTINGS frame contains the following:

  • SETTINGS_HEADER_TABLE_SIZE: HPACK (a header compression algorithm) The maximum length of the header table. Default value 4096
  • SETTINGS_ENABLE_PUSH: indicates the configuration for the client to send to the server. If this parameter is set to true, the client will allow the server to push the response. The default value is true
  • SETTINGS_MAX_CONCURRENT_STREAMS: The maximum number of streams open at the same time. This usually means the number of requests that can be responded to at the same time. By default, it is unlimited
  • SETTINGS_INITIAL_WINDOW_SIZE: The initial window size of the flow control. The default value is 65535
  • SETTINGS_MAX_FRAME_SIZE: Maximum length of frames accepted by the peer. The default value is 16384
  • SETTINGS_MAX_HEADER_LIST_SIZE: Specifies the maximum header list length that the peer end can accept. The default value is unlimited

Flow control is implemented as described above, with each batch of DATA frames sent, the window size is reduced. Note that flow control only applies to DATA frames.

We mentioned that flow control can work on both streams and connections. How does this work? Connection flow control is similar to the above stream flow control logic. Each time a DATA frame is sent, the Connection and stream Windows are reduced. However, WINDOW_UPDATE either works on the stream alone, Or on connection alone (when StreAMID is 0, it means on Connection).

Problem orientation

So back to the problem at the beginning, we take URL www.sysgeek.cn/ as an example. Through local code debug, we found that the final throw exception was caused by the window size larger than 2^ 32-1 after receiving WINDOW_UPDATE frame:

Delta = 524288; delta = 524288; delta = 524288; delta = 65535

RFC 7540 **[2]** (Connection window size can only be changed after receiving WINDOW_UPDATE)

Therefore, we conclude that the httpCore5 source code is buggy, and after removing the marked line of code, the request will execute normally.

Unfortunately, this bug was fixed in the COMMIT while preparing to give PR to HttpCore5.

The resources

[1] PTS:

Help.aliyun.com/document\_d…

[2] the RFC 7540:

Datatracker.ietf.org/doc/html/rf…

The original link

This article is the original content of Aliyun and shall not be reproduced without permission.