diff --git a/examples/spdylay_ssl.cc b/examples/spdylay_ssl.cc index 339b51c3..f8289b9a 100644 --- a/examples/spdylay_ssl.cc +++ b/examples/spdylay_ssl.cc @@ -472,7 +472,7 @@ int select_next_proto_cb(SSL* ssl, } std::string& next_proto = *(std::string*)arg; if(next_proto.empty()) { - if(spdylay_select_next_protocol(out, outlen, in, inlen) != 1) { + if(spdylay_select_next_protocol(out, outlen, in, inlen) <= 0) { std::cerr << "Server did not advertise spdy/2 or spdy/3 protocol." << std::endl; abort(); diff --git a/lib/includes/spdylay/spdylay.h b/lib/includes/spdylay/spdylay.h index 8bfd1f55..03ec0498 100644 --- a/lib/includes/spdylay/spdylay.h +++ b/lib/includes/spdylay/spdylay.h @@ -758,8 +758,11 @@ int spdylay_submit_goaway(spdylay_session *session, uint32_t status_code); * * The selection algorithm is as follows: * - * 1. If server's list contains "spdy/2", this function selects - * "spdy/2" and returns 1. The following steps are not taken. + * 1. If server's list contains SPDY versions the spdylay library + * supports, this function selects one of them and returns its SPDY + * protocol version which can be used directly with + * spdylay_session_client_new() and spdylay_session_server_new() + * . The following steps are not taken. * * 2. If server's list contains "http/1.1", this function selects * "http/1.1" and returns 0. The following step is not taken. @@ -785,8 +788,10 @@ int spdylay_submit_goaway(spdylay_session *session, uint32_t status_code); * const unsigned char *in, unsigned int inlen, * void *arg) * { - * if (spdylay_select_next_protocol(out, outlen, in, inlen) == 1) { - * ((MyType*)arg)->spdy_version = spdylay_npn_get_version(*out, *outlen); + * int version; + * version = spdylay_select_next_protocol(out, outlen, in, inlen); + * if(version > 0) { + * ((MyType*)arg)->spdy_version = version; * } * return SSL_TLSEXT_ERR_OK; * } diff --git a/lib/spdylay_npn.c b/lib/spdylay_npn.c index a7f75b1c..73f664ce 100644 --- a/lib/spdylay_npn.c +++ b/lib/spdylay_npn.c @@ -29,6 +29,7 @@ typedef struct { const unsigned char *proto; uint8_t len; + uint16_t version; } spdylay_npn_proto; int spdylay_select_next_protocol(unsigned char **out, unsigned char *outlen, @@ -37,8 +38,8 @@ int spdylay_select_next_protocol(unsigned char **out, unsigned char *outlen, int http_selected = 0; unsigned int i = 0; static const spdylay_npn_proto proto_list[] = { - { (const unsigned char*)"spdy/2", 6 }, - { (const unsigned char*)"spdy/3", 6 } + { (const unsigned char*)"spdy/2", 6, SPDYLAY_PROTO_SPDY2 }, + { (const unsigned char*)"spdy/3", 6, SPDYLAY_PROTO_SPDY3 } }; for(; i < inlen; i += in[i]+1) { int j; @@ -47,7 +48,7 @@ int spdylay_select_next_protocol(unsigned char **out, unsigned char *outlen, memcmp(&in[i+1], proto_list[j].proto, in[i]) == 0) { *out = (unsigned char*)&in[i+1]; *outlen = in[i]; - return 1; + return proto_list[j].version; } } if(in[i] == 8 && memcmp(&in[i+1], "http/1.1", in[i]) == 0) { diff --git a/tests/spdylay_npn_test.c b/tests/spdylay_npn_test.c index 5f8ce42b..3b28cc30 100644 --- a/tests/spdylay_npn_test.c +++ b/tests/spdylay_npn_test.c @@ -36,8 +36,8 @@ static void spdy2() }; unsigned char outlen; unsigned char* out; - CU_ASSERT(1 == spdylay_select_next_protocol(&out, &outlen, - spdy, sizeof(spdy))); + CU_ASSERT(SPDYLAY_PROTO_SPDY2 == + spdylay_select_next_protocol(&out, &outlen, spdy, sizeof(spdy))); CU_ASSERT(6 == outlen); CU_ASSERT(memcmp("spdy/2", out, outlen) == 0); }