Call on_stream_close_callback when server pushed SYN_STREAM has FIN flag set.
Don't mix status code and return value in spdylay_session_on_syn_stream_received.
This commit is contained in:
parent
8069575838
commit
fd06d21638
|
@ -1003,19 +1003,20 @@ static int spdylay_session_handle_invalid_stream
|
||||||
int spdylay_session_on_syn_stream_received(spdylay_session *session,
|
int spdylay_session_on_syn_stream_received(spdylay_session *session,
|
||||||
spdylay_frame *frame)
|
spdylay_frame *frame)
|
||||||
{
|
{
|
||||||
int r;
|
int r = 0;
|
||||||
|
int status_code;
|
||||||
if(session->goaway_flags) {
|
if(session->goaway_flags) {
|
||||||
/* We don't accept SYN_STREAM after GOAWAY is sent or received. */
|
/* We don't accept SYN_STREAM after GOAWAY is sent or received. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
r = spdylay_session_validate_syn_stream(session, &frame->syn_stream);
|
status_code = spdylay_session_validate_syn_stream(session,
|
||||||
if(r == 0) {
|
&frame->syn_stream);
|
||||||
|
if(status_code == 0) {
|
||||||
uint8_t flags = frame->syn_stream.hd.flags;
|
uint8_t flags = frame->syn_stream.hd.flags;
|
||||||
if((flags & SPDYLAY_FLAG_FIN) && (flags & SPDYLAY_FLAG_UNIDIRECTIONAL)) {
|
if((flags & SPDYLAY_FLAG_FIN) && (flags & SPDYLAY_FLAG_UNIDIRECTIONAL)) {
|
||||||
/* If the stream is UNIDIRECTIONAL and FIN bit set, we can close
|
/* If the stream is UNIDIRECTIONAL and FIN bit set, we can close
|
||||||
stream upon receiving SYN_STREAM. So, the stream needs not to
|
stream upon receiving SYN_STREAM. So, the stream needs not to
|
||||||
be opened. */
|
be opened. */
|
||||||
r = 0;
|
|
||||||
} else {
|
} else {
|
||||||
spdylay_stream *stream;
|
spdylay_stream *stream;
|
||||||
stream = spdylay_session_open_stream(session, frame->syn_stream.stream_id,
|
stream = spdylay_session_open_stream(session, frame->syn_stream.stream_id,
|
||||||
|
@ -1035,18 +1036,26 @@ int spdylay_session_on_syn_stream_received(spdylay_session *session,
|
||||||
SPDYLAY_FLAG_UNIDIRECTIONAL is not set here. */
|
SPDYLAY_FLAG_UNIDIRECTIONAL is not set here. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(r == 0) {
|
session->last_recv_stream_id = frame->syn_stream.stream_id;
|
||||||
session->last_recv_stream_id = frame->syn_stream.stream_id;
|
spdylay_session_call_on_ctrl_frame_received(session, SPDYLAY_SYN_STREAM,
|
||||||
spdylay_session_call_on_ctrl_frame_received(session, SPDYLAY_SYN_STREAM,
|
frame);
|
||||||
frame);
|
if(flags & SPDYLAY_FLAG_FIN) {
|
||||||
if(flags & SPDYLAY_FLAG_FIN) {
|
spdylay_session_call_on_request_recv(session,
|
||||||
spdylay_session_call_on_request_recv(session,
|
frame->syn_stream.stream_id);
|
||||||
frame->syn_stream.stream_id);
|
if(flags & SPDYLAY_FLAG_UNIDIRECTIONAL) {
|
||||||
|
/* Note that we call on_stream_close_callback without opening
|
||||||
|
stream. */
|
||||||
|
if(session->callbacks.on_stream_close_callback) {
|
||||||
|
session->callbacks.on_stream_close_callback
|
||||||
|
(session, frame->syn_stream.stream_id, SPDYLAY_OK,
|
||||||
|
session->user_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r = spdylay_session_handle_invalid_stream
|
r = spdylay_session_handle_invalid_stream
|
||||||
(session, frame->syn_stream.stream_id, SPDYLAY_SYN_STREAM, frame, r);
|
(session, frame->syn_stream.stream_id, SPDYLAY_SYN_STREAM, frame,
|
||||||
|
status_code);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,8 @@ int main(int argc, char* argv[])
|
||||||
test_spdylay_session_data_backoff_by_high_pri_frame) ||
|
test_spdylay_session_data_backoff_by_high_pri_frame) ||
|
||||||
!CU_add_test(pSuite, "session_stop_data_with_rst_stream",
|
!CU_add_test(pSuite, "session_stop_data_with_rst_stream",
|
||||||
test_spdylay_session_stop_data_with_rst_stream) ||
|
test_spdylay_session_stop_data_with_rst_stream) ||
|
||||||
|
!CU_add_test(pSuite, "session_stream_close_on_syn_stream",
|
||||||
|
test_spdylay_session_stream_close_on_syn_stream) ||
|
||||||
!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) ||
|
||||||
|
|
|
@ -163,6 +163,16 @@ static void on_request_recv_callback(spdylay_session *session,
|
||||||
ud->stream_id = stream_id;
|
ud->stream_id = stream_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void no_stream_user_data_stream_close_callback
|
||||||
|
(spdylay_session *session,
|
||||||
|
int32_t stream_id,
|
||||||
|
spdylay_status_code status_code,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
my_user_data* my_data = (my_user_data*)user_data;
|
||||||
|
++my_data->stream_close_cb_called;
|
||||||
|
}
|
||||||
|
|
||||||
static char** dup_nv(const char **src)
|
static char** dup_nv(const char **src)
|
||||||
{
|
{
|
||||||
return spdylay_frame_nv_copy(src);
|
return spdylay_frame_nv_copy(src);
|
||||||
|
@ -960,8 +970,9 @@ void test_spdylay_session_on_request_recv_callback()
|
||||||
spdylay_session_del(session);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stream_close_callback(spdylay_session *session, int32_t stream_id,
|
static void stream_close_callback(spdylay_session *session, int32_t stream_id,
|
||||||
spdylay_status_code status_code, void *user_data)
|
spdylay_status_code status_code,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
my_user_data* my_data = (my_user_data*)user_data;
|
my_user_data* my_data = (my_user_data*)user_data;
|
||||||
void *stream_data = spdylay_session_get_stream_user_data(session, stream_id);
|
void *stream_data = spdylay_session_get_stream_user_data(session, stream_id);
|
||||||
|
@ -1124,3 +1135,33 @@ void test_spdylay_session_stop_data_with_rst_stream()
|
||||||
|
|
||||||
spdylay_session_del(session);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that on_stream_close_callback is called when server pushed
|
||||||
|
* SYN_STREAM have SPDYLAY_FLAG_FIN.
|
||||||
|
*/
|
||||||
|
void test_spdylay_session_stream_close_on_syn_stream()
|
||||||
|
{
|
||||||
|
spdylay_session *session;
|
||||||
|
spdylay_session_callbacks callbacks;
|
||||||
|
const char *nv[] = { NULL };
|
||||||
|
my_user_data ud;
|
||||||
|
spdylay_frame frame;
|
||||||
|
|
||||||
|
memset(&callbacks, 0, sizeof(spdylay_session_callbacks));
|
||||||
|
callbacks.on_stream_close_callback =
|
||||||
|
no_stream_user_data_stream_close_callback;
|
||||||
|
ud.stream_close_cb_called = 0;
|
||||||
|
|
||||||
|
spdylay_session_client_new(&session, &callbacks, &ud);
|
||||||
|
spdylay_session_open_stream(session, 1, SPDYLAY_FLAG_NONE, 3,
|
||||||
|
SPDYLAY_STREAM_OPENING, NULL);
|
||||||
|
spdylay_frame_syn_stream_init(&frame.syn_stream,
|
||||||
|
SPDYLAY_FLAG_FIN | SPDYLAY_FLAG_UNIDIRECTIONAL,
|
||||||
|
2, 1, 3, dup_nv(nv));
|
||||||
|
|
||||||
|
CU_ASSERT(0 == spdylay_session_on_syn_stream_received(session, &frame));
|
||||||
|
|
||||||
|
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||||
|
spdylay_session_del(session);
|
||||||
|
}
|
||||||
|
|
|
@ -50,5 +50,6 @@ void test_spdylay_session_on_stream_close();
|
||||||
void test_spdylay_session_max_concurrent_streams();
|
void test_spdylay_session_max_concurrent_streams();
|
||||||
void test_spdylay_session_data_backoff_by_high_pri_frame();
|
void test_spdylay_session_data_backoff_by_high_pri_frame();
|
||||||
void test_spdylay_session_stop_data_with_rst_stream();
|
void test_spdylay_session_stop_data_with_rst_stream();
|
||||||
|
void test_spdylay_session_stream_close_on_syn_stream();
|
||||||
|
|
||||||
#endif // SPDYLAY_SESSION_TEST_H
|
#endif // SPDYLAY_SESSION_TEST_H
|
||||||
|
|
Loading…
Reference in New Issue