Added pri to spdylay_stream. Refactored SYN_STREAM, SYN_REPLY handling when they are received.
This commit is contained in:
parent
6629f35a94
commit
cbb8dd6a8c
|
@ -33,14 +33,19 @@ extern "C" {
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SPDYLAY_ERR_NOMEM = -500,
|
|
||||||
SPDYLAY_ERR_INVALID_ARGUMENT = -501,
|
SPDYLAY_ERR_INVALID_ARGUMENT = -501,
|
||||||
SPDYLAY_ERR_ZLIB = -502,
|
SPDYLAY_ERR_ZLIB = -502,
|
||||||
SPDYLAY_ERR_ZLIB_BUF = -503,
|
SPDYLAY_ERR_ZLIB_BUF = -503,
|
||||||
SPDYLAY_ERR_WOULDBLOCK = -504,
|
SPDYLAY_ERR_WOULDBLOCK = -504,
|
||||||
SPDYLAY_ERR_PROTO = -505,
|
SPDYLAY_ERR_PROTO = -505,
|
||||||
SPDYLAY_ERR_CALLBACK_FAILURE = -505,
|
|
||||||
SPDYLAY_ERR_INVALID_FRAME = -506,
|
SPDYLAY_ERR_INVALID_FRAME = -506,
|
||||||
|
|
||||||
|
/* The errors < SPDYLAY_ERR_FATAL mean that the library is under
|
||||||
|
unexpected condition that it cannot process any further data
|
||||||
|
reliably (e.g., out of memory). */
|
||||||
|
SPDYLAY_ERR_FATAL = -900,
|
||||||
|
SPDYLAY_ERR_NOMEM = -901,
|
||||||
|
SPDYLAY_ERR_CALLBACK_FAILURE = -902,
|
||||||
} spdylay_error;
|
} spdylay_error;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -58,7 +63,9 @@ typedef enum {
|
||||||
} spdylay_frame_type;
|
} spdylay_frame_type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SPDYLAY_FLAG_FIN = 1
|
SPDYLAY_FLAG_NONE = 0,
|
||||||
|
SPDYLAY_FLAG_FIN = 1,
|
||||||
|
SPDYLAY_FLAG_UNIDIRECTIONAL = 2
|
||||||
} spdylay_flag;
|
} spdylay_flag;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -33,6 +33,16 @@
|
||||||
#include "spdylay_stream.h"
|
#include "spdylay_stream.h"
|
||||||
#include "spdylay_helper.h"
|
#include "spdylay_helper.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns spdylay_stream* object whose stream ID is |stream_id|. It
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
int spdylay_outbound_item_compar(const void *lhsx, const void *rhsx)
|
int spdylay_outbound_item_compar(const void *lhsx, const void *rhsx)
|
||||||
{
|
{
|
||||||
const spdylay_outbound_item *lhs, *rhs;
|
const spdylay_outbound_item *lhs, *rhs;
|
||||||
|
@ -146,6 +156,17 @@ int spdylay_session_add_frame(spdylay_session *session,
|
||||||
case SPDYLAY_SYN_STREAM:
|
case SPDYLAY_SYN_STREAM:
|
||||||
item->pri = 4-frame->syn_stream.pri;
|
item->pri = 4-frame->syn_stream.pri;
|
||||||
break;
|
break;
|
||||||
|
case SPDYLAY_RST_STREAM: {
|
||||||
|
spdylay_stream *stream = spdylay_session_get_stream
|
||||||
|
(session, frame->rst_stream.stream_id);
|
||||||
|
if(stream) {
|
||||||
|
stream->state = SPDYLAY_STREAM_CLOSING;
|
||||||
|
item->pri = stream->pri;
|
||||||
|
} else {
|
||||||
|
item->pri = 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
item->pri = 4;
|
item->pri = 4;
|
||||||
};
|
};
|
||||||
|
@ -176,14 +197,15 @@ int spdylay_session_add_rst_stream(spdylay_session *session,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
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);
|
spdylay_stream_init(stream, stream_id, flags, pri);
|
||||||
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);
|
||||||
|
@ -209,7 +231,9 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
}
|
}
|
||||||
printf("packed %d bytes\n", 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.pri);
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
free(framebuf);
|
free(framebuf);
|
||||||
return r;
|
return r;
|
||||||
|
@ -363,6 +387,17 @@ static int spdylay_session_is_new_peer_stream_id(spdylay_session *session,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int spdylay_session_is_my_stream_id(spdylay_session *session,
|
||||||
|
int32_t stream_id)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
if(stream_id == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
r = stream_id % 2;
|
||||||
|
return (session->server && r == 0) || r == 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validates SYN_STREAM frame |frame|. This function returns 0 if it
|
* Validates SYN_STREAM frame |frame|. This function returns 0 if it
|
||||||
* succeeds, or -1.
|
* succeeds, or -1.
|
||||||
|
@ -378,28 +413,6 @@ static int spdylay_session_validate_syn_stream(spdylay_session *session,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static spdylay_stream* spdylay_session_get_stream(spdylay_session *session,
|
|
||||||
int32_t stream_id)
|
|
||||||
{
|
|
||||||
return (spdylay_stream*)spdylay_map_find(&session->streams, stream_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Validates SYN_REPLY frame |frame|. This function returns 0 if it
|
|
||||||
* succeeds, or -1.
|
|
||||||
*/
|
|
||||||
static int spdylay_session_validate_syn_reply(spdylay_session *session,
|
|
||||||
spdylay_syn_reply *frame)
|
|
||||||
{
|
|
||||||
spdylay_stream *stream;
|
|
||||||
stream = spdylay_session_get_stream(session, frame->stream_id);
|
|
||||||
if(stream && stream->state == SPDYLAY_STREAM_OPENING) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int spdylay_session_handle_invalid_ctrl_frame(spdylay_session *session,
|
static int spdylay_session_handle_invalid_ctrl_frame(spdylay_session *session,
|
||||||
int32_t stream_id,
|
int32_t stream_id,
|
||||||
spdylay_frame_type type,
|
spdylay_frame_type type,
|
||||||
|
@ -415,6 +428,56 @@ static int spdylay_session_handle_invalid_ctrl_frame(spdylay_session *session,
|
||||||
session->callbacks.on_invalid_ctrl_recv_callback
|
session->callbacks.on_invalid_ctrl_recv_callback
|
||||||
(session, type, frame, session->user_data);
|
(session, type, frame, session->user_data);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spdylay_session_on_syn_stream_received(spdylay_session *session,
|
||||||
|
spdylay_frame *frame)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
if(spdylay_session_validate_syn_stream(session, &frame->syn_stream) == 0) {
|
||||||
|
r = spdylay_session_open_stream(session, frame->syn_stream.stream_id,
|
||||||
|
frame->syn_stream.hd.flags,
|
||||||
|
frame->syn_stream.pri);
|
||||||
|
if(r == 0) {
|
||||||
|
session->last_recv_stream_id = frame->syn_stream.stream_id;
|
||||||
|
spdylay_session_call_on_ctrl_frame_received(session, SPDYLAY_SYN_STREAM,
|
||||||
|
frame);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r = spdylay_session_handle_invalid_ctrl_frame
|
||||||
|
(session, frame->syn_stream.stream_id, SPDYLAY_SYN_STREAM, frame);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spdylay_session_on_syn_reply_received(spdylay_session *session,
|
||||||
|
spdylay_frame *frame)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
int valid = 0;
|
||||||
|
if(spdylay_session_is_my_stream_id(session, frame->syn_reply.stream_id)) {
|
||||||
|
spdylay_stream *stream = spdylay_session_get_stream
|
||||||
|
(session, frame->syn_reply.stream_id);
|
||||||
|
if(stream) {
|
||||||
|
if(stream->state == SPDYLAY_STREAM_OPENING) {
|
||||||
|
valid = 1;
|
||||||
|
stream->state = SPDYLAY_STREAM_OPENED;
|
||||||
|
spdylay_session_call_on_ctrl_frame_received(session, SPDYLAY_SYN_REPLY,
|
||||||
|
frame);
|
||||||
|
} else if(stream->state == SPDYLAY_STREAM_CLOSING) {
|
||||||
|
/* This is race condition. SPDYLAY_STREAM_CLOSING indicates
|
||||||
|
that we queued RST_STREAM but it has not been sent. It will
|
||||||
|
eventually sent, so we just ignore this frame. */
|
||||||
|
valid = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!valid) {
|
||||||
|
r = spdylay_session_handle_invalid_ctrl_frame
|
||||||
|
(session, frame->syn_reply.stream_id, SPDYLAY_SYN_REPLY, frame);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||||
|
@ -434,13 +497,7 @@ int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||||
session->iframe.len,
|
session->iframe.len,
|
||||||
&session->hd_inflater);
|
&session->hd_inflater);
|
||||||
if(r == 0) {
|
if(r == 0) {
|
||||||
r = spdylay_session_validate_syn_stream(session, &frame.syn_stream);
|
r = spdylay_session_on_syn_stream_received(session, &frame);
|
||||||
if(r == 0) {
|
|
||||||
spdylay_session_call_on_ctrl_frame_received(session, type, &frame);
|
|
||||||
} else {
|
|
||||||
r = spdylay_session_handle_invalid_ctrl_frame
|
|
||||||
(session, frame.syn_stream.stream_id, type, &frame);
|
|
||||||
}
|
|
||||||
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||||
} else {
|
} else {
|
||||||
/* TODO if r indicates mulformed NV pairs (multiple nulls) or
|
/* TODO if r indicates mulformed NV pairs (multiple nulls) or
|
||||||
|
@ -457,13 +514,7 @@ int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||||
session->iframe.len,
|
session->iframe.len,
|
||||||
&session->hd_inflater);
|
&session->hd_inflater);
|
||||||
if(r == 0) {
|
if(r == 0) {
|
||||||
r = spdylay_session_validate_syn_reply(session, &frame.syn_reply);
|
r = spdylay_session_on_syn_reply_received(session, &frame);
|
||||||
if(r == 0) {
|
|
||||||
spdylay_session_call_on_ctrl_frame_received(session, type, &frame);
|
|
||||||
} else {
|
|
||||||
r = spdylay_session_handle_invalid_ctrl_frame
|
|
||||||
(session, frame.syn_reply.stream_id, type, &frame);
|
|
||||||
}
|
|
||||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -471,10 +522,11 @@ int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||||
/* ignore */
|
/* ignore */
|
||||||
printf("Received control frame type %x\n", type);
|
printf("Received control frame type %x\n", type);
|
||||||
}
|
}
|
||||||
if(r != 0) {
|
if(r < SPDYLAY_ERR_FATAL) {
|
||||||
return r;
|
return r;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int spdylay_session_process_data_frame(spdylay_session *session)
|
int spdylay_session_process_data_frame(spdylay_session *session)
|
||||||
|
@ -555,7 +607,11 @@ int spdylay_session_recv(spdylay_session *session)
|
||||||
session->ibuf.mark += readlen;
|
session->ibuf.mark += readlen;
|
||||||
if(session->iframe.len == session->iframe.off) {
|
if(session->iframe.len == session->iframe.off) {
|
||||||
if(spdylay_frame_is_ctrl_frame(session->iframe.headbuf[0])) {
|
if(spdylay_frame_is_ctrl_frame(session->iframe.headbuf[0])) {
|
||||||
spdylay_session_process_ctrl_frame(session);
|
r = spdylay_session_process_ctrl_frame(session);
|
||||||
|
if(r < 0) {
|
||||||
|
/* Fatal error */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
spdylay_session_process_data_frame(session);
|
spdylay_session_process_data_frame(session);
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,8 +101,35 @@ int spdylay_session_add_frame(spdylay_session *session,
|
||||||
int spdylay_session_add_rst_stream(spdylay_session *session,
|
int spdylay_session_add_rst_stream(spdylay_session *session,
|
||||||
int32_t stream_id, uint32_t status_code);
|
int32_t stream_id, uint32_t status_code);
|
||||||
|
|
||||||
int spdylay_session_open_stream(spdylay_session *session, int32_t stream_id);
|
/*
|
||||||
|
* Creates new stream in |session| with stream ID |stream_id|,
|
||||||
|
* priority |pri| and flags |flags|. Currently, |flags| &
|
||||||
|
* SPDYLAY_FLAG_UNIDIRECTIONAL is non-zero, this stream is
|
||||||
|
* unidirectional. |flags| & SPDYLAY_FLAG_FIN is non-zero, the sender
|
||||||
|
* of SYN_STREAM will not send any further data in this stream.
|
||||||
|
*/
|
||||||
|
int spdylay_session_open_stream(spdylay_session *session, int32_t stream_id,
|
||||||
|
uint8_t flags, uint8_t pri);
|
||||||
|
|
||||||
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|.
|
||||||
|
* This function does first
|
||||||
|
* validate received frame and then open stream and call callback
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
int spdylay_session_on_syn_stream_received(spdylay_session *session,
|
||||||
|
spdylay_frame *frame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when SYN_STREAM is received. Received frame is |frame|.
|
||||||
|
* This function does first validate received frame and then open
|
||||||
|
* stream and call callback functions.
|
||||||
|
*/
|
||||||
|
int spdylay_session_on_syn_reply_received(spdylay_session *session,
|
||||||
|
spdylay_frame *frame);
|
||||||
|
|
||||||
|
|
||||||
#endif /* SPDYLAY_SESSION_H */
|
#endif /* SPDYLAY_SESSION_H */
|
||||||
|
|
|
@ -24,10 +24,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)
|
||||||
{
|
{
|
||||||
stream->stream_id = stream_id;
|
stream->stream_id = stream_id;
|
||||||
stream->state = SPDYLAY_STREAM_OPENING;
|
stream->state = SPDYLAY_STREAM_OPENING;
|
||||||
|
stream->flags = flags;
|
||||||
|
stream->pri = pri;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spdylay_stream_free(spdylay_stream *stream)
|
void spdylay_stream_free(spdylay_stream *stream)
|
||||||
|
|
|
@ -31,6 +31,15 @@
|
||||||
|
|
||||||
#include <spdylay/spdylay.h>
|
#include <spdylay/spdylay.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If local peer is stream initiator:
|
||||||
|
* SPDYLAY_STREAM_OPENING : upon sending SYN_STREAM
|
||||||
|
* SPDYLAY_STREAM_OPENED : upon receiving SYN_REPLY
|
||||||
|
*
|
||||||
|
* If remote peer is stream initiator:
|
||||||
|
* SPDYLAY_STREAM_OPENING : upon receiving SYN_STREAM
|
||||||
|
* SPDYLAY_STREAM_OPENED : upon sending SYN_REPLY
|
||||||
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* 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,
|
||||||
|
@ -47,11 +56,14 @@ typedef enum {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t stream_id;
|
int32_t stream_id;
|
||||||
spdylay_stream_state state;
|
spdylay_stream_state state;
|
||||||
/* Use same value in frame */
|
/* Use same value in SYN_STREAM frame */
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
|
/* Use same scheme in SYN_STREAM frame */
|
||||||
|
uint8_t pri;
|
||||||
} 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);
|
||||||
|
|
||||||
void spdylay_stream_free(spdylay_stream *stream);
|
void spdylay_stream_free(spdylay_stream *stream);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,10 @@ int main()
|
||||||
test_spdylay_session_recv_invalid_stream_id) ||
|
test_spdylay_session_recv_invalid_stream_id) ||
|
||||||
!CU_add_test(pSuite, "session_add_frame",
|
!CU_add_test(pSuite, "session_add_frame",
|
||||||
test_spdylay_session_add_frame) ||
|
test_spdylay_session_add_frame) ||
|
||||||
|
!CU_add_test(pSuite, "session_on_syn_stream_received",
|
||||||
|
test_spdylay_session_on_syn_stream_received) ||
|
||||||
|
!CU_add_test(pSuite, "session_on_syn_reply_received",
|
||||||
|
test_spdylay_session_on_syn_reply_received) ||
|
||||||
!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)) {
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "spdylay_session.h"
|
#include "spdylay_session.h"
|
||||||
|
#include "spdylay_stream.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t buf[4096];
|
uint8_t buf[4096];
|
||||||
|
@ -48,7 +49,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
accumulator *acc;
|
accumulator *acc;
|
||||||
scripted_data_feed *df;
|
scripted_data_feed *df;
|
||||||
int flags;
|
int valid, invalid;
|
||||||
} my_user_data;
|
} my_user_data;
|
||||||
|
|
||||||
static void scripted_data_feed_init(scripted_data_feed *df,
|
static void scripted_data_feed_init(scripted_data_feed *df,
|
||||||
|
@ -88,13 +89,22 @@ static ssize_t accumulator_send_callback(spdylay_session *session,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void on_ctrl_recv_callback(spdylay_session *session,
|
||||||
|
spdylay_frame_type type,
|
||||||
|
spdylay_frame *frame,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
my_user_data *ud = (my_user_data*)user_data;
|
||||||
|
++ud->valid;
|
||||||
|
}
|
||||||
|
|
||||||
static void on_invalid_ctrl_recv_callback(spdylay_session *session,
|
static void on_invalid_ctrl_recv_callback(spdylay_session *session,
|
||||||
spdylay_frame_type type,
|
spdylay_frame_type type,
|
||||||
spdylay_frame *frame,
|
spdylay_frame *frame,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
my_user_data *ud = (my_user_data*)user_data;
|
my_user_data *ud = (my_user_data*)user_data;
|
||||||
++ud->flags;
|
++ud->invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char** dup_nv(const char **src)
|
static char** dup_nv(const char **src)
|
||||||
|
@ -128,7 +138,8 @@ void test_spdylay_session_recv()
|
||||||
|
|
||||||
user_data.df = &df;
|
user_data.df = &df;
|
||||||
spdylay_session_client_new(&session, &callbacks, &user_data);
|
spdylay_session_client_new(&session, &callbacks, &user_data);
|
||||||
spdylay_frame_syn_stream_init(&frame.syn_stream, 0, 0, 0, 3, dup_nv(nv));
|
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_FLAG_NONE, 0, 0, 3,
|
||||||
|
dup_nv(nv));
|
||||||
framelen = spdylay_frame_pack_syn_stream(&framedata, &frame.syn_stream,
|
framelen = spdylay_frame_pack_syn_stream(&framedata, &frame.syn_stream,
|
||||||
&session->hd_deflater);
|
&session->hd_deflater);
|
||||||
scripted_data_feed_init(&df, framedata, framelen);
|
scripted_data_feed_init(&df, framedata, framelen);
|
||||||
|
@ -165,7 +176,8 @@ void test_spdylay_session_add_frame()
|
||||||
CU_ASSERT(0 == spdylay_session_client_new(&session, &callbacks, &user_data));
|
CU_ASSERT(0 == spdylay_session_client_new(&session, &callbacks, &user_data));
|
||||||
|
|
||||||
frame = malloc(sizeof(spdylay_frame));
|
frame = malloc(sizeof(spdylay_frame));
|
||||||
spdylay_frame_syn_stream_init(&frame->syn_stream, 0, 0, 0, 3, dup_nv(nv));
|
spdylay_frame_syn_stream_init(&frame->syn_stream, SPDYLAY_FLAG_NONE, 0, 0, 3,
|
||||||
|
dup_nv(nv));
|
||||||
|
|
||||||
CU_ASSERT(0 == spdylay_session_add_frame(session, SPDYLAY_SYN_STREAM, frame));
|
CU_ASSERT(0 == spdylay_session_add_frame(session, SPDYLAY_SYN_STREAM, frame));
|
||||||
CU_ASSERT(0 == spdylay_pq_empty(&session->ob_pq));
|
CU_ASSERT(0 == spdylay_pq_empty(&session->ob_pq));
|
||||||
|
@ -203,9 +215,10 @@ void test_spdylay_session_recv_invalid_stream_id()
|
||||||
spdylay_frame frame;
|
spdylay_frame frame;
|
||||||
|
|
||||||
user_data.df = &df;
|
user_data.df = &df;
|
||||||
user_data.flags = 0;
|
user_data.invalid = 0;
|
||||||
spdylay_session_client_new(&session, &callbacks, &user_data);
|
spdylay_session_client_new(&session, &callbacks, &user_data);
|
||||||
spdylay_frame_syn_stream_init(&frame.syn_stream, 0, 1, 0, 3, dup_nv(nv));
|
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_FLAG_NONE, 1, 0, 3,
|
||||||
|
dup_nv(nv));
|
||||||
framelen = spdylay_frame_pack_syn_stream(&framedata, &frame.syn_stream,
|
framelen = spdylay_frame_pack_syn_stream(&framedata, &frame.syn_stream,
|
||||||
&session->hd_deflater);
|
&session->hd_deflater);
|
||||||
scripted_data_feed_init(&df, framedata, framelen);
|
scripted_data_feed_init(&df, framedata, framelen);
|
||||||
|
@ -213,9 +226,10 @@ void test_spdylay_session_recv_invalid_stream_id()
|
||||||
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||||
|
|
||||||
CU_ASSERT(0 == spdylay_session_recv(session));
|
CU_ASSERT(0 == spdylay_session_recv(session));
|
||||||
CU_ASSERT(1 == user_data.flags);
|
CU_ASSERT(1 == user_data.invalid);
|
||||||
|
|
||||||
spdylay_frame_syn_reply_init(&frame.syn_reply, 0, 100, dup_nv(nv));
|
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_FLAG_NONE, 100,
|
||||||
|
dup_nv(nv));
|
||||||
framelen = spdylay_frame_pack_syn_reply(&framedata, &frame.syn_reply,
|
framelen = spdylay_frame_pack_syn_reply(&framedata, &frame.syn_reply,
|
||||||
&session->hd_deflater);
|
&session->hd_deflater);
|
||||||
scripted_data_feed_init(&df, framedata, framelen);
|
scripted_data_feed_init(&df, framedata, framelen);
|
||||||
|
@ -223,8 +237,74 @@ void test_spdylay_session_recv_invalid_stream_id()
|
||||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||||
|
|
||||||
CU_ASSERT(0 == spdylay_session_recv(session));
|
CU_ASSERT(0 == spdylay_session_recv(session));
|
||||||
CU_ASSERT(2 == user_data.flags);
|
CU_ASSERT(2 == user_data.invalid);
|
||||||
|
|
||||||
spdylay_session_del(session);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_spdylay_session_on_syn_stream_received()
|
||||||
|
{
|
||||||
|
spdylay_session *session;
|
||||||
|
spdylay_session_callbacks callbacks = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
on_ctrl_recv_callback,
|
||||||
|
on_invalid_ctrl_recv_callback
|
||||||
|
};
|
||||||
|
my_user_data user_data;
|
||||||
|
const char *nv[] = { NULL };
|
||||||
|
spdylay_frame frame;
|
||||||
|
user_data.valid = 0;
|
||||||
|
user_data.invalid = 0;
|
||||||
|
|
||||||
|
spdylay_session_client_new(&session, &callbacks, &user_data);
|
||||||
|
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_FLAG_NONE,
|
||||||
|
2, 0, 3, dup_nv(nv));
|
||||||
|
|
||||||
|
CU_ASSERT(0 == spdylay_session_on_syn_stream_received(session, &frame));
|
||||||
|
CU_ASSERT(1 == user_data.valid);
|
||||||
|
CU_ASSERT(SPDYLAY_STREAM_OPENING ==
|
||||||
|
((spdylay_stream*)spdylay_map_find(&session->streams, 2))->state);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == spdylay_session_on_syn_stream_received(session, &frame));
|
||||||
|
CU_ASSERT(1 == user_data.invalid);
|
||||||
|
CU_ASSERT(SPDYLAY_STREAM_CLOSING ==
|
||||||
|
((spdylay_stream*)spdylay_map_find(&session->streams, 2))->state);
|
||||||
|
|
||||||
|
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||||
|
spdylay_session_del(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_spdylay_session_on_syn_reply_received()
|
||||||
|
{
|
||||||
|
spdylay_session *session;
|
||||||
|
spdylay_session_callbacks callbacks = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
on_ctrl_recv_callback,
|
||||||
|
on_invalid_ctrl_recv_callback
|
||||||
|
};
|
||||||
|
my_user_data user_data;
|
||||||
|
const char *nv[] = { NULL };
|
||||||
|
spdylay_frame frame;
|
||||||
|
user_data.valid = 0;
|
||||||
|
user_data.invalid = 0;
|
||||||
|
|
||||||
|
spdylay_session_client_new(&session, &callbacks, &user_data);
|
||||||
|
spdylay_session_open_stream(session, 1, SPDYLAY_FLAG_NONE, 0);
|
||||||
|
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_FLAG_NONE, 1,
|
||||||
|
dup_nv(nv));
|
||||||
|
|
||||||
|
CU_ASSERT(0 == spdylay_session_on_syn_reply_received(session, &frame));
|
||||||
|
CU_ASSERT(1 == user_data.valid);
|
||||||
|
CU_ASSERT(SPDYLAY_STREAM_OPENED ==
|
||||||
|
((spdylay_stream*)spdylay_map_find(&session->streams, 1))->state);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == spdylay_session_on_syn_reply_received(session, &frame));
|
||||||
|
CU_ASSERT(1 == user_data.invalid);
|
||||||
|
CU_ASSERT(SPDYLAY_STREAM_CLOSING ==
|
||||||
|
((spdylay_stream*)spdylay_map_find(&session->streams, 1))->state);
|
||||||
|
|
||||||
|
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||||
|
spdylay_session_del(session);
|
||||||
|
}
|
||||||
|
|
|
@ -28,5 +28,7 @@
|
||||||
void test_spdylay_session_recv();
|
void test_spdylay_session_recv();
|
||||||
void test_spdylay_session_recv_invalid_stream_id();
|
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_reply_received();
|
||||||
|
|
||||||
#endif // SPDYLAY_SESSION_TEST_H
|
#endif // SPDYLAY_SESSION_TEST_H
|
||||||
|
|
Loading…
Reference in New Issue