Search code examples
httphttpsnettyhttp2

What the half close does in http2? What the diff between local and remote in stream state in http2?


What the half close does in http2? What the diff between local and remote in stream state in http2?

I have seen that: reserved(local) --> half closed(remote) in the lifecycle of a stream.

Why local to remote? why not reserved(local) --> half closed(local)?


Solution

  • Each stream will have two different view points - the client and the server, the requester and the provider. Call it what you want.

    So the "reserved" state is used when a PUSH_PROMISE has been sent. At this point the server has stated it intends to push a resource on another stream, so that stream identifier is reserved and cannot be used for anything but this pushed resource.

    At this point the server sees it as follows:

    • It will be a server-initiated stream so will be an even numbered stream.
    • The server has reserved the stream id itself - it was not reserved by the remote client. Hence reserved (local)
    • It will then send the HEADERS frame response. At this point the server has started sending the resource so when this happens HTTP/2 basically says the stream is closed from the client point of view - it's to listen to incoming data, but not to send any data (other than control signals like WINDOWS_UPDATE, PRIORITY or RST_STREAM frames). The stream is effectively now one-way or half-closed and it is closed to the remote client sending any data, but the local server is still allowed to send data - hence half closed (remote)

    The client will see the exact same flow from the opposite point of view:

    • It knows from the PUSH_PROMISE that a stream has been reserved and it should expect it to come in soon.
    • As the stream is a server-initiated stream it's not one the client created so it's treated as a remotely reserved stream - hence reserved (remote)
    • After the server starts sending the data, the client knows it's not allowed to send any data on that stream (not that it really was for Push Promise streams but still). It can re-prioritize the pushed resource (using a PRIORITY frame) or even cancel it (using RST_STREAM frame) but that's all it can do (other than acknowledge receipt of data using the WINDOWS_UPDATE frame). The stream is therefore restricted as to what the client can send on it - or as the spec prefers to say it is half-closed for any client (aka local) requests - hence half-closed (local).

    The key to understanding the HTTP/2 state model is to realise that a request does not flow down one side or the other - but down both sides at the same time! It just depends whether you are looking at it from the sender or receiver point of view.