aboutsummaryrefslogtreecommitdiff
path: root/src/microspdy/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microspdy/session.c')
-rw-r--r--src/microspdy/session.c111
1 files changed, 110 insertions, 1 deletions
diff --git a/src/microspdy/session.c b/src/microspdy/session.c
index 7edebaba..918b9fdf 100644
--- a/src/microspdy/session.c
+++ b/src/microspdy/session.c
@@ -380,7 +380,9 @@ spdyf_handler_read_data (struct SPDY_Session *session)
380 frame->length, 380 frame->length,
381 0 == (SPDY_DATA_FLAG_FIN & frame->flags)); 381 0 == (SPDY_DATA_FLAG_FIN & frame->flags));
382 382
383 session->read_buffer_beginning += frame->length; 383 session->read_buffer_beginning += frame->length;
384
385 stream->window_size -= frame->length;
384 386
385 //TODO close in and send rst maybe 387 //TODO close in and send rst maybe
386 SPDYF_ASSERT(SPDY_YES == ret, "Cancel POST data is not yet implemented"); 388 SPDYF_ASSERT(SPDY_YES == ret, "Cancel POST data is not yet implemented");
@@ -389,6 +391,20 @@ spdyf_handler_read_data (struct SPDY_Session *session)
389 { 391 {
390 stream->is_in_closed = true; 392 stream->is_in_closed = true;
391 } 393 }
394 else if(stream->window_size < SPDYF_INITIAL_WINDOW_SIZE / 2)
395 {
396 //very simple implementation of flow control
397 //when the window's size is under the half of the initial value,
398 //increase it again up to the initial value
399
400 //prepare WINDOW_UPDATE
401 if(SPDY_YES == SPDYF_prepare_window_update(session, stream,
402 SPDYF_INITIAL_WINDOW_SIZE - stream->window_size))
403 {
404 stream->window_size = SPDYF_INITIAL_WINDOW_SIZE;
405 }
406 //else: do it later
407 }
392 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER; 408 session->status = SPDY_SESSION_STATUS_WAIT_FOR_HEADER;
393 free(frame); 409 free(frame);
394 } 410 }
@@ -751,6 +767,47 @@ SPDYF_handler_write_rst_stream (struct SPDY_Session *session)
751 return SPDY_YES; 767 return SPDY_YES;
752} 768}
753 769
770
771int
772SPDYF_handler_write_window_update (struct SPDY_Session *session)
773{
774 struct SPDYF_Response_Queue *response_queue = session->response_queue_head;
775 struct SPDYF_Control_Frame control_frame;
776 size_t total_size;
777
778 SPDYF_ASSERT(NULL == session->write_buffer, "the function is called not in the correct moment");
779
780 memcpy(&control_frame, response_queue->control_frame, sizeof(control_frame));
781
782 total_size = sizeof(struct SPDYF_Control_Frame) //SPDY header
783 + 4 // stream id as "subheader"
784 + 4; // delta-window-size as "subheader"
785
786 if(NULL == (session->write_buffer = malloc(total_size)))
787 {
788 return SPDY_NO;
789 }
790 session->write_buffer_beginning = 0;
791 session->write_buffer_offset = 0;
792 session->write_buffer_size = total_size;
793
794 control_frame.length = 8; // always for WINDOW_UPDATE
795 SPDYF_CONTROL_FRAME_HTON(&control_frame);
796
797 //put frame headers to write buffer
798 memcpy(session->write_buffer + session->write_buffer_offset,&control_frame,sizeof(struct SPDYF_Control_Frame));
799 session->write_buffer_offset += sizeof(struct SPDYF_Control_Frame);
800
801 //put stream id and delta-window-size to write buffer
802 memcpy(session->write_buffer + session->write_buffer_offset, response_queue->data, 8);
803 session->write_buffer_offset += 8;
804
805 SPDYF_ASSERT(0 == session->write_buffer_beginning, "bug1");
806 SPDYF_ASSERT(session->write_buffer_offset == session->write_buffer_size, "bug2");
807
808 return SPDY_YES;
809}
810
754 811
755void 812void
756SPDYF_handler_ignore_frame (struct SPDY_Session *session) 813SPDYF_handler_ignore_frame (struct SPDY_Session *session)
@@ -1638,3 +1695,55 @@ SPDYF_prepare_rst_stream (struct SPDY_Session *session,
1638 1695
1639 return SPDY_YES; 1696 return SPDY_YES;
1640} 1697}
1698
1699
1700int
1701SPDYF_prepare_window_update (struct SPDY_Session *session,
1702 struct SPDYF_Stream * stream,
1703 int32_t delta_window_size)
1704{
1705 struct SPDYF_Response_Queue *response_to_queue;
1706 struct SPDYF_Control_Frame *control_frame;
1707 uint32_t *data;
1708
1709 SPDYF_ASSERT(NULL != stream, "stream cannot be NULL");
1710
1711 if(NULL == (response_to_queue = malloc(sizeof(struct SPDYF_Response_Queue))))
1712 {
1713 return SPDY_NO;
1714 }
1715 memset(response_to_queue, 0, sizeof(struct SPDYF_Response_Queue));
1716
1717 if(NULL == (control_frame = malloc(sizeof(struct SPDYF_Control_Frame))))
1718 {
1719 free(response_to_queue);
1720 return SPDY_NO;
1721 }
1722 memset(control_frame, 0, sizeof(struct SPDYF_Control_Frame));
1723
1724 if(NULL == (data = malloc(8)))
1725 {
1726 free(control_frame);
1727 free(response_to_queue);
1728 return SPDY_NO;
1729 }
1730 *(data) = HTON31(stream->stream_id);
1731 *(data + 1) = HTON31(delta_window_size);
1732
1733 control_frame->control_bit = 1;
1734 control_frame->version = SPDY_VERSION;
1735 control_frame->type = SPDY_CONTROL_FRAME_TYPES_WINDOW_UPDATE;
1736 control_frame->flags = 0;
1737
1738 response_to_queue->control_frame = control_frame;
1739 response_to_queue->process_response_handler = &SPDYF_handler_write_window_update;
1740 response_to_queue->data = data;
1741 response_to_queue->data_size = 8;
1742 response_to_queue->stream = stream;
1743
1744 SPDYF_queue_response (response_to_queue,
1745 session,
1746 -1);
1747
1748 return SPDY_YES;
1749}