libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit fe35bcf2eb982078ee043927bda2b6cc107871bd
parent 0bebdb1cc3d5aaf217c1227ebc2b58ec7698377b
Author: Andrey Uzunov <andrey.uzunov@gmail.com>
Date:   Thu, 18 Jul 2013 21:44:37 +0000

spdy: send RST_STREAM when user callback for response fails

Diffstat:
Msrc/microspdy/session.c | 31+++++++++++++++++++++++++------
Msrc/microspdy/session.h | 4++--
2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/src/microspdy/session.c b/src/microspdy/session.c @@ -129,7 +129,7 @@ spdyf_handler_read_syn_stream (struct SPDY_Session *session) if(0 == name_value_strm_size || 0 == compressed_data_size) { //Protocol error: send RST_STREAM - if(SPDY_YES != SPDYF_prepare_rst_stream(session, session->current_stream_id, + if(SPDY_YES != SPDYF_prepare_rst_stream(session, session->streams_head, SPDY_RST_STREAM_STATUS_PROTOCOL_ERROR)) { //no memory, try later to send RST @@ -571,11 +571,22 @@ SPDYF_handler_write_data (struct SPDY_Session *session) if(ret < 0 || ret > response_queue->response->rcb_block_size) { - //TODO send RST_STREAM (app error) + free(session->write_buffer); + session->write_buffer = NULL; + + //send RST_STREAM + if(SPDY_YES == (ret = SPDYF_prepare_rst_stream(session, + response_queue->stream, + SPDY_RST_STREAM_STATUS_INTERNAL_ERROR))) + { + return SPDY_NO; + } + + //else no memory //for now close session + //TODO what? session->status = SPDY_SESSION_STATUS_CLOSING; - free(session->write_buffer); return SPDY_NO; } if(0 == ret && more) @@ -619,6 +630,7 @@ SPDYF_handler_write_data (struct SPDY_Session *session) session->status = SPDY_SESSION_STATUS_CLOSING; free(session->write_buffer); + session->write_buffer = NULL; return SPDY_NO; } @@ -992,7 +1004,7 @@ SPDYF_session_write (struct SPDY_Session *session, bool only_one_frame) if(session->write_buffer_beginning == session->write_buffer_size) { //that response is handled, remove it from queue - free(session->write_buffer); + free(session->write_buffer); session->write_buffer = NULL; session->write_buffer_size = 0; queue_head = session->response_queue_head; @@ -1175,7 +1187,7 @@ SPDYF_session_idle (struct SPDY_Session *session) session->read_buffer_beginning = session->read_buffer_offset; SPDYF_prepare_rst_stream(session, - session->current_stream_id, //may be 0 here which is not good + session->current_stream_id > 0 ? session->streams_head : NULL, //may be 0 here which is not good SPDY_RST_STREAM_STATUS_FRAME_TOO_LARGE); //actually the read buffer can be bigger than the @@ -1541,13 +1553,19 @@ SPDYF_prepare_goaway (struct SPDY_Session *session, int SPDYF_prepare_rst_stream (struct SPDY_Session *session, - uint32_t stream_id, + struct SPDYF_Stream * stream, enum SPDY_RST_STREAM_STATUS status) { struct SPDYF_Response_Queue *response_to_queue; struct SPDYF_Control_Frame *control_frame; uint32_t *data; + uint32_t stream_id; + if(NULL == stream) + stream_id = 0; + else + stream_id = stream->stream_id; + if(NULL == (response_to_queue = malloc(sizeof(struct SPDYF_Response_Queue)))) { return SPDY_NO; @@ -1579,6 +1597,7 @@ SPDYF_prepare_rst_stream (struct SPDY_Session *session, response_to_queue->process_response_handler = &SPDYF_handler_write_rst_stream; response_to_queue->data = data; response_to_queue->data_size = 8; + response_to_queue->stream = stream; SPDYF_queue_response (response_to_queue, session, diff --git a/src/microspdy/session.h b/src/microspdy/session.h @@ -160,14 +160,14 @@ SPDYF_prepare_goaway (struct SPDY_Session *session, * will be discarded soon. * * @param session SPDY session - * @param stream_id stream to terminate + * @param stream stream to terminate * @param status code for the RST_STREAM frame * @return SPDY_NO on memory error or * SPDY_YES on success */ int SPDYF_prepare_rst_stream (struct SPDY_Session *session, - uint32_t stream_id, + struct SPDYF_Stream * stream, enum SPDY_RST_STREAM_STATUS status);