Added stream_user_data arg to spdylay_submit_request() to identify stream ID later easily.

Specified stream_user_data_arg can be retrieved by
spdylay_session_get_stream_user_data() function. The application code can use
this function insde spdylay_on_ctrl_send_callback() and identify stream ID
for the request associated by the stream_user_data.
The sample usage is in examples/spdycat.cc.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-02-04 01:37:21 +09:00
parent 876c33c562
commit 1f72165549
10 changed files with 126 additions and 59 deletions

View File

@ -70,7 +70,6 @@ struct Request {
};
std::map<int32_t, Request*> stream2req;
std::map<std::string, Request*> path2req;
size_t numreq, complete;
Config config;
@ -86,34 +85,31 @@ void on_data_chunk_recv_callback
}
}
void check_stream_id(spdylay_frame_type type, spdylay_frame *frame)
void check_stream_id(spdylay_session *session,
spdylay_frame_type type, spdylay_frame *frame)
{
if(type == SPDYLAY_SYN_STREAM) {
for(int i = 0; frame->syn_stream.nv[i]; i += 2) {
if(strcmp("url", frame->syn_stream.nv[i]) == 0) {
std::map<std::string, Request*>::iterator itr = path2req.find
(frame->syn_stream.nv[i+1]);
if(itr != path2req.end()) {
stream2req[frame->syn_stream.stream_id] = (*itr).second;
}
break;
}
}
}
int32_t stream_id = frame->syn_stream.stream_id;
Request *req = (Request*)spdylay_session_get_stream_user_data(session,
stream_id);
stream2req[stream_id] = req;
}
void on_ctrl_send_callback2
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
void *user_data)
{
check_stream_id(type, frame);
if(type == SPDYLAY_SYN_STREAM) {
check_stream_id(session, type, frame);
}
}
void on_ctrl_send_callback3
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
void *user_data)
{
check_stream_id(type, frame);
if(type == SPDYLAY_SYN_STREAM) {
check_stream_id(session, type, frame);
}
on_ctrl_send_callback(session, type, frame, user_data);
}
@ -136,7 +132,6 @@ int communicate(const std::string& host, uint16_t port,
{
numreq = reqvec.size();
complete = 0;
path2req.clear();
stream2req.clear();
int fd = connect_to(host, port);
if(fd == -1) {
@ -171,9 +166,8 @@ int communicate(const std::string& host, uint16_t port,
for(int i = 0, n = reqvec.size(); i < n; ++i) {
uri::UriStruct& us = reqvec[i].us;
std::string path = us.dir+us.file+us.query;
int r = sc.submit_request(hostport, path, 3);
int r = sc.submit_request(hostport, path, 3, &reqvec[i]);
assert(r == 0);
path2req[path] = &reqvec[i];
}
pollfds[0].fd = fd;
ctl_poll(pollfds, &sc);

View File

@ -105,7 +105,8 @@ int Spdylay::fd() const
}
int Spdylay::submit_request(const std::string& hostport,
const std::string& path, uint8_t pri)
const std::string& path, uint8_t pri,
void *stream_user_data)
{
const char *nv[] = {
"host", hostport.c_str(),
@ -116,7 +117,7 @@ int Spdylay::submit_request(const std::string& hostport,
"version", "HTTP/1.1",
NULL
};
return spdylay_submit_request(session_, pri, nv, NULL);
return spdylay_submit_request(session_, pri, nv, NULL, stream_user_data);
}
bool Spdylay::would_block(int r)

View File

@ -50,7 +50,7 @@ public:
bool want_write();
int fd() const;
int submit_request(const std::string& hostport, const std::string& path,
uint8_t pri);
uint8_t pri, void *stream_user_data);
bool would_block(int r);
private:
int fd_;

View File

@ -281,7 +281,8 @@ typedef void (*spdylay_on_data_send_callback)
/*
* Callback function invoked before frame |frame| of type |type| is
* sent. This may be useful, for example, to know the stream ID of
* SYN_STREAM frame, which is not assigned when it was queued.
* SYN_STREAM frame (see also spdylay_session_get_stream_user_data),
* which is not assigned when it was queued.
*/
typedef void (*spdylay_before_ctrl_send_callback)
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
@ -353,6 +354,18 @@ int spdylay_session_want_read(spdylay_session *session);
*/
int spdylay_session_want_write(spdylay_session *session);
/*
* Returns stream_user_data for the stream |stream_id|. The
* stream_user_data is provided by spdylay_submit_request(). If the
* stream is initiated by the remote endpoint, stream_user_data is
* always NULL. If the stream is initiated by the local endpoint and
* NULL is given in spdylay_submit_request(), then this function
* returns NULL. If the stream does not exist, this function returns
* NULL.
*/
void* spdylay_session_get_stream_user_data(spdylay_session *session,
int32_t stream_id);
/*
* Submits SYN_STREAM frame. |pri| is priority of this request and it
* must be in the range of [0, 3]. 0 means the higest priority. |nv|
@ -368,13 +381,20 @@ int spdylay_session_want_write(spdylay_session *session);
* If |data_prd| is not NULL, it provides data which will be sent in
* subsequent DATA frames. In this case, "POST" must be specified with
* "method" key in |nv|. If |data_prd| is NULL, SYN_STREAM have
* FLAG_FIN.
* FLAG_FIN. |stream_user_data| can be an arbitrary pointer, which
* can be retrieved by spdylay_session_get_stream_user_data(). Since
* stream ID is not known before sending SYN_STREAM frame and the
* application code has to compare url, and possibly other header
* field values, to identify stream ID for the request in
* spdylay_on_ctrl_send_callback(). With |stream_user_data|, the
* application can easily identifies stream ID for the request.
*
* This function returns 0 if it succeeds, or negative error code.
*/
int spdylay_submit_request(spdylay_session *session, uint8_t pri,
const char **nv,
spdylay_data_provider *data_prd);
spdylay_data_provider *data_prd,
void *stream_user_data);
/*
* Submits DATA frame to stream |stream_id|.

View File

@ -164,6 +164,7 @@ static void spdylay_outbound_item_free(spdylay_outbound_item *item)
switch(item->frame_type) {
case SPDYLAY_SYN_STREAM:
spdylay_frame_syn_stream_free(&item->frame->syn_stream);
free(((spdylay_syn_stream_aux_data*)item->aux_data)->data_prd);
break;
case SPDYLAY_SYN_REPLY:
spdylay_frame_syn_reply_free(&item->frame->syn_reply);
@ -308,14 +309,16 @@ int spdylay_session_add_rst_stream(spdylay_session *session,
spdylay_stream* spdylay_session_open_stream(spdylay_session *session,
int32_t stream_id,
uint8_t flags, uint8_t pri,
spdylay_stream_state initial_state)
spdylay_stream_state initial_state,
void *stream_user_data)
{
int r;
spdylay_stream *stream = malloc(sizeof(spdylay_stream));
if(stream == NULL) {
return NULL;
}
spdylay_stream_init(stream, stream_id, flags, pri, initial_state);
spdylay_stream_init(stream, stream_id, flags, pri, initial_state,
stream_user_data);
r = spdylay_map_insert(&session->streams, stream_id, stream);
if(r != 0) {
free(stream);
@ -415,6 +418,7 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
switch(item->frame_type) {
case SPDYLAY_SYN_STREAM: {
uint32_t stream_id;
spdylay_syn_stream_aux_data *aux_data;
if(session->goaway_flags) {
/* When GOAWAY is sent or received, peer must not send new
SYN_STREAM. */
@ -429,10 +433,12 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
if(framebuflen < 0) {
return framebuflen;
}
aux_data = (spdylay_syn_stream_aux_data*)item->aux_data;
if(spdylay_session_open_stream(session, stream_id,
item->frame->syn_stream.hd.flags,
item->frame->syn_stream.pri,
SPDYLAY_STREAM_INITIAL) == NULL) {
SPDYLAY_STREAM_INITIAL,
aux_data->stream_user_data) == NULL) {
free(framebuf);
return SPDYLAY_ERR_NOMEM;
}
@ -548,6 +554,7 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
spdylay_stream *stream =
spdylay_session_get_stream(session, frame->syn_stream.stream_id);
if(stream) {
spdylay_syn_stream_aux_data *aux_data;
stream->state = SPDYLAY_STREAM_OPENING;
if(frame->syn_stream.hd.flags & SPDYLAY_FLAG_FIN) {
spdylay_stream_shutdown(stream, SPDYLAY_SHUT_WR);
@ -556,12 +563,13 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
spdylay_stream_shutdown(stream, SPDYLAY_SHUT_RD);
}
spdylay_session_close_stream_if_shut_rdwr(session, stream);
if(item->aux_data) {
/* We assume aux_data is a pointer to spdylay_data_provider */
spdylay_data_provider *data_prd =
(spdylay_data_provider*)item->aux_data;
/* We assume aux_data is a pointer to spdylay_syn_stream_aux_data */
aux_data = (spdylay_syn_stream_aux_data*)item->aux_data;
if(aux_data->data_prd) {
int r;
r = spdylay_submit_data(session, frame->syn_stream.stream_id, data_prd);
/* spdylay_submit_data() makes a copy of aux_data->data_prd */
r = spdylay_submit_data(session, frame->syn_stream.stream_id,
aux_data->data_prd);
if(r != 0) {
/* TODO If r is not FATAL, we should send RST_STREAM. */
return r;
@ -885,7 +893,8 @@ int spdylay_session_on_syn_stream_received(spdylay_session *session,
stream = spdylay_session_open_stream(session, frame->syn_stream.stream_id,
frame->syn_stream.hd.flags,
frame->syn_stream.pri,
SPDYLAY_STREAM_OPENING);
SPDYLAY_STREAM_OPENING,
NULL);
if(stream) {
if(flags & SPDYLAY_FLAG_FIN) {
spdylay_stream_shutdown(stream, SPDYLAY_SHUT_RD);
@ -1431,13 +1440,15 @@ int spdylay_submit_data(spdylay_session *session, int32_t stream_id,
}
int spdylay_submit_request(spdylay_session *session, uint8_t pri,
const char **nv, spdylay_data_provider *data_prd)
const char **nv, spdylay_data_provider *data_prd,
void *stream_user_data)
{
int r;
spdylay_frame *frame;
char **nv_copy;
uint8_t flags = 0;
spdylay_data_provider *data_prd_copy = NULL;
spdylay_syn_stream_aux_data *aux_data;
if(pri > 3) {
return SPDYLAY_ERR_INVALID_ARGUMENT;
}
@ -1448,14 +1459,24 @@ int spdylay_submit_request(spdylay_session *session, uint8_t pri,
}
*data_prd_copy = *data_prd;
}
aux_data = malloc(sizeof(spdylay_syn_stream_aux_data));
if(aux_data == NULL) {
free(data_prd_copy);
return SPDYLAY_ERR_NOMEM;
}
aux_data->data_prd = data_prd_copy;
aux_data->stream_user_data = stream_user_data;
frame = malloc(sizeof(spdylay_frame));
if(frame == NULL) {
free(aux_data);
free(data_prd_copy);
return SPDYLAY_ERR_NOMEM;
}
nv_copy = spdylay_frame_nv_copy(nv);
if(nv_copy == NULL) {
free(frame);
free(aux_data);
free(data_prd_copy);
return SPDYLAY_ERR_NOMEM;
}
@ -1465,10 +1486,11 @@ int spdylay_submit_request(spdylay_session *session, uint8_t pri,
}
spdylay_frame_syn_stream_init(&frame->syn_stream, flags, 0, 0, pri, nv_copy);
r = spdylay_session_add_frame(session, SPDYLAY_SYN_STREAM, frame,
data_prd_copy);
aux_data);
if(r != 0) {
spdylay_frame_syn_stream_free(&frame->syn_stream);
free(frame);
free(aux_data);
free(data_prd_copy);
}
return r;
@ -1531,3 +1553,15 @@ uint32_t spdylay_session_get_next_unique_id(spdylay_session *session)
session->next_unique_id += 2;
return ret_id;
}
void* spdylay_session_get_stream_user_data(spdylay_session *session,
int32_t stream_id)
{
spdylay_stream *stream;
stream = spdylay_session_get_stream(session, stream_id);
if(stream) {
return stream->stream_user_data;
} else {
return NULL;
}
}

View File

@ -123,6 +123,11 @@ struct spdylay_session {
void *user_data;
};
typedef struct {
spdylay_data_provider *data_prd;
void *stream_user_data;
} spdylay_syn_stream_aux_data;
/* TODO stream timeout etc */
/*
@ -164,7 +169,8 @@ int spdylay_session_add_goaway(spdylay_session *session,
spdylay_stream* spdylay_session_open_stream(spdylay_session *session,
int32_t stream_id,
uint8_t flags, uint8_t pri,
spdylay_stream_state initial_state);
spdylay_stream_state initial_state,
void *stream_user_data);
/*
* Closes stream whose stream ID is |stream_id|. The reason of closure

View File

@ -26,7 +26,8 @@
void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id,
uint8_t flags, uint8_t pri,
spdylay_stream_state initial_state)
spdylay_stream_state initial_state,
void *stream_user_data)
{
stream->stream_id = stream_id;
stream->flags = flags;
@ -36,6 +37,7 @@ void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id,
stream->pushed_streams = NULL;
stream->pushed_streams_length = 0;
stream->pushed_streams_capacity = 0;
stream->stream_user_data = stream_user_data;
}
void spdylay_stream_free(spdylay_stream *stream)

View File

@ -85,11 +85,14 @@ typedef struct {
/* The maximum number of stream ID the |pushed_streams| can
store. */
size_t pushed_streams_capacity;
/* The arbitrary data provided by user for this stream. */
void *stream_user_data;
} spdylay_stream;
void spdylay_stream_init(spdylay_stream *stream, int32_t stream_id,
uint8_t flags, uint8_t pri,
spdylay_stream_state initial_state);
spdylay_stream_state initial_state,
void *stream_user_data);
void spdylay_stream_free(spdylay_stream *stream);

View File

@ -200,10 +200,13 @@ void test_spdylay_session_add_frame()
NULL
};
spdylay_frame *frame;
spdylay_syn_stream_aux_data *aux_data =
malloc(sizeof(spdylay_syn_stream_aux_data));
const uint8_t hd_ans1[] = {
0x80, 0x02, 0x00, 0x01
};
uint32_t temp32;
memset(aux_data, 0, sizeof(spdylay_syn_stream_aux_data));
acc.length = 0;
user_data.acc = &acc;
CU_ASSERT(0 == spdylay_session_client_new(&session, &callbacks, &user_data));
@ -213,7 +216,7 @@ void test_spdylay_session_add_frame()
dup_nv(nv));
CU_ASSERT(0 == spdylay_session_add_frame(session, SPDYLAY_SYN_STREAM, frame,
NULL));
aux_data));
CU_ASSERT(0 == spdylay_pq_empty(&session->ob_pq));
CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(memcmp(hd_ans1, acc.buf, 4) == 0);
@ -336,7 +339,7 @@ void test_spdylay_session_on_syn_stream_received_with_push()
spdylay_session_client_new(&session, &callbacks, &user_data);
spdylay_session_open_stream(session, assoc_stream_id, SPDYLAY_FLAG_NONE,
pri, SPDYLAY_STREAM_OPENED);
pri, SPDYLAY_STREAM_OPENED, NULL);
spdylay_frame_syn_stream_init(&frame.syn_stream,
SPDYLAY_FLAG_UNIDIRECTIONAL,
stream_id, assoc_stream_id, pri, dup_nv(nv));
@ -388,7 +391,7 @@ void test_spdylay_session_on_syn_reply_received()
spdylay_session_client_new(&session, &callbacks, &user_data);
spdylay_session_open_stream(session, 1, SPDYLAY_FLAG_NONE, 0,
SPDYLAY_STREAM_OPENING);
SPDYLAY_STREAM_OPENING, NULL);
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_FLAG_NONE, 1,
dup_nv(nv));
@ -405,7 +408,7 @@ void test_spdylay_session_on_syn_reply_received()
/* Check the situation when SYN_REPLY is received after peer sends
FIN */
stream = spdylay_session_open_stream(session, 3, SPDYLAY_FLAG_NONE, 0,
SPDYLAY_STREAM_OPENED);
SPDYLAY_STREAM_OPENED, NULL);
spdylay_stream_shutdown(stream, SPDYLAY_SHUT_RD);
frame.syn_reply.stream_id = 3;
@ -428,11 +431,14 @@ void test_spdylay_session_send_syn_stream()
const char *nv[] = { NULL };
spdylay_frame *frame = malloc(sizeof(spdylay_frame));
spdylay_stream *stream;
spdylay_syn_stream_aux_data *aux_data =
malloc(sizeof(spdylay_syn_stream_aux_data));
memset(aux_data, 0, sizeof(spdylay_syn_stream_aux_data));
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, NULL);
spdylay_session_add_frame(session, SPDYLAY_SYN_STREAM, frame, aux_data);
CU_ASSERT(0 == spdylay_session_send(session));
stream = spdylay_session_get_stream(session, 1);
CU_ASSERT(SPDYLAY_STREAM_OPENING == stream->state);
@ -455,7 +461,7 @@ void test_spdylay_session_send_syn_reply()
CU_ASSERT(0 == spdylay_session_client_new(&session, &callbacks, NULL));
spdylay_session_open_stream(session, 2, SPDYLAY_FLAG_NONE, 3,
SPDYLAY_STREAM_OPENING);
SPDYLAY_STREAM_OPENING, NULL);
spdylay_frame_syn_reply_init(&frame->syn_reply, SPDYLAY_FLAG_NONE,
2, dup_nv(nv));
spdylay_session_add_frame(session, SPDYLAY_SYN_REPLY, frame, NULL);
@ -484,7 +490,7 @@ void test_spdylay_submit_response()
ud.data_source_length = 64*1024;
CU_ASSERT(0 == spdylay_session_client_new(&session, &callbacks, &ud));
spdylay_session_open_stream(session, stream_id, SPDYLAY_FLAG_NONE, 3,
SPDYLAY_STREAM_OPENING);
SPDYLAY_STREAM_OPENING, NULL);
CU_ASSERT(0 == spdylay_submit_response(session, stream_id, nv, &data_prd));
CU_ASSERT(0 == spdylay_session_send(session));
spdylay_session_del(session);
@ -506,7 +512,7 @@ void test_spdylay_submit_request_with_data()
data_prd.read_callback = fixed_length_data_source_read_callback;
ud.data_source_length = 64*1024;
CU_ASSERT(0 == spdylay_session_client_new(&session, &callbacks, &ud));
CU_ASSERT(0 == spdylay_submit_request(session, 3, nv, &data_prd));
CU_ASSERT(0 == spdylay_submit_request(session, 3, nv, &data_prd, NULL));
CU_ASSERT(0 == spdylay_session_send(session));
CU_ASSERT(0 == ud.data_source_length);
@ -552,7 +558,7 @@ void test_spdylay_session_on_headers_received()
spdylay_session_client_new(&session, &callbacks, &user_data);
spdylay_session_open_stream(session, 1, SPDYLAY_FLAG_NONE, 0,
SPDYLAY_STREAM_OPENED);
SPDYLAY_STREAM_OPENED, NULL);
spdylay_stream_shutdown(spdylay_session_get_stream(session, 1),
SPDYLAY_SHUT_WR);
spdylay_frame_headers_init(&frame.headers, SPDYLAY_FLAG_NONE, 1,
@ -575,7 +581,7 @@ void test_spdylay_session_on_headers_received()
/* Check to see when SPDYLAY_STREAM_CLOSING, incoming HEADERS is
discarded. */
spdylay_session_open_stream(session, 3, SPDYLAY_FLAG_NONE, 0,
SPDYLAY_STREAM_CLOSING);
SPDYLAY_STREAM_CLOSING, NULL);
frame.headers.stream_id = 3;
frame.headers.hd.flags = SPDYLAY_FLAG_NONE;
CU_ASSERT(0 == spdylay_session_on_headers_received(session, &frame));
@ -584,7 +590,7 @@ void test_spdylay_session_on_headers_received()
/* Server initiated stream */
spdylay_session_open_stream(session, 2, SPDYLAY_FLAG_NONE, 0,
SPDYLAY_STREAM_OPENING);
SPDYLAY_STREAM_OPENING, NULL);
frame.headers.hd.flags = SPDYLAY_FLAG_FIN;
frame.headers.stream_id = 2;
@ -677,7 +683,7 @@ void test_spdylay_session_on_data_received()
spdylay_session_client_new(&session, &callbacks, &user_data);
stream = spdylay_session_open_stream(session, stream_id, SPDYLAY_FLAG_NONE,
3, SPDYLAY_STREAM_OPENING);
3, SPDYLAY_STREAM_OPENING, NULL);
CU_ASSERT(0 == spdylay_session_on_data_received(session, SPDYLAY_FLAG_NONE,
4096, stream_id));
CU_ASSERT(0 == stream->shut_flags);
@ -690,7 +696,7 @@ void test_spdylay_session_on_data_received()
stream_id = 4;
spdylay_session_open_stream(session, stream_id, SPDYLAY_FLAG_NONE,
3, SPDYLAY_STREAM_CLOSING);
3, SPDYLAY_STREAM_CLOSING, NULL);
CU_ASSERT(0 == spdylay_session_on_data_received(session, SPDYLAY_FLAG_NONE,
4096, stream_id));
CU_ASSERT(NULL == spdylay_session_get_ob_pq_top(session));
@ -740,13 +746,13 @@ void test_spdylay_session_on_rst_received()
memset(&callbacks, 0, sizeof(spdylay_session_callbacks));
spdylay_session_server_new(&session, &callbacks, &user_data);
stream = spdylay_session_open_stream(session, 1, SPDYLAY_FLAG_NONE,
3, SPDYLAY_STREAM_OPENING);
3, SPDYLAY_STREAM_OPENING, NULL);
/* server push */
spdylay_session_open_stream(session, 2, SPDYLAY_FLAG_NONE,
3, SPDYLAY_STREAM_OPENING);
3, SPDYLAY_STREAM_OPENING, NULL);
spdylay_stream_add_pushed_stream(stream, 2);
spdylay_session_open_stream(session, 4, SPDYLAY_FLAG_NONE,
3, SPDYLAY_STREAM_OPENING);
3, SPDYLAY_STREAM_OPENING, NULL);
spdylay_stream_add_pushed_stream(stream, 4);
spdylay_frame_rst_stream_init(&frame.rst_stream, 1, SPDYLAY_CANCEL);
@ -772,13 +778,13 @@ void test_spdylay_session_send_rst_stream()
callbacks.send_callback = null_send_callback;
spdylay_session_client_new(&session, &callbacks, &user_data);
stream = spdylay_session_open_stream(session, 1, SPDYLAY_FLAG_NONE,
3, SPDYLAY_STREAM_OPENING);
3, SPDYLAY_STREAM_OPENING, NULL);
/* server push */
spdylay_session_open_stream(session, 2, SPDYLAY_FLAG_NONE,
3, SPDYLAY_STREAM_OPENING);
3, SPDYLAY_STREAM_OPENING, NULL);
spdylay_stream_add_pushed_stream(stream, 2);
spdylay_session_open_stream(session, 4, SPDYLAY_FLAG_NONE,
3, SPDYLAY_STREAM_OPENING);
3, SPDYLAY_STREAM_OPENING, NULL);
spdylay_stream_add_pushed_stream(stream, 4);
frame = malloc(sizeof(spdylay_frame));

View File

@ -32,7 +32,8 @@ void test_spdylay_stream_add_pushed_stream()
{
spdylay_stream stream;
int i, n;
spdylay_stream_init(&stream, 1, SPDYLAY_FLAG_NONE, 3, SPDYLAY_STREAM_OPENING);
spdylay_stream_init(&stream, 1, SPDYLAY_FLAG_NONE, 3, SPDYLAY_STREAM_OPENING,
NULL);
n = 26;
for(i = 2; i < n; i += 2) {
CU_ASSERT(0 == spdylay_stream_add_pushed_stream(&stream, i));