It turns out that the cause of complication in backend request line
construction is a absolute-form in HTTP/1 request. In HTTP/2, we have
separated pseudo-header fields and no problem at all. In this commit,
we parse request URI in HTTP/1 frontend and extract values from it to
make backend logic simpler. This patch removes host header field
emission in HTTP/2 backend if :authority is emitted. It also rewrites
host header field with authority part in absolute-form URI as per RFC
7230.
Currently, we use same number of HTTP/2 sessions per worker with given
backend addresses. New option to specify the number of HTTP/2 session
per worker will follow.
It seems that we don't care about this since we don't change buffer
pointer between would-block write/read and next write/read. Somehow
we decided we need these fields. As a precaution, we set
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER in SSL_set_mode() for both server
and client contexts.
It turns out that writing successfully to network is not enough.
After apparently successful network write, read fails and then we
first know network has been lost (at least my android mobile network).
In this change, we say connection check is successful only when
successful read. We already send PING in this case, so we just wait
PING ACK with short timeout. If timeout has expired, drop connection.
Since waiting for PING ACK could degrade performance for fast reliably
connected network, we decided to disable connection check by default.
Use --backend-http2-connection-check to enable it.
nghttp2_submit_request and nghttp2_submit_response will set
NGHTTP2_FLAG_END_STREAM after all given data is sent (data could be
0). This means we have no way to send trailers. In this commit, we
added NGHTTP2_DATA_FLAG_NO_END_STREAM flag. The application can set
this flag in *data_flags inside nghttp2_data_source_read_callback. If
NGHTTP2_DATA_FLAG_EOF is set, library automatically set
NGHTTP2_FLAG_END_STREAM. But if both NGHTTP2_DATA_FLAG_EOF and
NGHTTP2_DATA_FLAG_NO_END_STREAM are set, NGHTTP2_FLAG_END_STREAM will
not set by library. Then application can use new
nghttp2_submit_trailer() to send trailers. nghttp2_submit_trailer()
will set NGHTTP2_FLAG_END_STREAM and it is actually thing wrapper of
nghttp2_submit_headers().
After we sent SETTINGS including ENABLE_PUSH = 0, peer may already
issue PUSH_PROMISE before receiving our SETTINGS and react it to
SETTINGS ACK. Previously we accept this PUSH_PROMISE. In this
commit, we check the pending ENABLE_PUSH value and if it means
disabling push, we refuse PUSH_PROMISE with RST_STREAM of error
REFUSED_STREAM.