Commit 9d4e8eeb authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Simplify code

Move DATA frame handling code to switch-case of frame type.
parent 8099dd95
......@@ -816,9 +816,23 @@ int nghttp2_session_add_item(nghttp2_session *session,
frame = &item->frame;
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if (frame->hd.type != NGHTTP2_DATA) {
switch (frame->hd.type) {
case NGHTTP2_DATA:
if (!stream) {
return NGHTTP2_ERR_STREAM_CLOSED;
}
if (stream->item) {
return NGHTTP2_ERR_DATA_EXIST;
}
rv = nghttp2_stream_attach_item(stream, item);
if (rv != 0) {
return rv;
}
return 0;
case NGHTTP2_HEADERS:
/* We push request HEADERS and push response HEADERS to
dedicated queue because their transmission is affected by
......@@ -830,24 +844,25 @@ int nghttp2_session_add_item(nghttp2_session *session,
(stream && stream->state == NGHTTP2_STREAM_RESERVED)) {
nghttp2_outbound_queue_push(&session->ob_syn, item);
item->queued = 1;
break;
return 0;
;
}
nghttp2_outbound_queue_push(&session->ob_reg, item);
item->queued = 1;
break;
return 0;
case NGHTTP2_SETTINGS:
case NGHTTP2_PING:
nghttp2_outbound_queue_push(&session->ob_urgent, item);
item->queued = 1;
break;
return 0;
case NGHTTP2_RST_STREAM:
if (stream) {
stream->state = NGHTTP2_STREAM_CLOSING;
}
nghttp2_outbound_queue_push(&session->ob_reg, item);
item->queued = 1;
break;
return 0;
case NGHTTP2_PUSH_PROMISE: {
nghttp2_headers_aux_data *aux_data;
nghttp2_priority_spec pri_spec;
......@@ -875,7 +890,7 @@ int nghttp2_session_add_item(nghttp2_session *session,
nghttp2_outbound_queue_push(&session->ob_reg, item);
item->queued = 1;
break;
return 0;
}
case NGHTTP2_WINDOW_UPDATE:
if (stream) {
......@@ -885,30 +900,12 @@ int nghttp2_session_add_item(nghttp2_session *session,
}
nghttp2_outbound_queue_push(&session->ob_reg, item);
item->queued = 1;
break;
return 0;
default:
nghttp2_outbound_queue_push(&session->ob_reg, item);
item->queued = 1;
}
return 0;
}
if (!stream) {
return NGHTTP2_ERR_STREAM_CLOSED;
}
if (stream->item) {
return NGHTTP2_ERR_DATA_EXIST;
}
rv = nghttp2_stream_attach_item(stream, item);
if (rv != 0) {
return rv;
}
return 0;
}
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
......@@ -1941,8 +1938,101 @@ static int session_prep_frame(nghttp2_session *session,
mem = &session->mem;
frame = &item->frame;
if (frame->hd.type != NGHTTP2_DATA) {
switch (frame->hd.type) {
case NGHTTP2_DATA: {
size_t next_readmax;
nghttp2_stream *stream;
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if (stream) {
assert(stream->item == item);
}
rv = nghttp2_session_predicate_data_send(session, stream);
if (rv != 0) {
// If stream was already closed, nghttp2_session_get_stream()
// returns NULL, but item is still attached to the stream.
// Search stream including closed again.
stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
if (stream) {
int rv2;
rv2 = nghttp2_stream_detach_item(stream);
if (nghttp2_is_fatal(rv2)) {
return rv2;
}
}
return rv;
}
/* Assuming stream is not NULL */
assert(stream);
next_readmax = nghttp2_session_next_data_read(session, stream);
if (next_readmax == 0) {
/* This must be true since we only pop DATA frame item from
queue when session->remote_window_size > 0 */
assert(session->remote_window_size > 0);
rv = nghttp2_stream_defer_item(stream,
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
session->aob.item = NULL;
active_outbound_item_reset(&session->aob, mem);
return NGHTTP2_ERR_DEFERRED;
}
rv = nghttp2_session_pack_data(session, &session->aob.framebufs,
next_readmax, frame, &item->aux_data.data,
stream);
if (rv == NGHTTP2_ERR_PAUSE) {
return rv;
}
if (rv == NGHTTP2_ERR_DEFERRED) {
rv = nghttp2_stream_defer_item(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER);
if (nghttp2_is_fatal(rv)) {
return rv;
}
session->aob.item = NULL;
active_outbound_item_reset(&session->aob, mem);
return NGHTTP2_ERR_DEFERRED;
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_stream_detach_item(stream);
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id,
NGHTTP2_INTERNAL_ERROR);
if (nghttp2_is_fatal(rv)) {
return rv;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
if (rv != 0) {
int rv2;
rv2 = nghttp2_stream_detach_item(stream);
if (nghttp2_is_fatal(rv2)) {
return rv2;
}
return rv;
}
return 0;
}
case NGHTTP2_HEADERS: {
nghttp2_headers_aux_data *aux_data;
size_t estimated_payloadlen;
......@@ -2014,20 +2104,6 @@ static int session_prep_frame(nghttp2_session *session,
}
if (rv != 0) {
// If stream was already closed, nghttp2_session_get_stream()
// returns NULL, but item is still attached to the stream.
// Search stream including closed again.
stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
if (stream && stream->item == item) {
int rv2;
rv2 = nghttp2_stream_detach_item(stream);
if (nghttp2_is_fatal(rv2)) {
return rv2;
}
}
return rv;
}
}
......@@ -2057,7 +2133,7 @@ static int session_prep_frame(nghttp2_session *session,
session->last_sent_stream_id = frame->hd.stream_id;
}
break;
return 0;
}
case NGHTTP2_PRIORITY: {
if (session_is_closing(session)) {
......@@ -2071,15 +2147,14 @@ static int session_prep_frame(nghttp2_session *session,
"anchor" in dependency tree. Only client can do this in
nghttp2. In nghttp2, only server retains non-active (closed
or idle) streams in memory, so we don't open stream here. */
break;
return 0;
}
case NGHTTP2_RST_STREAM:
if (session_is_closing(session)) {
return NGHTTP2_ERR_SESSION_CLOSING;
}
nghttp2_frame_pack_rst_stream(&session->aob.framebufs,
&frame->rst_stream);
break;
nghttp2_frame_pack_rst_stream(&session->aob.framebufs, &frame->rst_stream);
return 0;
case NGHTTP2_SETTINGS: {
if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
assert(session->obq_flood_counter_ > 0);
......@@ -2093,12 +2168,11 @@ static int session_prep_frame(nghttp2_session *session,
}
}
rv = nghttp2_frame_pack_settings(&session->aob.framebufs,
&frame->settings);
rv = nghttp2_frame_pack_settings(&session->aob.framebufs, &frame->settings);
if (rv != 0) {
return rv;
}
break;
return 0;
}
case NGHTTP2_PUSH_PROMISE: {
nghttp2_stream *stream;
......@@ -2137,7 +2211,7 @@ static int session_prep_frame(nghttp2_session *session,
frame->push_promise.promised_stream_id);
session->last_sent_stream_id = frame->push_promise.promised_stream_id;
break;
return 0;
}
case NGHTTP2_PING:
if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
......@@ -2149,7 +2223,7 @@ static int session_prep_frame(nghttp2_session *session,
return NGHTTP2_ERR_SESSION_CLOSING;
}
nghttp2_frame_pack_ping(&session->aob.framebufs, &frame->ping);
break;
return 0;
case NGHTTP2_GOAWAY:
rv = nghttp2_frame_pack_goaway(&session->aob.framebufs, &frame->goaway);
if (rv != 0) {
......@@ -2157,7 +2231,7 @@ static int session_prep_frame(nghttp2_session *session,
}
session->local_last_stream_id = frame->goaway.last_stream_id;
break;
return 0;
case NGHTTP2_WINDOW_UPDATE:
rv = session_predicate_window_update_send(session, frame->hd.stream_id);
if (rv != 0) {
......@@ -2165,11 +2239,11 @@ static int session_prep_frame(nghttp2_session *session,
}
nghttp2_frame_pack_window_update(&session->aob.framebufs,
&frame->window_update);
break;
return 0;
case NGHTTP2_CONTINUATION:
/* We never handle CONTINUATION here. */
assert(0);
break;
return 0;
default: {
nghttp2_ext_aux_data *aux_data;
......@@ -2182,12 +2256,7 @@ static int session_prep_frame(nghttp2_session *session,
return NGHTTP2_ERR_SESSION_CLOSING;
}
rv = session_pack_extension(session, &session->aob.framebufs, frame);
if (rv != 0) {
return rv;
}
break;
return session_pack_extension(session, &session->aob.framebufs, frame);
}
switch (frame->hd.type) {
......@@ -2199,110 +2268,13 @@ static int session_prep_frame(nghttp2_session *session,
nghttp2_frame_pack_altsvc(&session->aob.framebufs, &frame->ext);
break;
return 0;
default:
/* Unreachable here */
assert(0);
break;
}
break;
}
}
return 0;
} else {
size_t next_readmax;
nghttp2_stream *stream;
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if (stream) {
assert(stream->item == item);
}
rv = nghttp2_session_predicate_data_send(session, stream);
if (rv != 0) {
// If stream was already closed, nghttp2_session_get_stream()
// returns NULL, but item is still attached to the stream.
// Search stream including closed again.
stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
if (stream) {
int rv2;
rv2 = nghttp2_stream_detach_item(stream);
if (nghttp2_is_fatal(rv2)) {
return rv2;
}
}
return rv;
}
/* Assuming stream is not NULL */
assert(stream);
next_readmax = nghttp2_session_next_data_read(session, stream);
if (next_readmax == 0) {
/* This must be true since we only pop DATA frame item from
queue when session->remote_window_size > 0 */
assert(session->remote_window_size > 0);
rv = nghttp2_stream_defer_item(stream,
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
session->aob.item = NULL;
active_outbound_item_reset(&session->aob, mem);
return NGHTTP2_ERR_DEFERRED;
}
rv = nghttp2_session_pack_data(session, &session->aob.framebufs,
next_readmax, frame, &item->aux_data.data,
stream);
if (rv == NGHTTP2_ERR_PAUSE) {
return rv;
}
if (rv == NGHTTP2_ERR_DEFERRED) {
rv = nghttp2_stream_defer_item(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER);
if (nghttp2_is_fatal(rv)) {
return rv;
}
session->aob.item = NULL;
active_outbound_item_reset(&session->aob, mem);
return NGHTTP2_ERR_DEFERRED;
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_stream_detach_item(stream);
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id,
NGHTTP2_INTERNAL_ERROR);
if (nghttp2_is_fatal(rv)) {
return rv;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
if (rv != 0) {
int rv2;
rv2 = nghttp2_stream_detach_item(stream);
if (nghttp2_is_fatal(rv2)) {
return rv2;
}
return rv;
}
return 0;
}
}
......@@ -2538,14 +2510,6 @@ static int session_after_frame_sent1(nghttp2_session *session) {
break;
}
if (stream->item == item) {
rv = nghttp2_stream_detach_item(stream);
if (nghttp2_is_fatal(rv)) {
return rv;
}
}
switch (frame->headers.cat) {
case NGHTTP2_HCAT_REQUEST: {
stream->state = NGHTTP2_STREAM_OPENING;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment