Disallow request from server, and response from client respectively.
When the violation is detected, return NGHTTP2_ERR_PROTO from
nghttp2_submit_request, nghttp2_submit_response,
nghttp2_submit_headers.
We also did some refactoring, and now self-dependency detection is
placed where it is only required.
Previously, we use session->next_stream_id to detect that given stream
ID was idle or not. But this was suboptimal, since it was updated
when stream ID was assigned, and it did not necessarily mean that it
actually has been sent to the peer. Now we introduced
session->sent_stream_id, which only updated when HEADERS/PUSH_PROMISE
has sent. Using sent_stream_id instead of next_stream_id tightens
idle stream detection, and misbehaved peer which sends frame with
stream ID that has not been generated.
This commit also overhauls test code which involves opening streams.
Now we have some wrapper functions for nghttp2_session_open_stream()
which also take care of updating next_stream_id and
last_recv_stream_id. They are crucial for some tests.
Return NGHTTP2_ERR_INVALID_ARGUMENT from nghttp2_submit_headers() if
given stream ID and pri_spec->stream_id are the same (thus trying to
depend on itself).
Also return NGHTTP2_ERR_INVALID_ARGUMENT from nghttp2_submit_request()
and nghttp2_submit_headers() with stream_id == 1, when new stream ID
equals to pri_spec->stream_id.
Previously, these cases are not checked, and just sent to peer.
With the presence of idle stream related API (e.g.,
nghttp2_create_idle_stream()), it is more predictable for client to
create idle streams with its dependency to another idle stream.
Previously, we didn't create complete parent idle stream in this case.
Now we create idle streams as we do on server side.
Previously we scheduled the transmission of response HEADERS using
priority tree in the belief that it allows more better utilization of
bandwidth for prioritized streams. But to reduce the overhead of
reconstruction of priority queue when connection level flow control
window is depleted, we just don't check priority tree in this case.
This means that response HEADERS frames are not sent even though they
are not flow controlled. This could waste bandwidth. To improve this
situation, we stop scheduling response HEADERS with priority tree for
now. Now they are just sent in the order they submitted. The
response body DATA continued to be scheduled with priority tree as
before.
return session_inflate_handle_invalid_stream(...) case is for streams
for INITIAL state, but this is rare case. In general, we'd like to
reduce RST_STREAM transmission, and it is suffice to ignore this frame
for now.
Previously, we only updated stream's weight field when only weight was
changed by PRIORITY frame. If stream is queued, it would be better to
actually reschedule it based on new weight. This could be especially
useful if weight is increased.
Previously, we updated descendant_last_cycle in
nghttp2_stream_reschedule, which is called after non-zero DATA frame.
But this was not optimal since we still had old descendant_last_cycle,
and new stream was scheduled based on it. Now descendant_last_cycle
is updated in nghttp2_stream_next_outbound_item, which is called when
stream with highest priority is selected from queue. And new stream
is scheduled based on it. This commit also removes 0-reset of
descendant_last_cycle and cycle in nghttp2_stream_reschedule. This
could help making them lower, so that they are not overflow. But
there is a pattern that it doesn't work, and we are not sure they are
really useful at this moment.