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.
Previously, stream object for pushed resource was not created during
nghttp2_submit_push_promise(). It was created just before
nghttp2_before_frame_send_callback was called for that PUSH_PROMISE
frame. This means that application could not call
nghttp2_submit_response for the pushed resource before
nghttp2_before_frame_send_callback was called. This could be solved
by callback chaining, but for web server with back pressure from
backend stream, it is a bit unnecessarily hard to use.
This commit changes nghttp2_submit_push_promise() behaviour so that
stream object is created during that call. It makes application call
nghttp2_submit_response right after successful
nghttp2_submit_push_promise call.
Previously, nghttp2_session_end_request_headers_received assumes
stream is still writable (in other words, local endpoint has not sent
END_STREAM). But this assumption is false, because application can
send response in nghttp2_on_begin_frame_callback. Probably, this
assumption was made before the callback was introduced. This commit
addresses this issue. Since all
nghttp2_session_end_*_headers_received functions are identical, we
refactored them into one function.
Because of the nature of heap based priority queue, and our compare
function, streams with the same weight and same parent are handled in
the reverse order they pushed to the queue. To allow stream pushed
earlier to be served first, secondary key "seq" is introduced to break
a tie. "seq" is monotonically increased integer per parent stream,
and it is assigned to stream when it is pused to the queue, and gets
incremented.
Previously, nghttp2_session_find_stream(session, 0) returned NULL
despite the fact that documentation said that it should return root
stream. Now it is corrected, and it returns root stream as
documented.
The added API is nghttp2_session_change_stream_priority(). This
provides the same functionality to re-prioritize stream when PRIORITY
frame. is received, but we do it without PRIORITY frame. This could
be useful for server to change pushed stream's priority silently.