Simplify session_after_frame_sent1
This commit is contained in:
parent
9d4e8eeb12
commit
905e16cb99
|
@ -2483,196 +2483,11 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
||||||
nghttp2_outbound_item *item = aob->item;
|
nghttp2_outbound_item *item = aob->item;
|
||||||
nghttp2_bufs *framebufs = &aob->framebufs;
|
nghttp2_bufs *framebufs = &aob->framebufs;
|
||||||
nghttp2_frame *frame;
|
nghttp2_frame *frame;
|
||||||
|
nghttp2_stream *stream;
|
||||||
|
|
||||||
frame = &item->frame;
|
frame = &item->frame;
|
||||||
|
|
||||||
if (frame->hd.type != NGHTTP2_DATA) {
|
if (frame->hd.type == NGHTTP2_DATA) {
|
||||||
|
|
||||||
if (frame->hd.type == NGHTTP2_HEADERS ||
|
|
||||||
frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
|
||||||
|
|
||||||
if (nghttp2_bufs_next_present(framebufs)) {
|
|
||||||
DEBUGF(fprintf(stderr, "send: CONTINUATION exists, just return\n"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv = session_call_on_frame_send(session, frame);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
switch (frame->hd.type) {
|
|
||||||
case NGHTTP2_HEADERS: {
|
|
||||||
nghttp2_headers_aux_data *aux_data;
|
|
||||||
nghttp2_stream *stream;
|
|
||||||
|
|
||||||
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
|
||||||
if (!stream) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (frame->headers.cat) {
|
|
||||||
case NGHTTP2_HCAT_REQUEST: {
|
|
||||||
stream->state = NGHTTP2_STREAM_OPENING;
|
|
||||||
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
|
|
||||||
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
|
|
||||||
}
|
|
||||||
rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
|
|
||||||
aux_data = &item->aux_data.headers;
|
|
||||||
if (aux_data->data_prd.read_callback) {
|
|
||||||
/* nghttp2_submit_data() makes a copy of aux_data->data_prd */
|
|
||||||
rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
|
|
||||||
frame->hd.stream_id, &aux_data->data_prd);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
/* TODO nghttp2_submit_data() may fail if stream has already
|
|
||||||
DATA frame item. We might have to handle it here. */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NGHTTP2_HCAT_PUSH_RESPONSE:
|
|
||||||
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH);
|
|
||||||
++session->num_outgoing_streams;
|
|
||||||
/* Fall through */
|
|
||||||
case NGHTTP2_HCAT_RESPONSE:
|
|
||||||
stream->state = NGHTTP2_STREAM_OPENED;
|
|
||||||
/* Fall through */
|
|
||||||
case NGHTTP2_HCAT_HEADERS:
|
|
||||||
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
|
|
||||||
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
|
|
||||||
}
|
|
||||||
rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
|
|
||||||
aux_data = &item->aux_data.headers;
|
|
||||||
if (aux_data->data_prd.read_callback) {
|
|
||||||
rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
|
|
||||||
frame->hd.stream_id, &aux_data->data_prd);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
/* TODO nghttp2_submit_data() may fail if stream has already
|
|
||||||
DATA frame item. We might have to handle it here. */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NGHTTP2_PRIORITY: {
|
|
||||||
nghttp2_stream *stream;
|
|
||||||
|
|
||||||
if (session->server) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
|
|
||||||
|
|
||||||
if (!stream) {
|
|
||||||
if (!session_detect_idle_stream(session, frame->hd.stream_id)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream = nghttp2_session_open_stream(
|
|
||||||
session, frame->hd.stream_id, NGHTTP2_FLAG_NONE,
|
|
||||||
&frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL);
|
|
||||||
if (!stream) {
|
|
||||||
return NGHTTP2_ERR_NOMEM;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rv = nghttp2_session_reprioritize_stream(session, stream,
|
|
||||||
&frame->priority.pri_spec);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nghttp2_session_adjust_idle_stream(session);
|
|
||||||
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NGHTTP2_RST_STREAM:
|
|
||||||
rv = nghttp2_session_close_stream(session, frame->hd.stream_id,
|
|
||||||
frame->rst_stream.error_code);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NGHTTP2_GOAWAY: {
|
|
||||||
nghttp2_goaway_aux_data *aux_data;
|
|
||||||
|
|
||||||
aux_data = &item->aux_data.goaway;
|
|
||||||
|
|
||||||
if ((aux_data->flags & NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE) == 0) {
|
|
||||||
|
|
||||||
if (aux_data->flags & NGHTTP2_GOAWAY_AUX_TERM_ON_SEND) {
|
|
||||||
session->goaway_flags |= NGHTTP2_GOAWAY_TERM_SENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
session->goaway_flags |= NGHTTP2_GOAWAY_SENT;
|
|
||||||
|
|
||||||
rv = session_close_stream_on_goaway(session,
|
|
||||||
frame->goaway.last_stream_id, 1);
|
|
||||||
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NGHTTP2_WINDOW_UPDATE:
|
|
||||||
if (frame->hd.stream_id == 0) {
|
|
||||||
session->window_update_queued = 0;
|
|
||||||
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
|
||||||
rv = session_update_connection_consumed_size(session, 0);
|
|
||||||
} else {
|
|
||||||
rv = session_update_recv_connection_window_size(session, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nghttp2_stream *stream;
|
|
||||||
|
|
||||||
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
|
||||||
if (!stream) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->window_update_queued = 0;
|
|
||||||
|
|
||||||
/* We don't have to send WINDOW_UPDATE if END_STREAM from peer
|
|
||||||
is seen. */
|
|
||||||
if (stream->shut_flags & NGHTTP2_SHUT_RD) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
|
||||||
rv = session_update_stream_consumed_size(session, stream, 0);
|
|
||||||
} else {
|
|
||||||
rv = session_update_recv_stream_window_size(session, stream, 0, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
nghttp2_stream *stream;
|
|
||||||
nghttp2_data_aux_data *aux_data;
|
nghttp2_data_aux_data *aux_data;
|
||||||
|
|
||||||
aux_data = &item->aux_data.data;
|
aux_data = &item->aux_data.data;
|
||||||
|
@ -2688,7 +2503,6 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
||||||
|
|
||||||
if (stream && aux_data->eof) {
|
if (stream && aux_data->eof) {
|
||||||
rv = nghttp2_stream_detach_item(stream);
|
rv = nghttp2_stream_detach_item(stream);
|
||||||
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -2698,7 +2512,6 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
||||||
nghttp2_submit_data() in the callback. */
|
nghttp2_submit_data() in the callback. */
|
||||||
if (session->callbacks.on_frame_send_callback) {
|
if (session->callbacks.on_frame_send_callback) {
|
||||||
rv = session_call_on_frame_send(session, frame);
|
rv = session_call_on_frame_send(session, frame);
|
||||||
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -2726,6 +2539,149 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
||||||
|
|
||||||
if (session->callbacks.on_frame_send_callback) {
|
if (session->callbacks.on_frame_send_callback) {
|
||||||
rv = session_call_on_frame_send(session, frame);
|
rv = session_call_on_frame_send(session, frame);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non-DATA frame */
|
||||||
|
|
||||||
|
if (frame->hd.type == NGHTTP2_HEADERS ||
|
||||||
|
frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
||||||
|
if (nghttp2_bufs_next_present(framebufs)) {
|
||||||
|
DEBUGF(fprintf(stderr, "send: CONTINUATION exists, just return\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rv = session_call_on_frame_send(session, frame);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
switch (frame->hd.type) {
|
||||||
|
case NGHTTP2_HEADERS: {
|
||||||
|
nghttp2_headers_aux_data *aux_data;
|
||||||
|
|
||||||
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||||
|
if (!stream) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (frame->headers.cat) {
|
||||||
|
case NGHTTP2_HCAT_REQUEST: {
|
||||||
|
stream->state = NGHTTP2_STREAM_OPENING;
|
||||||
|
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
|
||||||
|
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
|
||||||
|
}
|
||||||
|
rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
|
||||||
|
aux_data = &item->aux_data.headers;
|
||||||
|
if (aux_data->data_prd.read_callback) {
|
||||||
|
/* nghttp2_submit_data() makes a copy of aux_data->data_prd */
|
||||||
|
rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
|
||||||
|
frame->hd.stream_id, &aux_data->data_prd);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
/* TODO nghttp2_submit_data() may fail if stream has already
|
||||||
|
DATA frame item. We might have to handle it here. */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case NGHTTP2_HCAT_PUSH_RESPONSE:
|
||||||
|
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH);
|
||||||
|
++session->num_outgoing_streams;
|
||||||
|
/* Fall through */
|
||||||
|
case NGHTTP2_HCAT_RESPONSE:
|
||||||
|
stream->state = NGHTTP2_STREAM_OPENED;
|
||||||
|
/* Fall through */
|
||||||
|
case NGHTTP2_HCAT_HEADERS:
|
||||||
|
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
|
||||||
|
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
|
||||||
|
}
|
||||||
|
rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
|
||||||
|
aux_data = &item->aux_data.headers;
|
||||||
|
if (aux_data->data_prd.read_callback) {
|
||||||
|
rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
|
||||||
|
frame->hd.stream_id, &aux_data->data_prd);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
/* TODO nghttp2_submit_data() may fail if stream has already
|
||||||
|
DATA frame item. We might have to handle it here. */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
/* Unreachable */
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case NGHTTP2_PRIORITY:
|
||||||
|
if (session->server) {
|
||||||
|
return 0;
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
|
||||||
|
|
||||||
|
if (!stream) {
|
||||||
|
if (!session_detect_idle_stream(session, frame->hd.stream_id)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = nghttp2_session_open_stream(
|
||||||
|
session, frame->hd.stream_id, NGHTTP2_FLAG_NONE,
|
||||||
|
&frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL);
|
||||||
|
if (!stream) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rv = nghttp2_session_reprioritize_stream(session, stream,
|
||||||
|
&frame->priority.pri_spec);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = nghttp2_session_adjust_idle_stream(session);
|
||||||
|
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
case NGHTTP2_RST_STREAM:
|
||||||
|
rv = nghttp2_session_close_stream(session, frame->hd.stream_id,
|
||||||
|
frame->rst_stream.error_code);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
case NGHTTP2_GOAWAY: {
|
||||||
|
nghttp2_goaway_aux_data *aux_data;
|
||||||
|
|
||||||
|
aux_data = &item->aux_data.goaway;
|
||||||
|
|
||||||
|
if ((aux_data->flags & NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE) == 0) {
|
||||||
|
|
||||||
|
if (aux_data->flags & NGHTTP2_GOAWAY_AUX_TERM_ON_SEND) {
|
||||||
|
session->goaway_flags |= NGHTTP2_GOAWAY_TERM_SENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->goaway_flags |= NGHTTP2_GOAWAY_SENT;
|
||||||
|
|
||||||
|
rv = session_close_stream_on_goaway(session, frame->goaway.last_stream_id,
|
||||||
|
1);
|
||||||
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -2734,9 +2690,49 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Unreachable */
|
case NGHTTP2_WINDOW_UPDATE:
|
||||||
assert(0);
|
if (frame->hd.stream_id == 0) {
|
||||||
return 0;
|
session->window_update_queued = 0;
|
||||||
|
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
||||||
|
rv = session_update_connection_consumed_size(session, 0);
|
||||||
|
} else {
|
||||||
|
rv = session_update_recv_connection_window_size(session, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||||
|
if (!stream) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->window_update_queued = 0;
|
||||||
|
|
||||||
|
/* We don't have to send WINDOW_UPDATE if END_STREAM from peer
|
||||||
|
is seen. */
|
||||||
|
if (stream->shut_flags & NGHTTP2_SHUT_RD) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
||||||
|
rv = session_update_stream_consumed_size(session, stream, 0);
|
||||||
|
} else {
|
||||||
|
rv = session_update_recv_stream_window_size(session, stream, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue