Added stream status change after sending SYN_STREAM and SYN_REPLY.
This commit is contained in:
parent
1ce2598758
commit
6e627548be
|
@ -30,15 +30,10 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "spdylay_stream.h"
|
|
||||||
#include "spdylay_helper.h"
|
#include "spdylay_helper.h"
|
||||||
|
|
||||||
/*
|
spdylay_stream* spdylay_session_get_stream(spdylay_session *session,
|
||||||
* Returns spdylay_stream* object whose stream ID is |stream_id|. It
|
int32_t stream_id)
|
||||||
* could be NULL if such stream does not exist.
|
|
||||||
*/
|
|
||||||
static spdylay_stream* spdylay_session_get_stream(spdylay_session *session,
|
|
||||||
int32_t stream_id)
|
|
||||||
{
|
{
|
||||||
return (spdylay_stream*)spdylay_map_find(&session->streams, stream_id);
|
return (spdylay_stream*)spdylay_map_find(&session->streams, stream_id);
|
||||||
}
|
}
|
||||||
|
@ -115,6 +110,9 @@ static void spdylay_outbound_item_free(spdylay_outbound_item *item)
|
||||||
case SPDYLAY_SYN_STREAM:
|
case SPDYLAY_SYN_STREAM:
|
||||||
spdylay_frame_syn_stream_free(&item->frame->syn_stream);
|
spdylay_frame_syn_stream_free(&item->frame->syn_stream);
|
||||||
break;
|
break;
|
||||||
|
case SPDYLAY_SYN_REPLY:
|
||||||
|
spdylay_frame_syn_reply_free(&item->frame->syn_reply);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free(item->frame);
|
free(item->frame);
|
||||||
}
|
}
|
||||||
|
@ -201,14 +199,15 @@ int spdylay_session_add_rst_stream(spdylay_session *session,
|
||||||
}
|
}
|
||||||
|
|
||||||
int spdylay_session_open_stream(spdylay_session *session, int32_t stream_id,
|
int spdylay_session_open_stream(spdylay_session *session, int32_t stream_id,
|
||||||
uint8_t flags, uint8_t pri)
|
uint8_t flags, uint8_t pri,
|
||||||
|
spdylay_stream_state initial_state)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
spdylay_stream *stream = malloc(sizeof(spdylay_stream));
|
spdylay_stream *stream = malloc(sizeof(spdylay_stream));
|
||||||
if(stream == NULL) {
|
if(stream == NULL) {
|
||||||
return SPDYLAY_ERR_NOMEM;
|
return SPDYLAY_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
spdylay_stream_init(stream, stream_id, flags, pri);
|
spdylay_stream_init(stream, stream_id, flags, pri, initial_state);
|
||||||
r = spdylay_map_insert(&session->streams, stream_id, stream);
|
r = spdylay_map_insert(&session->streams, stream_id, stream);
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
free(stream);
|
free(stream);
|
||||||
|
@ -216,6 +215,19 @@ int spdylay_session_open_stream(spdylay_session *session, int32_t stream_id,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spdylay_session_close_stream(spdylay_session *session, int32_t stream_id)
|
||||||
|
{
|
||||||
|
spdylay_stream *stream = spdylay_session_get_stream(session, stream_id);
|
||||||
|
if(stream) {
|
||||||
|
spdylay_map_erase(&session->streams, stream_id);
|
||||||
|
spdylay_stream_free(stream);
|
||||||
|
free(stream);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return SPDYLAY_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
spdylay_outbound_item *item,
|
spdylay_outbound_item *item,
|
||||||
uint8_t **framebuf_ptr)
|
uint8_t **framebuf_ptr)
|
||||||
|
@ -233,20 +245,29 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
}
|
}
|
||||||
printf("packed %d bytes\n", framebuflen);
|
|
||||||
r = spdylay_session_open_stream(session, item->frame->syn_stream.stream_id,
|
r = spdylay_session_open_stream(session, item->frame->syn_stream.stream_id,
|
||||||
item->frame->syn_stream.hd.flags,
|
item->frame->syn_stream.hd.flags,
|
||||||
item->frame->syn_stream.pri);
|
item->frame->syn_stream.pri,
|
||||||
|
SPDYLAY_STREAM_INITIAL);
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
free(framebuf);
|
free(framebuf);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
*framebuf_ptr = framebuf;
|
break;
|
||||||
|
}
|
||||||
|
case SPDYLAY_SYN_REPLY: {
|
||||||
|
framebuflen = spdylay_frame_pack_syn_reply(&framebuf,
|
||||||
|
&item->frame->syn_reply,
|
||||||
|
&session->hd_deflater);
|
||||||
|
if(framebuflen < 0) {
|
||||||
|
return framebuflen;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
framebuflen = SPDYLAY_ERR_INVALID_ARGUMENT;
|
framebuflen = SPDYLAY_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
*framebuf_ptr = framebuf;
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +280,34 @@ static void spdylay_active_outbound_item_reset
|
||||||
memset(aob, 0, sizeof(spdylay_active_outbound_item));
|
memset(aob, 0, sizeof(spdylay_active_outbound_item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int spdylay_session_after_frame_sent(spdylay_session *session)
|
||||||
|
{
|
||||||
|
spdylay_frame *frame = session->aob.item->frame;
|
||||||
|
switch(session->aob.item->frame_type) {
|
||||||
|
case SPDYLAY_SYN_STREAM: {
|
||||||
|
spdylay_stream *stream =
|
||||||
|
spdylay_session_get_stream(session, frame->syn_stream.stream_id);
|
||||||
|
if(stream) {
|
||||||
|
stream->state = SPDYLAY_STREAM_OPENING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPDYLAY_SYN_REPLY: {
|
||||||
|
spdylay_stream *stream =
|
||||||
|
spdylay_session_get_stream(session, frame->syn_reply.stream_id);
|
||||||
|
if(stream) {
|
||||||
|
stream->state = SPDYLAY_STREAM_OPENED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPDYLAY_RST_STREAM:
|
||||||
|
spdylay_session_close_stream(session, frame->rst_stream.stream_id);
|
||||||
|
};
|
||||||
|
/* TODO If frame is data frame, we need to sent all chunk of
|
||||||
|
data.*/
|
||||||
|
spdylay_active_outbound_item_reset(&session->aob);
|
||||||
|
}
|
||||||
|
|
||||||
int spdylay_session_send(spdylay_session *session)
|
int spdylay_session_send(spdylay_session *session)
|
||||||
{
|
{
|
||||||
printf("session_send\n");
|
printf("session_send\n");
|
||||||
|
@ -298,9 +347,7 @@ int spdylay_session_send(spdylay_session *session)
|
||||||
session->aob.framebufoff += sentlen;
|
session->aob.framebufoff += sentlen;
|
||||||
if(session->aob.framebufoff == session->aob.framebuflen) {
|
if(session->aob.framebufoff == session->aob.framebuflen) {
|
||||||
/* Frame has completely sent */
|
/* Frame has completely sent */
|
||||||
spdylay_active_outbound_item_reset(&session->aob);
|
spdylay_session_after_frame_sent(session);
|
||||||
/* TODO If frame is data frame, we need to sent all chunk of
|
|
||||||
data.*/
|
|
||||||
} else {
|
} else {
|
||||||
/* partial write */
|
/* partial write */
|
||||||
break;
|
break;
|
||||||
|
@ -441,7 +488,8 @@ int spdylay_session_on_syn_stream_received(spdylay_session *session,
|
||||||
if(spdylay_session_validate_syn_stream(session, &frame->syn_stream) == 0) {
|
if(spdylay_session_validate_syn_stream(session, &frame->syn_stream) == 0) {
|
||||||
r = spdylay_session_open_stream(session, frame->syn_stream.stream_id,
|
r = spdylay_session_open_stream(session, frame->syn_stream.stream_id,
|
||||||
frame->syn_stream.hd.flags,
|
frame->syn_stream.hd.flags,
|
||||||
frame->syn_stream.pri);
|
frame->syn_stream.pri,
|
||||||
|
SPDYLAY_STREAM_OPENING);
|
||||||
if(r == 0) {
|
if(r == 0) {
|
||||||
session->last_recv_stream_id = frame->syn_stream.stream_id;
|
session->last_recv_stream_id = frame->syn_stream.stream_id;
|
||||||
spdylay_session_call_on_ctrl_frame_received(session, SPDYLAY_SYN_STREAM,
|
spdylay_session_call_on_ctrl_frame_received(session, SPDYLAY_SYN_STREAM,
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "spdylay_map.h"
|
#include "spdylay_map.h"
|
||||||
#include "spdylay_frame.h"
|
#include "spdylay_frame.h"
|
||||||
#include "spdylay_zlib.h"
|
#include "spdylay_zlib.h"
|
||||||
|
#include "spdylay_stream.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
spdylay_frame_type frame_type;
|
spdylay_frame_type frame_type;
|
||||||
|
@ -107,13 +108,20 @@ int spdylay_session_add_rst_stream(spdylay_session *session,
|
||||||
* SPDYLAY_FLAG_UNIDIRECTIONAL is non-zero, this stream is
|
* SPDYLAY_FLAG_UNIDIRECTIONAL is non-zero, this stream is
|
||||||
* unidirectional. |flags| & SPDYLAY_FLAG_FIN is non-zero, the sender
|
* unidirectional. |flags| & SPDYLAY_FLAG_FIN is non-zero, the sender
|
||||||
* of SYN_STREAM will not send any further data in this stream.
|
* of SYN_STREAM will not send any further data in this stream.
|
||||||
|
* The state of stream is set to |initial_state|.
|
||||||
*/
|
*/
|
||||||
int spdylay_session_open_stream(spdylay_session *session, int32_t stream_id,
|
int spdylay_session_open_stream(spdylay_session *session, int32_t stream_id,
|
||||||
uint8_t flags, uint8_t pri);
|
uint8_t flags, uint8_t pri,
|
||||||
|
spdylay_stream_state initial_state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Closes stream whose stream ID is |stream_id|. This function returns
|
||||||
|
* 0 if it succeeds, or negative error code. The possible error code
|
||||||
|
* is SPDYLAY_ERR_INVALID_ARGUMENT, which is used when stream
|
||||||
|
* |stream_id| does not exist. So the caller may ignore this error.
|
||||||
|
*/
|
||||||
int spdylay_session_close_stream(spdylay_session *session, int32_t stream_id);
|
int spdylay_session_close_stream(spdylay_session *session, int32_t stream_id);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when SYN_STREAM is received. Received frame is |frame|.
|
* Called when SYN_STREAM is received. Received frame is |frame|.
|
||||||
* This function does first
|
* This function does first
|
||||||
|
@ -132,4 +140,11 @@ int spdylay_session_on_syn_reply_received(spdylay_session *session,
|
||||||
spdylay_frame *frame);
|
spdylay_frame *frame);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns spdylay_stream* object whose stream ID is |stream_id|. It
|
||||||
|
* could be NULL if such stream does not exist.
|
||||||
|
*/
|
||||||
|
spdylay_stream* spdylay_session_get_stream(spdylay_session *session,
|
||||||
|
int32_t stream_id);
|
||||||
|
|
||||||
#endif /* SPDYLAY_SESSION_H */
|
#endif /* SPDYLAY_SESSION_H */
|
||||||
|
|
|
@ -25,12 +25,13 @@
|
||||||
#include "spdylay_stream.h"
|
#include "spdylay_stream.h"
|
||||||
|
|
||||||
void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id,
|
void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id,
|
||||||
uint8_t flags, uint8_t pri)
|
uint8_t flags, uint8_t pri,
|
||||||
|
spdylay_stream_state initial_state)
|
||||||
{
|
{
|
||||||
stream->stream_id = stream_id;
|
stream->stream_id = stream_id;
|
||||||
stream->state = SPDYLAY_STREAM_OPENING;
|
|
||||||
stream->flags = flags;
|
stream->flags = flags;
|
||||||
stream->pri = pri;
|
stream->pri = pri;
|
||||||
|
stream->state = initial_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spdylay_stream_free(spdylay_stream *stream)
|
void spdylay_stream_free(spdylay_stream *stream)
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
* SPDYLAY_STREAM_OPENED : upon sending SYN_REPLY
|
* SPDYLAY_STREAM_OPENED : upon sending SYN_REPLY
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
SPDYLAY_STREAM_INITIAL,
|
||||||
/* For stream initiator: SYN_STREAM has been sent, but SYN_REPLY is
|
/* For stream initiator: SYN_STREAM has been sent, but SYN_REPLY is
|
||||||
not received yet. For receiver: SYN_STREAM has been received,
|
not received yet. For receiver: SYN_STREAM has been received,
|
||||||
but it does not send SYN_REPLY yet. */
|
but it does not send SYN_REPLY yet. */
|
||||||
|
@ -63,7 +64,8 @@ typedef struct {
|
||||||
} spdylay_stream;
|
} spdylay_stream;
|
||||||
|
|
||||||
void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id,
|
void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id,
|
||||||
uint8_t flags, uint8_t pri);
|
uint8_t flags, uint8_t pri,
|
||||||
|
spdylay_stream_state initial_state);
|
||||||
|
|
||||||
void spdylay_stream_free(spdylay_stream *stream);
|
void spdylay_stream_free(spdylay_stream *stream);
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,10 @@ int main()
|
||||||
test_spdylay_session_on_syn_stream_received) ||
|
test_spdylay_session_on_syn_stream_received) ||
|
||||||
!CU_add_test(pSuite, "session_on_syn_reply_received",
|
!CU_add_test(pSuite, "session_on_syn_reply_received",
|
||||||
test_spdylay_session_on_syn_reply_received) ||
|
test_spdylay_session_on_syn_reply_received) ||
|
||||||
|
!CU_add_test(pSuite, "session_send_syn_stream",
|
||||||
|
test_spdylay_session_send_syn_stream) ||
|
||||||
|
!CU_add_test(pSuite, "session_send_syn_reply",
|
||||||
|
test_spdylay_session_send_syn_reply) ||
|
||||||
!CU_add_test(pSuite, "frame_unpack_nv", test_spdylay_frame_unpack_nv) ||
|
!CU_add_test(pSuite, "frame_unpack_nv", test_spdylay_frame_unpack_nv) ||
|
||||||
!CU_add_test(pSuite, "frame_count_nv_space",
|
!CU_add_test(pSuite, "frame_count_nv_space",
|
||||||
test_spdylay_frame_count_nv_space)) {
|
test_spdylay_frame_count_nv_space)) {
|
||||||
|
|
|
@ -62,6 +62,13 @@ static void scripted_data_feed_init(scripted_data_feed *df,
|
||||||
df->feedseq[0] = data_length;
|
df->feedseq[0] = data_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t null_send_callback(spdylay_session *session,
|
||||||
|
const uint8_t* data, size_t len, int flags,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t scripted_recv_callback(spdylay_session *session,
|
static ssize_t scripted_recv_callback(spdylay_session *session,
|
||||||
uint8_t* data, size_t len, int flags,
|
uint8_t* data, size_t len, int flags,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
|
@ -293,7 +300,8 @@ void test_spdylay_session_on_syn_reply_received()
|
||||||
user_data.invalid = 0;
|
user_data.invalid = 0;
|
||||||
|
|
||||||
spdylay_session_client_new(&session, &callbacks, &user_data);
|
spdylay_session_client_new(&session, &callbacks, &user_data);
|
||||||
spdylay_session_open_stream(session, 1, SPDYLAY_FLAG_NONE, 0);
|
spdylay_session_open_stream(session, 1, SPDYLAY_FLAG_NONE, 0,
|
||||||
|
SPDYLAY_STREAM_OPENING);
|
||||||
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_FLAG_NONE, 1,
|
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_FLAG_NONE, 1,
|
||||||
dup_nv(nv));
|
dup_nv(nv));
|
||||||
|
|
||||||
|
@ -310,3 +318,53 @@ void test_spdylay_session_on_syn_reply_received()
|
||||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||||
spdylay_session_del(session);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_spdylay_session_send_syn_stream()
|
||||||
|
{
|
||||||
|
spdylay_session *session;
|
||||||
|
spdylay_session_callbacks callbacks = {
|
||||||
|
null_send_callback,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
const char *nv[] = { NULL };
|
||||||
|
spdylay_frame *frame = malloc(sizeof(spdylay_frame));
|
||||||
|
spdylay_stream *stream;
|
||||||
|
|
||||||
|
spdylay_session_client_new(&session, &callbacks, NULL);
|
||||||
|
spdylay_frame_syn_stream_init(&frame->syn_stream, SPDYLAY_FLAG_NONE,
|
||||||
|
0, 0, 3, dup_nv(nv));
|
||||||
|
spdylay_session_add_frame(session, SPDYLAY_SYN_STREAM, frame);
|
||||||
|
CU_ASSERT(0 == spdylay_session_send(session));
|
||||||
|
stream = spdylay_session_get_stream(session, 1);
|
||||||
|
CU_ASSERT(SPDYLAY_STREAM_OPENING == stream->state);
|
||||||
|
|
||||||
|
spdylay_session_del(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_spdylay_session_send_syn_reply()
|
||||||
|
{
|
||||||
|
spdylay_session *session;
|
||||||
|
spdylay_session_callbacks callbacks = {
|
||||||
|
null_send_callback,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
const char *nv[] = { NULL };
|
||||||
|
spdylay_frame *frame = malloc(sizeof(spdylay_frame));
|
||||||
|
spdylay_stream *stream;
|
||||||
|
|
||||||
|
CU_ASSERT(0 == spdylay_session_client_new(&session, &callbacks, NULL));
|
||||||
|
spdylay_session_open_stream(session, 2, SPDYLAY_FLAG_NONE, 3,
|
||||||
|
SPDYLAY_STREAM_OPENING);
|
||||||
|
spdylay_frame_syn_reply_init(&frame->syn_reply, SPDYLAY_FLAG_NONE,
|
||||||
|
2, dup_nv(nv));
|
||||||
|
spdylay_session_add_frame(session, SPDYLAY_SYN_REPLY, frame);
|
||||||
|
CU_ASSERT(0 == spdylay_session_send(session));
|
||||||
|
stream = spdylay_session_get_stream(session, 2);
|
||||||
|
CU_ASSERT(SPDYLAY_STREAM_OPENED == stream->state);
|
||||||
|
|
||||||
|
spdylay_session_del(session);
|
||||||
|
}
|
||||||
|
|
|
@ -30,5 +30,7 @@ void test_spdylay_session_recv_invalid_stream_id();
|
||||||
void test_spdylay_session_add_frame();
|
void test_spdylay_session_add_frame();
|
||||||
void test_spdylay_session_on_syn_stream_received();
|
void test_spdylay_session_on_syn_stream_received();
|
||||||
void test_spdylay_session_on_syn_reply_received();
|
void test_spdylay_session_on_syn_reply_received();
|
||||||
|
void test_spdylay_session_send_syn_stream();
|
||||||
|
void test_spdylay_session_send_syn_reply();
|
||||||
|
|
||||||
#endif // SPDYLAY_SESSION_TEST_H
|
#endif // SPDYLAY_SESSION_TEST_H
|
||||||
|
|
Loading…
Reference in New Issue