Hide spdylay_data from public API.

The spdylay_data contains full of implementation details and is not
used in public API. It should be hidden.
The spdylay_frame union now only contains the control frame.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-03-29 23:59:51 +09:00
parent 67e83e09a6
commit ba56ed6c48
8 changed files with 572 additions and 497 deletions

View File

@ -176,7 +176,7 @@ typedef enum {
/** /**
* @enum * @enum
* The frame types in SPDY protocol. * The control frame types in SPDY protocol.
*/ */
typedef enum { typedef enum {
/** /**
@ -214,11 +214,7 @@ typedef enum {
/** /**
* The WINDOW_UPDATE control frame. This first appeared in SPDY/3. * The WINDOW_UPDATE control frame. This first appeared in SPDY/3.
*/ */
SPDYLAY_WINDOW_UPDATE = 9, SPDYLAY_WINDOW_UPDATE = 9
/**
* The DATA frame.
*/
SPDYLAY_DATA = 100
} spdylay_frame_type; } spdylay_frame_type;
/** /**
@ -639,6 +635,19 @@ typedef struct {
int32_t delta_window_size; int32_t delta_window_size;
} spdylay_window_update; } spdylay_window_update;
/**
* @struct
*
* Convenient structure to inspect control frame header. It is useful
* to get the frame type.
*/
typedef struct {
/**
* The control frame header.
*/
spdylay_ctrl_hd hd;
} spdylay_ctrl_frame;
/** /**
* @union * @union
* *
@ -695,37 +704,17 @@ typedef struct {
spdylay_data_source_read_callback read_callback; spdylay_data_source_read_callback read_callback;
} spdylay_data_provider; } spdylay_data_provider;
/**
* @struct
* The DATA frame. It has the following members:
*/
typedef struct {
/**
* The stream ID.
*/
int32_t stream_id;
/**
* The DATA frame flags. See :type:`spdylay_data_flag`.
*/
uint8_t flags;
/**
* The flag to indicate whether EOF was reached or not. Initially
* |eof| is 0. It becomes 1 after all data were read.
*/
uint8_t eof;
/**
* The data to be sent for this DATA frame.
*/
spdylay_data_provider data_prd;
} spdylay_data;
/** /**
* @union * @union
* *
* This union includes all control frames and DATA frame to pass them * This union includes all control frames to pass them
* to various function calls as spdylay_frame type. * to various function calls as spdylay_frame type.
*/ */
typedef union { typedef union {
/**
* Convenient structure to inspect control frame header.
*/
spdylay_ctrl_frame common;
/** /**
* The SYN_STREAM control frame. * The SYN_STREAM control frame.
*/ */
@ -758,10 +747,6 @@ typedef union {
* The WINDOW_UPDATE control frame. * The WINDOW_UPDATE control frame.
*/ */
spdylay_window_update window_update; spdylay_window_update window_update;
/**
* The DATA frame.
*/
spdylay_data data;
} spdylay_frame; } spdylay_frame;
/** /**

View File

@ -52,6 +52,38 @@
(LEN_SIZE == 2 ? \ (LEN_SIZE == 2 ? \
spdylay_put_uint16be(OUT, VAL) : spdylay_put_uint32be(OUT, VAL)) spdylay_put_uint16be(OUT, VAL) : spdylay_put_uint32be(OUT, VAL))
/* Category of SPDY frames. */
typedef enum {
/* Control frame */
SPDYLAY_CTRL,
/* DATA frame */
SPDYLAY_DATA
} spdylay_frame_category;
/**
* @struct
* The DATA frame. It has the following members:
*/
typedef struct {
/**
* The stream ID.
*/
int32_t stream_id;
/**
* The DATA frame flags. See :type:`spdylay_data_flag`.
*/
uint8_t flags;
/**
* The flag to indicate whether EOF was reached or not. Initially
* |eof| is 0. It becomes 1 after all data were read.
*/
uint8_t eof;
/**
* The data to be sent for this DATA frame.
*/
spdylay_data_provider data_prd;
} spdylay_data;
/* /*
* Returns the number of bytes in length of name/value pair for the * Returns the number of bytes in length of name/value pair for the
* given protocol version |version|. If |version| is not supported, * given protocol version |version|. If |version| is not supported,

View File

@ -24,45 +24,57 @@
*/ */
#include "spdylay_outbound_item.h" #include "spdylay_outbound_item.h"
#include <assert.h>
void spdylay_outbound_item_free(spdylay_outbound_item *item) void spdylay_outbound_item_free(spdylay_outbound_item *item)
{ {
if(item == NULL) { if(item == NULL) {
return; return;
} }
switch(item->frame_type) { if(item->frame_cat == SPDYLAY_CTRL) {
spdylay_frame_type frame_type;
spdylay_frame *frame;
frame_type = spdylay_outbound_item_get_ctrl_frame_type(item);
frame = spdylay_outbound_item_get_ctrl_frame(item);
switch(frame_type) {
case SPDYLAY_SYN_STREAM: case SPDYLAY_SYN_STREAM:
spdylay_frame_syn_stream_free(&item->frame->syn_stream); spdylay_frame_syn_stream_free(&frame->syn_stream);
free(((spdylay_syn_stream_aux_data*)item->aux_data)->data_prd); free(((spdylay_syn_stream_aux_data*)item->aux_data)->data_prd);
break; break;
case SPDYLAY_SYN_REPLY: case SPDYLAY_SYN_REPLY:
spdylay_frame_syn_reply_free(&item->frame->syn_reply); spdylay_frame_syn_reply_free(&frame->syn_reply);
break; break;
case SPDYLAY_RST_STREAM: case SPDYLAY_RST_STREAM:
spdylay_frame_rst_stream_free(&item->frame->rst_stream); spdylay_frame_rst_stream_free(&frame->rst_stream);
break; break;
case SPDYLAY_SETTINGS: case SPDYLAY_SETTINGS:
spdylay_frame_settings_free(&item->frame->settings); spdylay_frame_settings_free(&frame->settings);
break; break;
case SPDYLAY_NOOP: case SPDYLAY_NOOP:
/* We don't have any public API to add NOOP, so here is /* We don't have any public API to add NOOP, so here is
unreachable. */ unreachable. */
abort(); abort();
case SPDYLAY_PING: case SPDYLAY_PING:
spdylay_frame_ping_free(&item->frame->ping); spdylay_frame_ping_free(&frame->ping);
break; break;
case SPDYLAY_GOAWAY: case SPDYLAY_GOAWAY:
spdylay_frame_goaway_free(&item->frame->goaway); spdylay_frame_goaway_free(&frame->goaway);
break; break;
case SPDYLAY_HEADERS: case SPDYLAY_HEADERS:
spdylay_frame_headers_free(&item->frame->headers); spdylay_frame_headers_free(&frame->headers);
break; break;
case SPDYLAY_WINDOW_UPDATE: case SPDYLAY_WINDOW_UPDATE:
spdylay_frame_window_update_free(&item->frame->window_update); spdylay_frame_window_update_free(&frame->window_update);
break;
case SPDYLAY_DATA:
spdylay_frame_data_free(&item->frame->data);
break; break;
} }
} else if(item->frame_cat == SPDYLAY_DATA) {
spdylay_data *data_frame;
data_frame = spdylay_outbound_item_get_data_frame(item);
spdylay_frame_data_free(data_frame);
} else {
/* Unreachable */
assert(0);
}
free(item->frame); free(item->frame);
free(item->aux_data); free(item->aux_data);
} }

View File

@ -38,8 +38,10 @@ typedef struct {
} spdylay_syn_stream_aux_data; } spdylay_syn_stream_aux_data;
typedef struct { typedef struct {
spdylay_frame_type frame_type; /* Type of |frame|. SPDYLAY_CTRL: spdylay_frame*, SPDYLAY_DATA:
spdylay_frame *frame; spdylay_data* */
spdylay_frame_category frame_cat;
void *frame;
void *aux_data; void *aux_data;
int pri; int pri;
int64_t seq; int64_t seq;
@ -51,4 +53,10 @@ typedef struct {
*/ */
void spdylay_outbound_item_free(spdylay_outbound_item *item); void spdylay_outbound_item_free(spdylay_outbound_item *item);
/* Macros to cast spdylay_outbound_item.frame to the proper type. */
#define spdylay_outbound_item_get_ctrl_frame(ITEM) ((spdylay_frame*)ITEM->frame)
#define spdylay_outbound_item_get_ctrl_frame_type(ITEM) \
(((spdylay_frame*)ITEM->frame)->common.hd.type)
#define spdylay_outbound_item_get_data_frame(ITEM) ((spdylay_data*)ITEM->frame)
#endif /* SPDYLAY_OUTBOUND_ITEM_H */ #endif /* SPDYLAY_OUTBOUND_ITEM_H */

View File

@ -305,8 +305,8 @@ void spdylay_session_del(spdylay_session *session)
} }
int spdylay_session_add_frame(spdylay_session *session, int spdylay_session_add_frame(spdylay_session *session,
spdylay_frame_type frame_type, spdylay_frame_category frame_cat,
spdylay_frame *frame, void *abs_frame,
void *aux_data) void *aux_data)
{ {
int r; int r;
@ -315,12 +315,15 @@ int spdylay_session_add_frame(spdylay_session *session,
if(item == NULL) { if(item == NULL) {
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
} }
item->frame_type = frame_type; item->frame_cat = frame_cat;
item->frame = frame; item->frame = abs_frame;
item->aux_data = aux_data; item->aux_data = aux_data;
item->seq = session->next_seq++; item->seq = session->next_seq++;
/* Set priority lowest at the moment. */ /* Set priority lowest at the moment. */
item->pri = spdylay_session_get_pri_lowest(session); item->pri = spdylay_session_get_pri_lowest(session);
if(frame_cat == SPDYLAY_CTRL) {
spdylay_frame *frame = (spdylay_frame*)abs_frame;
spdylay_frame_type frame_type = frame->common.hd.type;
switch(frame_type) { switch(frame_type) {
case SPDYLAY_SYN_STREAM: case SPDYLAY_SYN_STREAM:
item->pri = frame->syn_stream.pri; item->pri = frame->syn_stream.pri;
@ -349,7 +352,7 @@ int spdylay_session_add_frame(spdylay_session *session,
case SPDYLAY_NOOP: case SPDYLAY_NOOP:
/* We don't have any public API to add NOOP, so here is /* We don't have any public API to add NOOP, so here is
unreachable. */ unreachable. */
abort(); assert(0);
case SPDYLAY_PING: case SPDYLAY_PING:
/* Ping has "height" priority. Give it -1. */ /* Ping has "height" priority. Give it -1. */
item->pri = -1; item->pri = -1;
@ -373,20 +376,24 @@ int spdylay_session_add_frame(spdylay_session *session,
} }
break; break;
} }
case SPDYLAY_DATA: {
spdylay_stream *stream = spdylay_session_get_stream
(session, frame->data.stream_id);
if(stream) {
item->pri = stream->pri;
} }
break;
}
};
if(frame_type == SPDYLAY_SYN_STREAM) { if(frame_type == SPDYLAY_SYN_STREAM) {
r = spdylay_pq_push(&session->ob_ss_pq, item); r = spdylay_pq_push(&session->ob_ss_pq, item);
} else { } else {
r = spdylay_pq_push(&session->ob_pq, item); r = spdylay_pq_push(&session->ob_pq, item);
} }
} else if(frame_cat == SPDYLAY_DATA) {
spdylay_data *data_frame = (spdylay_data*)abs_frame;
spdylay_stream *stream = spdylay_session_get_stream(session,
data_frame->stream_id);
if(stream) {
item->pri = stream->pri;
}
r = spdylay_pq_push(&session->ob_pq, item);
} else {
/* Unreachable */
assert(0);
}
if(r != 0) { if(r != 0) {
free(item); free(item);
return r; return r;
@ -405,7 +412,7 @@ int spdylay_session_add_rst_stream(spdylay_session *session,
} }
spdylay_frame_rst_stream_init(&frame->rst_stream, session->version, spdylay_frame_rst_stream_init(&frame->rst_stream, session->version,
stream_id, status_code); stream_id, status_code);
r = spdylay_session_add_frame(session, SPDYLAY_RST_STREAM, frame, NULL); r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
if(r != 0) { if(r != 0) {
spdylay_frame_rst_stream_free(&frame->rst_stream); spdylay_frame_rst_stream_free(&frame->rst_stream);
free(frame); free(frame);
@ -729,41 +736,46 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
spdylay_outbound_item *item) spdylay_outbound_item *item)
{ {
ssize_t framebuflen; ssize_t framebuflen;
switch(item->frame_type) { if(item->frame_cat == SPDYLAY_CTRL) {
spdylay_frame *frame;
spdylay_frame_type frame_type;
frame = spdylay_outbound_item_get_ctrl_frame(item);
frame_type = spdylay_outbound_item_get_ctrl_frame_type(item);
switch(frame_type) {
case SPDYLAY_SYN_STREAM: { case SPDYLAY_SYN_STREAM: {
int32_t stream_id; int32_t stream_id;
spdylay_syn_stream_aux_data *aux_data; spdylay_syn_stream_aux_data *aux_data;
int r; int r;
r = spdylay_session_predicate_syn_stream_send(session, r = spdylay_session_predicate_syn_stream_send(session,
&item->frame->syn_stream); &frame->syn_stream);
if(r != 0) { if(r != 0) {
return r; return r;
} }
stream_id = session->next_stream_id; stream_id = session->next_stream_id;
item->frame->syn_stream.stream_id = stream_id; frame->syn_stream.stream_id = stream_id;
session->next_stream_id += 2; session->next_stream_id += 2;
if(session->version == SPDYLAY_PROTO_SPDY2) { if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_3to2(item->frame->syn_stream.nv); spdylay_frame_nv_3to2(frame->syn_stream.nv);
spdylay_frame_nv_sort(item->frame->syn_stream.nv); spdylay_frame_nv_sort(frame->syn_stream.nv);
} }
framebuflen = spdylay_frame_pack_syn_stream(&session->aob.framebuf, framebuflen = spdylay_frame_pack_syn_stream(&session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
&session->nvbuf, &session->nvbuf,
&session->nvbuflen, &session->nvbuflen,
&item->frame->syn_stream, &frame->syn_stream,
&session->hd_deflater); &session->hd_deflater);
if(session->version == SPDYLAY_PROTO_SPDY2) { if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_2to3(item->frame->syn_stream.nv); spdylay_frame_nv_2to3(frame->syn_stream.nv);
spdylay_frame_nv_sort(item->frame->syn_stream.nv); spdylay_frame_nv_sort(frame->syn_stream.nv);
} }
if(framebuflen < 0) { if(framebuflen < 0) {
return framebuflen; return framebuflen;
} }
aux_data = (spdylay_syn_stream_aux_data*)item->aux_data; aux_data = (spdylay_syn_stream_aux_data*)item->aux_data;
if(spdylay_session_open_stream(session, stream_id, if(spdylay_session_open_stream(session, stream_id,
item->frame->syn_stream.hd.flags, frame->syn_stream.hd.flags,
item->frame->syn_stream.pri, frame->syn_stream.pri,
SPDYLAY_STREAM_INITIAL, SPDYLAY_STREAM_INITIAL,
aux_data->stream_user_data) == NULL) { aux_data->stream_user_data) == NULL) {
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
@ -772,24 +784,24 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
} }
case SPDYLAY_SYN_REPLY: { case SPDYLAY_SYN_REPLY: {
int r; int r;
r = spdylay_session_predicate_syn_reply_send r = spdylay_session_predicate_syn_reply_send(session,
(session, item->frame->syn_reply.stream_id); frame->syn_reply.stream_id);
if(r != 0) { if(r != 0) {
return r; return r;
} }
if(session->version == SPDYLAY_PROTO_SPDY2) { if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_3to2(item->frame->syn_reply.nv); spdylay_frame_nv_3to2(frame->syn_reply.nv);
spdylay_frame_nv_sort(item->frame->syn_reply.nv); spdylay_frame_nv_sort(frame->syn_reply.nv);
} }
framebuflen = spdylay_frame_pack_syn_reply(&session->aob.framebuf, framebuflen = spdylay_frame_pack_syn_reply(&session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
&session->nvbuf, &session->nvbuf,
&session->nvbuflen, &session->nvbuflen,
&item->frame->syn_reply, &frame->syn_reply,
&session->hd_deflater); &session->hd_deflater);
if(session->version == SPDYLAY_PROTO_SPDY2) { if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_2to3(item->frame->syn_reply.nv); spdylay_frame_nv_2to3(frame->syn_reply.nv);
spdylay_frame_nv_sort(item->frame->syn_reply.nv); spdylay_frame_nv_sort(frame->syn_reply.nv);
} }
if(framebuflen < 0) { if(framebuflen < 0) {
return framebuflen; return framebuflen;
@ -799,7 +811,7 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
case SPDYLAY_RST_STREAM: case SPDYLAY_RST_STREAM:
framebuflen = spdylay_frame_pack_rst_stream(&session->aob.framebuf, framebuflen = spdylay_frame_pack_rst_stream(&session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
&item->frame->rst_stream); &frame->rst_stream);
if(framebuflen < 0) { if(framebuflen < 0) {
return framebuflen; return framebuflen;
} }
@ -807,7 +819,7 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
case SPDYLAY_SETTINGS: case SPDYLAY_SETTINGS:
framebuflen = spdylay_frame_pack_settings(&session->aob.framebuf, framebuflen = spdylay_frame_pack_settings(&session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
&item->frame->settings); &frame->settings);
if(framebuflen < 0) { if(framebuflen < 0) {
return framebuflen; return framebuflen;
} }
@ -815,11 +827,11 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
case SPDYLAY_NOOP: case SPDYLAY_NOOP:
/* We don't have any public API to add NOOP, so here is /* We don't have any public API to add NOOP, so here is
unreachable. */ unreachable. */
abort(); assert(0);
case SPDYLAY_PING: case SPDYLAY_PING:
framebuflen = spdylay_frame_pack_ping(&session->aob.framebuf, framebuflen = spdylay_frame_pack_ping(&session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
&item->frame->ping); &frame->ping);
if(framebuflen < 0) { if(framebuflen < 0) {
return framebuflen; return framebuflen;
} }
@ -827,23 +839,23 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
case SPDYLAY_HEADERS: { case SPDYLAY_HEADERS: {
int r; int r;
r = spdylay_session_predicate_headers_send(session, r = spdylay_session_predicate_headers_send(session,
item->frame->headers.stream_id); frame->headers.stream_id);
if(r != 0) { if(r != 0) {
return r; return r;
} }
if(session->version == SPDYLAY_PROTO_SPDY2) { if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_3to2(item->frame->headers.nv); spdylay_frame_nv_3to2(frame->headers.nv);
spdylay_frame_nv_sort(item->frame->headers.nv); spdylay_frame_nv_sort(frame->headers.nv);
} }
framebuflen = spdylay_frame_pack_headers(&session->aob.framebuf, framebuflen = spdylay_frame_pack_headers(&session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
&session->nvbuf, &session->nvbuf,
&session->nvbuflen, &session->nvbuflen,
&item->frame->headers, &frame->headers,
&session->hd_deflater); &session->hd_deflater);
if(session->version == SPDYLAY_PROTO_SPDY2) { if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_2to3(item->frame->headers.nv); spdylay_frame_nv_2to3(frame->headers.nv);
spdylay_frame_nv_sort(item->frame->headers.nv); spdylay_frame_nv_sort(frame->headers.nv);
} }
if(framebuflen < 0) { if(framebuflen < 0) {
return framebuflen; return framebuflen;
@ -853,13 +865,13 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
case SPDYLAY_WINDOW_UPDATE: { case SPDYLAY_WINDOW_UPDATE: {
int r; int r;
r = spdylay_session_predicate_window_update_send r = spdylay_session_predicate_window_update_send
(session, item->frame->window_update.stream_id); (session, frame->window_update.stream_id);
if(r != 0) { if(r != 0) {
return r; return r;
} }
framebuflen = spdylay_frame_pack_window_update(&session->aob.framebuf, framebuflen = spdylay_frame_pack_window_update(&session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
&item->frame->window_update); &frame->window_update);
if(framebuflen < 0) { if(framebuflen < 0) {
return framebuflen; return framebuflen;
} }
@ -875,21 +887,25 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
} }
framebuflen = spdylay_frame_pack_goaway(&session->aob.framebuf, framebuflen = spdylay_frame_pack_goaway(&session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
&item->frame->goaway); &frame->goaway);
if(framebuflen < 0) { if(framebuflen < 0) {
return framebuflen; return framebuflen;
} }
break; break;
case SPDYLAY_DATA: { default:
framebuflen = SPDYLAY_ERR_INVALID_ARGUMENT;
}
} else if(item->frame_cat == SPDYLAY_DATA) {
size_t next_readmax; size_t next_readmax;
spdylay_stream *stream; spdylay_stream *stream;
spdylay_data *data_frame;
int r; int r;
r = spdylay_session_predicate_data_send(session, data_frame = spdylay_outbound_item_get_data_frame(item);
item->frame->data.stream_id); r = spdylay_session_predicate_data_send(session, data_frame->stream_id);
if(r != 0) { if(r != 0) {
return r; return r;
} }
stream = spdylay_session_get_stream(session, item->frame->data.stream_id); stream = spdylay_session_get_stream(session, data_frame->stream_id);
/* Assuming stream is not NULL */ /* Assuming stream is not NULL */
assert(stream); assert(stream);
next_readmax = spdylay_session_next_data_read(session, stream); next_readmax = spdylay_session_next_data_read(session, stream);
@ -901,17 +917,16 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
&session->aob.framebuf, &session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
next_readmax, next_readmax,
&item->frame->data); data_frame);
if(framebuflen == SPDYLAY_ERR_DEFERRED) { if(framebuflen == SPDYLAY_ERR_DEFERRED) {
spdylay_stream_defer_data(stream, item, SPDYLAY_DEFERRED_NONE); spdylay_stream_defer_data(stream, item, SPDYLAY_DEFERRED_NONE);
return SPDYLAY_ERR_DEFERRED; return SPDYLAY_ERR_DEFERRED;
} else if(framebuflen < 0) { } else if(framebuflen < 0) {
return framebuflen; return framebuflen;
} }
break; } else {
} /* Unreachable */
default: assert(0);
framebuflen = SPDYLAY_ERR_INVALID_ARGUMENT;
} }
return framebuflen; return framebuflen;
} }
@ -1013,23 +1028,16 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
{ {
/* TODO handle FIN flag. */ /* TODO handle FIN flag. */
spdylay_outbound_item *item = session->aob.item; spdylay_outbound_item *item = session->aob.item;
spdylay_frame *frame = session->aob.item->frame; if(item->frame_cat == SPDYLAY_CTRL) {
spdylay_frame_type type = session->aob.item->frame_type; spdylay_frame *frame;
if(type == SPDYLAY_DATA) { spdylay_frame_type type;
if(session->callbacks.on_data_send_callback) { frame = spdylay_outbound_item_get_ctrl_frame(session->aob.item);
session->callbacks.on_data_send_callback type = spdylay_outbound_item_get_ctrl_frame_type(session->aob.item);
(session, if(session->callbacks.on_ctrl_send_callback &&
frame->data.eof ? frame->data.flags : type != SPDYLAY_WINDOW_UPDATE) {
(frame->data.flags & (~SPDYLAY_DATA_FLAG_FIN)),
frame->data.stream_id,
session->aob.framebuflen-SPDYLAY_HEAD_LEN, session->user_data);
}
} else {
if(session->callbacks.on_ctrl_send_callback) {
session->callbacks.on_ctrl_send_callback session->callbacks.on_ctrl_send_callback
(session, type, frame, session->user_data); (session, type, frame, session->user_data);
} }
}
switch(type) { switch(type) {
case SPDYLAY_SYN_STREAM: { case SPDYLAY_SYN_STREAM: {
spdylay_stream *stream = spdylay_stream *stream =
@ -1089,9 +1097,11 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
} }
case SPDYLAY_RST_STREAM: case SPDYLAY_RST_STREAM:
if(!session->server && if(!session->server &&
spdylay_session_is_my_stream_id(session, frame->rst_stream.stream_id) && spdylay_session_is_my_stream_id(session,
frame->rst_stream.stream_id) &&
frame->rst_stream.status_code == SPDYLAY_CANCEL) { frame->rst_stream.status_code == SPDYLAY_CANCEL) {
spdylay_session_close_pushed_streams(session, frame->rst_stream.stream_id, spdylay_session_close_pushed_streams(session,
frame->rst_stream.stream_id,
frame->rst_stream.status_code); frame->rst_stream.status_code);
} }
spdylay_session_close_stream(session, frame->rst_stream.stream_id, spdylay_session_close_stream(session, frame->rst_stream.stream_id,
@ -1103,7 +1113,7 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
case SPDYLAY_NOOP: case SPDYLAY_NOOP:
/* We don't have any public API to add NOOP, so here is /* We don't have any public API to add NOOP, so here is
unreachable. */ unreachable. */
abort(); assert(0);
case SPDYLAY_PING: case SPDYLAY_PING:
/* We record the time now and show application code RTT when /* We record the time now and show application code RTT when
reply PING is received. */ reply PING is received. */
@ -1125,24 +1135,33 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
} }
case SPDYLAY_WINDOW_UPDATE: case SPDYLAY_WINDOW_UPDATE:
break; break;
case SPDYLAY_DATA: }
if(frame->data.eof && (frame->data.flags & SPDYLAY_DATA_FLAG_FIN)) { spdylay_active_outbound_item_reset(&session->aob);
} else if(item->frame_cat == SPDYLAY_DATA) {
int r;
spdylay_data *data_frame;
data_frame = spdylay_outbound_item_get_data_frame(session->aob.item);
if(session->callbacks.on_data_send_callback) {
session->callbacks.on_data_send_callback
(session,
data_frame->eof ? data_frame->flags :
(data_frame->flags & (~SPDYLAY_DATA_FLAG_FIN)),
data_frame->stream_id,
session->aob.framebuflen-SPDYLAY_HEAD_LEN, session->user_data);
}
if(data_frame->eof && (data_frame->flags & SPDYLAY_DATA_FLAG_FIN)) {
spdylay_stream *stream = spdylay_stream *stream =
spdylay_session_get_stream(session, frame->data.stream_id); spdylay_session_get_stream(session, data_frame->stream_id);
if(stream) { if(stream) {
spdylay_stream_shutdown(stream, SPDYLAY_SHUT_WR); spdylay_stream_shutdown(stream, SPDYLAY_SHUT_WR);
spdylay_session_close_stream_if_shut_rdwr(session, stream); spdylay_session_close_stream_if_shut_rdwr(session, stream);
} }
} }
break;
};
if(type == SPDYLAY_DATA) {
int r;
/* If session is closed or RST_STREAM was queued, we won't send /* If session is closed or RST_STREAM was queued, we won't send
further data. */ further data. */
if(frame->data.eof || if(data_frame->eof ||
spdylay_session_predicate_data_send(session, spdylay_session_predicate_data_send(session,
frame->data.stream_id) != 0) { data_frame->stream_id) != 0) {
spdylay_active_outbound_item_reset(&session->aob); spdylay_active_outbound_item_reset(&session->aob);
} else { } else {
spdylay_outbound_item* item = spdylay_session_get_next_ob_item(session); spdylay_outbound_item* item = spdylay_session_get_next_ob_item(session);
@ -1152,7 +1171,7 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
if(item == NULL || session->aob.item->pri <= item->pri) { if(item == NULL || session->aob.item->pri <= item->pri) {
size_t next_readmax; size_t next_readmax;
spdylay_stream *stream; spdylay_stream *stream;
stream = spdylay_session_get_stream(session, frame->data.stream_id); stream = spdylay_session_get_stream(session, data_frame->stream_id);
/* Assuming stream is not NULL */ /* Assuming stream is not NULL */
assert(stream); assert(stream);
next_readmax = spdylay_session_next_data_read(session, stream); next_readmax = spdylay_session_next_data_read(session, stream);
@ -1167,7 +1186,7 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
&session->aob.framebuf, &session->aob.framebuf,
&session->aob.framebufmax, &session->aob.framebufmax,
next_readmax, next_readmax,
&frame->data); data_frame);
if(r == SPDYLAY_ERR_DEFERRED) { if(r == SPDYLAY_ERR_DEFERRED) {
spdylay_stream_defer_data(stream, session->aob.item, spdylay_stream_defer_data(stream, session->aob.item,
SPDYLAY_DEFERRED_NONE); SPDYLAY_DEFERRED_NONE);
@ -1196,7 +1215,8 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
} }
} }
} else { } else {
spdylay_active_outbound_item_reset(&session->aob); /* Unreachable */
assert(0);
} }
return 0; return 0;
} }
@ -1219,18 +1239,23 @@ int spdylay_session_send(spdylay_session *session)
if(framebuflen == SPDYLAY_ERR_DEFERRED) { if(framebuflen == SPDYLAY_ERR_DEFERRED) {
continue; continue;
} else if(framebuflen < 0) { } else if(framebuflen < 0) {
if(item->frame_cat == SPDYLAY_CTRL &&
session->callbacks.on_ctrl_not_send_callback &&
spdylay_is_non_fatal(framebuflen)) {
/* The library is responsible for the transmission of /* The library is responsible for the transmission of
WINDOW_UPDATE frame, so we don't call error callback for WINDOW_UPDATE frame, so we don't call error callback for
it. */ it. */
if(session->callbacks.on_ctrl_not_send_callback && spdylay_frame_type frame_type;
spdylay_is_non_fatal(framebuflen) && frame_type = spdylay_outbound_item_get_ctrl_frame_type(item);
item->frame_type != SPDYLAY_WINDOW_UPDATE) { if(frame_type != SPDYLAY_WINDOW_UPDATE) {
session->callbacks.on_ctrl_not_send_callback(session, session->callbacks.on_ctrl_not_send_callback
item->frame_type, (session,
item->frame, frame_type,
spdylay_outbound_item_get_ctrl_frame(item),
framebuflen, framebuflen,
session->user_data); session->user_data);
} }
}
spdylay_outbound_item_free(item); spdylay_outbound_item_free(item);
free(item); free(item);
if(spdylay_is_fatal(framebuflen)) { if(spdylay_is_fatal(framebuflen)) {
@ -1242,10 +1267,17 @@ int spdylay_session_send(spdylay_session *session)
session->aob.item = item; session->aob.item = item;
session->aob.framebuflen = framebuflen; session->aob.framebuflen = framebuflen;
/* Call before_send callback */ /* Call before_send callback */
if(item->frame_type != SPDYLAY_DATA && if(item->frame_cat == SPDYLAY_CTRL &&
session->callbacks.before_ctrl_send_callback) { session->callbacks.before_ctrl_send_callback) {
spdylay_frame_type frame_type;
frame_type = spdylay_outbound_item_get_ctrl_frame_type(item);
if(frame_type != SPDYLAY_WINDOW_UPDATE) {
session->callbacks.before_ctrl_send_callback session->callbacks.before_ctrl_send_callback
(session, item->frame_type, item->frame, session->user_data); (session,
frame_type,
spdylay_outbound_item_get_ctrl_frame(item),
session->user_data);
}
} }
} }
data = session->aob.framebuf + session->aob.framebufoff; data = session->aob.framebuf + session->aob.framebufoff;
@ -1261,11 +1293,11 @@ int spdylay_session_send(spdylay_session *session)
} else { } else {
session->aob.framebufoff += sentlen; session->aob.framebufoff += sentlen;
if(session->flow_control && if(session->flow_control &&
session->aob.item->frame_type == SPDYLAY_DATA) { session->aob.item->frame_cat == SPDYLAY_DATA) {
spdylay_frame *frame; spdylay_data *frame;
spdylay_stream *stream; spdylay_stream *stream;
frame = session->aob.item->frame; frame = spdylay_outbound_item_get_data_frame(session->aob.item);
stream = spdylay_session_get_stream(session, frame->data.stream_id); stream = spdylay_session_get_stream(session, frame->stream_id);
if(stream) { if(stream) {
stream->window_size -= spdylay_get_uint32(&session->aob.framebuf[4]); stream->window_size -= spdylay_get_uint32(&session->aob.framebuf[4]);
} }
@ -1753,8 +1785,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
int r = 0; int r = 0;
uint16_t type; uint16_t type;
spdylay_frame frame; spdylay_frame frame;
memcpy(&type, &session->iframe.headbuf[2], sizeof(uint16_t)); type = spdylay_get_uint16(&session->iframe.headbuf[2]);
type = ntohs(type);
switch(type) { switch(type) {
case SPDYLAY_SYN_STREAM: case SPDYLAY_SYN_STREAM:
spdylay_buffer_reset(&session->inflatebuf); spdylay_buffer_reset(&session->inflatebuf);
@ -2193,7 +2224,7 @@ int spdylay_session_add_ping(spdylay_session *session, uint32_t unique_id)
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
} }
spdylay_frame_ping_init(&frame->ping, session->version, unique_id); spdylay_frame_ping_init(&frame->ping, session->version, unique_id);
r = spdylay_session_add_frame(session, SPDYLAY_PING, frame, NULL); r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
if(r != 0) { if(r != 0) {
spdylay_frame_ping_free(&frame->ping); spdylay_frame_ping_free(&frame->ping);
free(frame); free(frame);
@ -2213,7 +2244,7 @@ int spdylay_session_add_goaway(spdylay_session *session,
} }
spdylay_frame_goaway_init(&frame->goaway, session->version, spdylay_frame_goaway_init(&frame->goaway, session->version,
last_good_stream_id, status_code); last_good_stream_id, status_code);
r = spdylay_session_add_frame(session, SPDYLAY_GOAWAY, frame, NULL); r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
if(r != 0) { if(r != 0) {
spdylay_frame_goaway_free(&frame->goaway); spdylay_frame_goaway_free(&frame->goaway);
free(frame); free(frame);
@ -2233,7 +2264,7 @@ int spdylay_session_add_window_update(spdylay_session *session,
} }
spdylay_frame_window_update_init(&frame->window_update, session->version, spdylay_frame_window_update_init(&frame->window_update, session->version,
stream_id, delta_window_size); stream_id, delta_window_size);
r = spdylay_session_add_frame(session, SPDYLAY_WINDOW_UPDATE, frame, NULL); r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
if(r != 0) { if(r != 0) {
spdylay_frame_window_update_free(&frame->window_update); spdylay_frame_window_update_free(&frame->window_update);
free(frame); free(frame);

View File

@ -181,11 +181,14 @@ int spdylay_session_is_my_stream_id(spdylay_session *session,
int32_t stream_id); int32_t stream_id);
/* /*
* Adds frame |frame| of type |frame_type| to the outbound queue in * Adds frame |frame| to the outbound queue in |session|. The
* |session|. |aux_data| is a pointer to the arbitrary data. Its * |frame_cat| must be either SPDYLAY_CTRL or SPDYLAY_DATA. If the
* interpretation is defined per |frame_type|. When this function * |frame_cat| is SPDYLAY_CTRL, the |frame| must be a pointer to
* succeeds, it takes ownership of |frame| and |aux_data|, so caller * spdylay_frame. If the |frame_cat| is SPDYLAY_DATA, it must be a
* must not free them on success. * pointer to spdylay_data. |aux_data| is a pointer to the arbitrary
* data. Its interpretation is defined per the type of the frame. When
* this function succeeds, it takes ownership of |frame| and
* |aux_data|, so caller must not free them on success.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
@ -194,9 +197,8 @@ int spdylay_session_is_my_stream_id(spdylay_session *session,
* Out of memory. * Out of memory.
*/ */
int spdylay_session_add_frame(spdylay_session *session, int spdylay_session_add_frame(spdylay_session *session,
spdylay_frame_type frame_type, spdylay_frame_category frame_cat,
spdylay_frame *frame, void *abs_frame, void *aux_data);
void *aux_data);
/* /*
* Adds RST_STREAM frame for the stream |stream_id| with status code * Adds RST_STREAM frame for the stream |stream_id| with status code

View File

@ -92,7 +92,7 @@ static int spdylay_submit_syn_stream_shared
spdylay_frame_syn_stream_init(&frame->syn_stream, spdylay_frame_syn_stream_init(&frame->syn_stream,
session->version, flags_copy, session->version, flags_copy,
0, assoc_stream_id, pri, nv_copy); 0, assoc_stream_id, pri, nv_copy);
r = spdylay_session_add_frame(session, SPDYLAY_SYN_STREAM, frame, r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame,
aux_data); aux_data);
if(r != 0) { if(r != 0) {
spdylay_frame_syn_stream_free(&frame->syn_stream); spdylay_frame_syn_stream_free(&frame->syn_stream);
@ -133,7 +133,7 @@ int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags,
} }
spdylay_frame_syn_reply_init(&frame->syn_reply, session->version, flags_copy, spdylay_frame_syn_reply_init(&frame->syn_reply, session->version, flags_copy,
stream_id, nv_copy); stream_id, nv_copy);
r = spdylay_session_add_frame(session, SPDYLAY_SYN_REPLY, frame, NULL); r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
if(r != 0) { if(r != 0) {
spdylay_frame_syn_reply_free(&frame->syn_reply); spdylay_frame_syn_reply_free(&frame->syn_reply);
free(frame); free(frame);
@ -163,7 +163,7 @@ int spdylay_submit_headers(spdylay_session *session, uint8_t flags,
} }
spdylay_frame_headers_init(&frame->headers, session->version, flags_copy, spdylay_frame_headers_init(&frame->headers, session->version, flags_copy,
stream_id, nv_copy); stream_id, nv_copy);
r = spdylay_session_add_frame(session, SPDYLAY_HEADERS, frame, NULL); r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
if(r != 0) { if(r != 0) {
spdylay_frame_headers_free(&frame->headers); spdylay_frame_headers_free(&frame->headers);
free(frame); free(frame);
@ -218,7 +218,7 @@ int spdylay_submit_settings(spdylay_session *session, uint8_t flags,
spdylay_frame_iv_sort(iv_copy, niv); spdylay_frame_iv_sort(iv_copy, niv);
spdylay_frame_settings_init(&frame->settings, session->version, spdylay_frame_settings_init(&frame->settings, session->version,
flags, iv_copy, niv); flags, iv_copy, niv);
r = spdylay_session_add_frame(session, SPDYLAY_SETTINGS, frame, NULL); r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
if(r == 0) { if(r == 0) {
spdylay_session_update_local_settings(session, iv_copy, niv); spdylay_session_update_local_settings(session, iv_copy, niv);
} else { } else {
@ -274,7 +274,7 @@ int spdylay_submit_response(spdylay_session *session,
} }
spdylay_frame_syn_reply_init(&frame->syn_reply, session->version, flags, spdylay_frame_syn_reply_init(&frame->syn_reply, session->version, flags,
stream_id, nv_copy); stream_id, nv_copy);
r = spdylay_session_add_frame(session, SPDYLAY_SYN_REPLY, frame, r = spdylay_session_add_frame(session, SPDYLAY_CTRL, frame,
data_prd_copy); data_prd_copy);
if(r != 0) { if(r != 0) {
spdylay_frame_syn_reply_free(&frame->syn_reply); spdylay_frame_syn_reply_free(&frame->syn_reply);
@ -289,20 +289,20 @@ int spdylay_submit_data(spdylay_session *session, int32_t stream_id,
const spdylay_data_provider *data_prd) const spdylay_data_provider *data_prd)
{ {
int r; int r;
spdylay_frame *frame; spdylay_data *data_frame;
uint8_t nflags = 0; uint8_t nflags = 0;
frame = malloc(sizeof(spdylay_frame)); data_frame = malloc(sizeof(spdylay_frame));
if(frame == NULL) { if(data_frame == NULL) {
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
} }
if(flags & SPDYLAY_DATA_FLAG_FIN) { if(flags & SPDYLAY_DATA_FLAG_FIN) {
nflags |= SPDYLAY_DATA_FLAG_FIN; nflags |= SPDYLAY_DATA_FLAG_FIN;
} }
spdylay_frame_data_init(&frame->data, stream_id, nflags, data_prd); spdylay_frame_data_init(data_frame, stream_id, nflags, data_prd);
r = spdylay_session_add_frame(session, SPDYLAY_DATA, frame, NULL); r = spdylay_session_add_frame(session, SPDYLAY_DATA, data_frame, NULL);
if(r != 0) { if(r != 0) {
spdylay_frame_data_free(&frame->data); spdylay_frame_data_free(data_frame);
free(frame); free(data_frame);
} }
return r; return r;
} }

View File

@ -33,6 +33,10 @@
#include "spdylay_session.h" #include "spdylay_session.h"
#include "spdylay_stream.h" #include "spdylay_stream.h"
#define OB_CTRL(ITEM) spdylay_outbound_item_get_ctrl_frame(ITEM)
#define OB_CTRL_TYPE(ITEM) spdylay_outbound_item_get_ctrl_frame_type(ITEM)
#define OB_DATA(ITEM) spdylay_outbound_item_get_data_frame(ITEM)
typedef struct { typedef struct {
uint8_t buf[4096]; uint8_t buf[4096];
size_t length; size_t length;
@ -260,8 +264,8 @@ void test_spdylay_session_recv(void)
CU_ASSERT(0 == spdylay_session_recv(session)); CU_ASSERT(0 == spdylay_session_recv(session));
CU_ASSERT(0 == user_data.ctrl_recv_cb_called); CU_ASSERT(0 == user_data.ctrl_recv_cb_called);
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(SPDYLAY_RST_STREAM == item->frame_type); CU_ASSERT(SPDYLAY_RST_STREAM == OB_CTRL_TYPE(item));
CU_ASSERT(SPDYLAY_PROTOCOL_ERROR == item->frame->rst_stream.status_code); CU_ASSERT(SPDYLAY_PROTOCOL_ERROR == OB_CTRL(item)->rst_stream.status_code);
spdylay_session_del(session); spdylay_session_del(session);
@ -282,8 +286,8 @@ void test_spdylay_session_recv(void)
CU_ASSERT(0 == spdylay_session_recv(session)); CU_ASSERT(0 == spdylay_session_recv(session));
CU_ASSERT(0 == user_data.ctrl_recv_cb_called); CU_ASSERT(0 == user_data.ctrl_recv_cb_called);
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(SPDYLAY_RST_STREAM == item->frame_type); CU_ASSERT(SPDYLAY_RST_STREAM == OB_CTRL_TYPE(item));
CU_ASSERT(SPDYLAY_PROTOCOL_ERROR == item->frame->rst_stream.status_code); CU_ASSERT(SPDYLAY_PROTOCOL_ERROR == OB_CTRL(item)->rst_stream.status_code);
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
@ -302,8 +306,8 @@ void test_spdylay_session_recv(void)
CU_ASSERT(0 == spdylay_session_recv(session)); CU_ASSERT(0 == spdylay_session_recv(session));
CU_ASSERT(0 == user_data.ctrl_recv_cb_called); CU_ASSERT(0 == user_data.ctrl_recv_cb_called);
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(SPDYLAY_RST_STREAM == item->frame_type); CU_ASSERT(SPDYLAY_RST_STREAM == OB_CTRL_TYPE(item));
CU_ASSERT(SPDYLAY_PROTOCOL_ERROR == item->frame->rst_stream.status_code); CU_ASSERT(SPDYLAY_PROTOCOL_ERROR == OB_CTRL(item)->rst_stream.status_code);
free(framedata); free(framedata);
free(nvbuf); free(nvbuf);
@ -342,7 +346,7 @@ void test_spdylay_session_add_frame(void)
spdylay_frame_syn_stream_init(&frame->syn_stream, SPDYLAY_PROTO_SPDY2, spdylay_frame_syn_stream_init(&frame->syn_stream, SPDYLAY_PROTO_SPDY2,
SPDYLAY_CTRL_FLAG_NONE, 0, 0, 3, dup_nv(nv)); SPDYLAY_CTRL_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_CTRL, frame,
aux_data)); aux_data));
CU_ASSERT(0 == spdylay_pq_empty(&session->ob_ss_pq)); CU_ASSERT(0 == spdylay_pq_empty(&session->ob_ss_pq));
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
@ -579,8 +583,8 @@ void test_spdylay_session_on_syn_reply_received(void)
CU_ASSERT(0 == spdylay_session_on_syn_reply_received(session, &frame)); CU_ASSERT(0 == spdylay_session_on_syn_reply_received(session, &frame));
CU_ASSERT(1 == user_data.invalid_ctrl_recv_cb_called); CU_ASSERT(1 == user_data.invalid_ctrl_recv_cb_called);
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(SPDYLAY_RST_STREAM == item->frame_type); CU_ASSERT(SPDYLAY_RST_STREAM == OB_CTRL_TYPE(item));
CU_ASSERT(SPDYLAY_STREAM_IN_USE == item->frame->rst_stream.status_code); CU_ASSERT(SPDYLAY_STREAM_IN_USE == OB_CTRL(item)->rst_stream.status_code);
spdylay_frame_syn_reply_free(&frame.syn_reply); spdylay_frame_syn_reply_free(&frame.syn_reply);
@ -603,7 +607,7 @@ void test_spdylay_session_send_syn_stream(void)
spdylay_session_client_new(&session, SPDYLAY_PROTO_SPDY2, &callbacks, NULL); spdylay_session_client_new(&session, SPDYLAY_PROTO_SPDY2, &callbacks, NULL);
spdylay_frame_syn_stream_init(&frame->syn_stream, SPDYLAY_PROTO_SPDY2, spdylay_frame_syn_stream_init(&frame->syn_stream, SPDYLAY_PROTO_SPDY2,
SPDYLAY_CTRL_FLAG_NONE, 0, 0, 3, dup_nv(nv)); SPDYLAY_CTRL_FLAG_NONE, 0, 0, 3, dup_nv(nv));
spdylay_session_add_frame(session, SPDYLAY_SYN_STREAM, frame, aux_data); spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, aux_data);
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
stream = spdylay_session_get_stream(session, 1); stream = spdylay_session_get_stream(session, 1);
CU_ASSERT(SPDYLAY_STREAM_OPENING == stream->state); CU_ASSERT(SPDYLAY_STREAM_OPENING == stream->state);
@ -628,7 +632,7 @@ void test_spdylay_session_send_syn_reply(void)
SPDYLAY_STREAM_OPENING, NULL); SPDYLAY_STREAM_OPENING, NULL);
spdylay_frame_syn_reply_init(&frame->syn_reply, SPDYLAY_PROTO_SPDY2, spdylay_frame_syn_reply_init(&frame->syn_reply, SPDYLAY_PROTO_SPDY2,
SPDYLAY_CTRL_FLAG_NONE, 2, dup_nv(nv)); SPDYLAY_CTRL_FLAG_NONE, 2, dup_nv(nv));
spdylay_session_add_frame(session, SPDYLAY_SYN_REPLY, frame, NULL); spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
stream = spdylay_session_get_stream(session, 2); stream = spdylay_session_get_stream(session, 2);
CU_ASSERT(SPDYLAY_STREAM_OPENED == stream->state); CU_ASSERT(SPDYLAY_STREAM_OPENED == stream->state);
@ -657,7 +661,7 @@ void test_spdylay_submit_response(void)
SPDYLAY_STREAM_OPENING, NULL); SPDYLAY_STREAM_OPENING, NULL);
CU_ASSERT(0 == spdylay_submit_response(session, stream_id, nv, &data_prd)); CU_ASSERT(0 == spdylay_submit_response(session, stream_id, nv, &data_prd));
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(0 == strcmp("content-length", item->frame->syn_reply.nv[0])); CU_ASSERT(0 == strcmp("content-length", OB_CTRL(item)->syn_reply.nv[0]));
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
spdylay_session_del(session); spdylay_session_del(session);
} }
@ -683,8 +687,8 @@ void test_spdylay_submit_response_with_null_data_read_callback(void)
SPDYLAY_STREAM_OPENING, NULL); SPDYLAY_STREAM_OPENING, NULL);
CU_ASSERT(0 == spdylay_submit_response(session, 1, nv, &data_prd)); CU_ASSERT(0 == spdylay_submit_response(session, 1, nv, &data_prd));
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(0 == strcmp(":version", item->frame->syn_reply.nv[0])); CU_ASSERT(0 == strcmp(":version", OB_CTRL(item)->syn_reply.nv[0]));
CU_ASSERT(item->frame->syn_reply.hd.flags & SPDYLAY_CTRL_FLAG_FIN); CU_ASSERT(OB_CTRL(item)->syn_reply.hd.flags & SPDYLAY_CTRL_FLAG_FIN);
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(0 == spdylay_frame_unpack_syn_reply(&frame.syn_reply, CU_ASSERT(0 == spdylay_frame_unpack_syn_reply(&frame.syn_reply,
@ -719,7 +723,7 @@ void test_spdylay_submit_request_with_data(void)
&callbacks, &ud)); &callbacks, &ud));
CU_ASSERT(0 == spdylay_submit_request(session, 3, nv, &data_prd, NULL)); CU_ASSERT(0 == spdylay_submit_request(session, 3, nv, &data_prd, NULL));
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(0 == strcmp("version", item->frame->syn_stream.nv[0])); CU_ASSERT(0 == strcmp("version", OB_CTRL(item)->syn_stream.nv[0]));
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(0 == ud.data_source_length); CU_ASSERT(0 == ud.data_source_length);
@ -745,8 +749,8 @@ void test_spdylay_submit_request_with_null_data_read_callback(void)
&callbacks, &ud)); &callbacks, &ud));
CU_ASSERT(0 == spdylay_submit_request(session, 3, nv, &data_prd, NULL)); CU_ASSERT(0 == spdylay_submit_request(session, 3, nv, &data_prd, NULL));
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(0 == strcmp(":version", item->frame->syn_stream.nv[0])); CU_ASSERT(0 == strcmp(":version", OB_CTRL(item)->syn_stream.nv[0]));
CU_ASSERT(item->frame->syn_stream.hd.flags & SPDYLAY_CTRL_FLAG_FIN); CU_ASSERT(OB_CTRL(item)->syn_stream.hd.flags & SPDYLAY_CTRL_FLAG_FIN);
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(0 == spdylay_frame_unpack_syn_stream(&frame.syn_stream, CU_ASSERT(0 == spdylay_frame_unpack_syn_stream(&frame.syn_stream,
@ -776,11 +780,11 @@ void test_spdylay_submit_syn_stream(void)
CU_ASSERT(0 == spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_FIN, 1, 3, CU_ASSERT(0 == spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_FIN, 1, 3,
nv, NULL)); nv, NULL));
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(0 == strcmp("version", item->frame->syn_stream.nv[0])); CU_ASSERT(0 == strcmp("version", OB_CTRL(item)->syn_stream.nv[0]));
CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == item->frame->syn_stream.hd.flags); CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == OB_CTRL(item)->syn_stream.hd.flags);
/* See assoc-stream-ID is ignored */ /* See assoc-stream-ID is ignored */
CU_ASSERT(0 == item->frame->syn_stream.assoc_stream_id); CU_ASSERT(0 == OB_CTRL(item)->syn_stream.assoc_stream_id);
CU_ASSERT(3 == item->frame->syn_stream.pri); CU_ASSERT(3 == OB_CTRL(item)->syn_stream.pri);
spdylay_session_del(session); spdylay_session_del(session);
@ -789,10 +793,10 @@ void test_spdylay_submit_syn_stream(void)
CU_ASSERT(0 == spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_FIN, 1, 3, CU_ASSERT(0 == spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_FIN, 1, 3,
nv, NULL)); nv, NULL));
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(0 == strcmp("version", item->frame->syn_stream.nv[0])); CU_ASSERT(0 == strcmp("version", OB_CTRL(item)->syn_stream.nv[0]));
CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == item->frame->syn_stream.hd.flags); CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == OB_CTRL(item)->syn_stream.hd.flags);
CU_ASSERT(1 == item->frame->syn_stream.assoc_stream_id); CU_ASSERT(1 == OB_CTRL(item)->syn_stream.assoc_stream_id);
CU_ASSERT(3 == item->frame->syn_stream.pri); CU_ASSERT(3 == OB_CTRL(item)->syn_stream.pri);
/* Invalid assoc-stream-ID */ /* Invalid assoc-stream-ID */
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT == CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
@ -820,8 +824,8 @@ void test_spdylay_submit_syn_reply(void)
CU_ASSERT(0 == spdylay_submit_syn_reply(session, SPDYLAY_CTRL_FLAG_FIN, 1, CU_ASSERT(0 == spdylay_submit_syn_reply(session, SPDYLAY_CTRL_FLAG_FIN, 1,
nv)); nv));
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(0 == strcmp("version", item->frame->syn_reply.nv[0])); CU_ASSERT(0 == strcmp("version", OB_CTRL(item)->syn_reply.nv[0]));
CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == item->frame->syn_reply.hd.flags); CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == OB_CTRL(item)->syn_reply.hd.flags);
ud.ctrl_send_cb_called = 0; ud.ctrl_send_cb_called = 0;
ud.sent_frame_type = 0; ud.sent_frame_type = 0;
@ -862,8 +866,8 @@ void test_spdylay_submit_headers(void)
&callbacks, &ud)); &callbacks, &ud));
CU_ASSERT(0 == spdylay_submit_headers(session, SPDYLAY_CTRL_FLAG_FIN, 1, nv)); CU_ASSERT(0 == spdylay_submit_headers(session, SPDYLAY_CTRL_FLAG_FIN, 1, nv));
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(0 == strcmp(":version", item->frame->headers.nv[0])); CU_ASSERT(0 == strcmp(":version", OB_CTRL(item)->headers.nv[0]));
CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == item->frame->headers.hd.flags); CU_ASSERT(SPDYLAY_CTRL_FLAG_FIN == OB_CTRL(item)->headers.hd.flags);
ud.ctrl_send_cb_called = 0; ud.ctrl_send_cb_called = 0;
ud.sent_frame_type = 0; ud.sent_frame_type = 0;
@ -1009,6 +1013,7 @@ void test_spdylay_session_on_window_update_received(void)
data_item = malloc(sizeof(spdylay_outbound_item)); data_item = malloc(sizeof(spdylay_outbound_item));
memset(data_item, 0, sizeof(spdylay_outbound_item)); memset(data_item, 0, sizeof(spdylay_outbound_item));
data_item->frame_cat = SPDYLAY_DATA;
spdylay_stream_defer_data(stream, data_item, SPDYLAY_DEFERRED_FLOW_CONTROL); spdylay_stream_defer_data(stream, data_item, SPDYLAY_DEFERRED_FLOW_CONTROL);
CU_ASSERT(0 == spdylay_session_on_window_update_received(session, &frame)); CU_ASSERT(0 == spdylay_session_on_window_update_received(session, &frame));
@ -1043,8 +1048,8 @@ void test_spdylay_session_on_ping_received(void)
CU_ASSERT(0 == spdylay_session_on_ping_received(session, &frame)); CU_ASSERT(0 == spdylay_session_on_ping_received(session, &frame));
CU_ASSERT(1 == user_data.ctrl_recv_cb_called); CU_ASSERT(1 == user_data.ctrl_recv_cb_called);
top = spdylay_session_get_ob_pq_top(session); top = spdylay_session_get_ob_pq_top(session);
CU_ASSERT(SPDYLAY_PING == top->frame_type); CU_ASSERT(SPDYLAY_PING == OB_CTRL_TYPE(top));
CU_ASSERT(unique_id == top->frame->ping.unique_id); CU_ASSERT(unique_id == OB_CTRL(top)->ping.unique_id);
session->last_ping_unique_id = 1; session->last_ping_unique_id = 1;
frame.ping.unique_id = 1; frame.ping.unique_id = 1;
@ -1127,8 +1132,8 @@ void test_spdylay_session_on_data_received(void)
SPDYLAY_DATA_FLAG_NONE, SPDYLAY_DATA_FLAG_NONE,
4096, stream_id)); 4096, stream_id));
top = spdylay_session_get_ob_pq_top(session); top = spdylay_session_get_ob_pq_top(session);
CU_ASSERT(SPDYLAY_RST_STREAM == top->frame_type); CU_ASSERT(SPDYLAY_RST_STREAM == OB_CTRL_TYPE(top));
CU_ASSERT(SPDYLAY_INVALID_STREAM == top->frame->rst_stream.status_code); CU_ASSERT(SPDYLAY_INVALID_STREAM == OB_CTRL(top)->rst_stream.status_code);
spdylay_session_del(session); spdylay_session_del(session);
} }
@ -1212,7 +1217,7 @@ void test_spdylay_session_send_rst_stream(void)
frame = malloc(sizeof(spdylay_frame)); frame = malloc(sizeof(spdylay_frame));
spdylay_frame_rst_stream_init(&frame->rst_stream, SPDYLAY_PROTO_SPDY2, 1, spdylay_frame_rst_stream_init(&frame->rst_stream, SPDYLAY_PROTO_SPDY2, 1,
SPDYLAY_CANCEL); SPDYLAY_CANCEL);
spdylay_session_add_frame(session, SPDYLAY_RST_STREAM, frame, NULL); spdylay_session_add_frame(session, SPDYLAY_CTRL, frame, NULL);
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(NULL == spdylay_session_get_stream(session, 1)); CU_ASSERT(NULL == spdylay_session_get_stream(session, 1));
@ -1236,11 +1241,11 @@ void test_spdylay_session_get_next_ob_item(void)
CU_ASSERT(NULL == spdylay_session_get_next_ob_item(session)); CU_ASSERT(NULL == spdylay_session_get_next_ob_item(session));
spdylay_submit_ping(session); spdylay_submit_ping(session);
CU_ASSERT(SPDYLAY_PING == CU_ASSERT(SPDYLAY_PING ==
spdylay_session_get_next_ob_item(session)->frame_type); OB_CTRL_TYPE(spdylay_session_get_next_ob_item(session)));
spdylay_submit_request(session, 0, nv, NULL, NULL); spdylay_submit_request(session, 0, nv, NULL, NULL);
CU_ASSERT(SPDYLAY_PING == CU_ASSERT(SPDYLAY_PING ==
spdylay_session_get_next_ob_item(session)->frame_type); OB_CTRL_TYPE(spdylay_session_get_next_ob_item(session)));
CU_ASSERT(0 == spdylay_session_send(session)); CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(NULL == spdylay_session_get_next_ob_item(session)); CU_ASSERT(NULL == spdylay_session_get_next_ob_item(session));
@ -1253,12 +1258,12 @@ void test_spdylay_session_get_next_ob_item(void)
spdylay_submit_response(session, 1, nv, NULL); spdylay_submit_response(session, 1, nv, NULL);
CU_ASSERT(SPDYLAY_SYN_REPLY == CU_ASSERT(SPDYLAY_SYN_REPLY ==
spdylay_session_get_next_ob_item(session)->frame_type); OB_CTRL_TYPE(spdylay_session_get_next_ob_item(session)));
session->local_settings[SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS] = 3; session->local_settings[SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS] = 3;
CU_ASSERT(SPDYLAY_SYN_STREAM == CU_ASSERT(SPDYLAY_SYN_STREAM ==
spdylay_session_get_next_ob_item(session)->frame_type); OB_CTRL_TYPE(spdylay_session_get_next_ob_item(session)));
spdylay_session_del(session); spdylay_session_del(session);
} }
@ -1280,12 +1285,12 @@ void test_spdylay_session_pop_next_ob_item(void)
spdylay_submit_request(session, 0, nv, NULL, NULL); spdylay_submit_request(session, 0, nv, NULL, NULL);
item = spdylay_session_pop_next_ob_item(session); item = spdylay_session_pop_next_ob_item(session);
CU_ASSERT(SPDYLAY_PING == item->frame_type); CU_ASSERT(SPDYLAY_PING == OB_CTRL_TYPE(item));
spdylay_outbound_item_free(item); spdylay_outbound_item_free(item);
free(item); free(item);
item = spdylay_session_pop_next_ob_item(session); item = spdylay_session_pop_next_ob_item(session);
CU_ASSERT(SPDYLAY_SYN_STREAM == item->frame_type); CU_ASSERT(SPDYLAY_SYN_STREAM == OB_CTRL_TYPE(item));
spdylay_outbound_item_free(item); spdylay_outbound_item_free(item);
free(item); free(item);
@ -1298,7 +1303,7 @@ void test_spdylay_session_pop_next_ob_item(void)
spdylay_submit_response(session, 1, nv, NULL); spdylay_submit_response(session, 1, nv, NULL);
item = spdylay_session_pop_next_ob_item(session); item = spdylay_session_pop_next_ob_item(session);
CU_ASSERT(SPDYLAY_SYN_REPLY == item->frame_type); CU_ASSERT(SPDYLAY_SYN_REPLY == OB_CTRL_TYPE(item));
spdylay_outbound_item_free(item); spdylay_outbound_item_free(item);
free(item); free(item);
@ -1308,7 +1313,7 @@ void test_spdylay_session_pop_next_ob_item(void)
session->local_settings[SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS] = 2; session->local_settings[SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS] = 2;
item = spdylay_session_pop_next_ob_item(session); item = spdylay_session_pop_next_ob_item(session);
CU_ASSERT(SPDYLAY_SYN_STREAM == item->frame_type); CU_ASSERT(SPDYLAY_SYN_STREAM == OB_CTRL_TYPE(item));
spdylay_outbound_item_free(item); spdylay_outbound_item_free(item);
free(item); free(item);
@ -1425,8 +1430,8 @@ void test_spdylay_session_max_concurrent_streams(void)
CU_ASSERT(0 == spdylay_session_on_syn_stream_received(session, &frame)); CU_ASSERT(0 == spdylay_session_on_syn_stream_received(session, &frame));
item = spdylay_session_get_ob_pq_top(session); item = spdylay_session_get_ob_pq_top(session);
CU_ASSERT(SPDYLAY_RST_STREAM == item->frame_type); CU_ASSERT(SPDYLAY_RST_STREAM == OB_CTRL_TYPE(item));
CU_ASSERT(SPDYLAY_REFUSED_STREAM == item->frame->rst_stream.status_code) CU_ASSERT(SPDYLAY_REFUSED_STREAM == OB_CTRL(item)->rst_stream.status_code)
spdylay_frame_syn_stream_free(&frame.syn_stream); spdylay_frame_syn_stream_free(&frame.syn_stream);
@ -1668,7 +1673,7 @@ void test_spdylay_session_defer_data(void)
/* Resume deferred DATA */ /* Resume deferred DATA */
CU_ASSERT(0 == spdylay_session_resume_data(session, 1)); CU_ASSERT(0 == spdylay_session_resume_data(session, 1));
item = spdylay_session_get_ob_pq_top(session); item = spdylay_session_get_ob_pq_top(session);
item->frame->data.data_prd.read_callback = OB_DATA(item)->data_prd.read_callback =
fixed_length_data_source_read_callback; fixed_length_data_source_read_callback;
ud.block_count = 1; ud.block_count = 1;
/* Reads 2 4KiB blocks */ /* Reads 2 4KiB blocks */
@ -1676,7 +1681,7 @@ void test_spdylay_session_defer_data(void)
CU_ASSERT(ud.data_source_length == 8*1024); CU_ASSERT(ud.data_source_length == 8*1024);
/* Deferred again */ /* Deferred again */
item->frame->data.data_prd.read_callback = defer_data_source_read_callback; OB_DATA(item)->data_prd.read_callback = defer_data_source_read_callback;
/* This is needed since 4KiB block is already read and waiting to be /* This is needed since 4KiB block is already read and waiting to be
sent. No read_callback invocation. */ sent. No read_callback invocation. */
ud.block_count = 1; ud.block_count = 1;
@ -1687,7 +1692,7 @@ void test_spdylay_session_defer_data(void)
CU_ASSERT(0 == spdylay_session_resume_data(session, 1)); CU_ASSERT(0 == spdylay_session_resume_data(session, 1));
item = spdylay_session_get_ob_pq_top(session); item = spdylay_session_get_ob_pq_top(session);
item->frame->data.data_prd.read_callback = OB_DATA(item)->data_prd.read_callback =
fixed_length_data_source_read_callback; fixed_length_data_source_read_callback;
ud.block_count = 1; ud.block_count = 1;
/* Reads 2 4KiB blocks */ /* Reads 2 4KiB blocks */
@ -2014,7 +2019,7 @@ void test_spdylay_submit_settings(void)
item = spdylay_session_get_next_ob_item(session); item = spdylay_session_get_next_ob_item(session);
CU_ASSERT(SPDYLAY_SETTINGS == item->frame_type); CU_ASSERT(SPDYLAY_SETTINGS == OB_CTRL_TYPE(item));
frame = item->frame; frame = item->frame;
CU_ASSERT(2 == frame->settings.niv); CU_ASSERT(2 == frame->settings.niv);