Made spdylay_select_next_protocol() return SPDY protocol version if one of

SPDY versions is selected.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-03-02 22:52:01 +09:00
parent 4bb3c9370d
commit 8fd2fabef8
4 changed files with 16 additions and 10 deletions

View File

@ -472,7 +472,7 @@ int select_next_proto_cb(SSL* ssl,
} }
std::string& next_proto = *(std::string*)arg; std::string& next_proto = *(std::string*)arg;
if(next_proto.empty()) { 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::cerr << "Server did not advertise spdy/2 or spdy/3 protocol."
<< std::endl; << std::endl;
abort(); abort();

View File

@ -758,8 +758,11 @@ int spdylay_submit_goaway(spdylay_session *session, uint32_t status_code);
* *
* The selection algorithm is as follows: * The selection algorithm is as follows:
* *
* 1. If server's list contains "spdy/2", this function selects * 1. If server's list contains SPDY versions the spdylay library
* "spdy/2" and returns 1. The following steps are not taken. * 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 * 2. If server's list contains "http/1.1", this function selects
* "http/1.1" and returns 0. The following step is not taken. * "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, * const unsigned char *in, unsigned int inlen,
* void *arg) * void *arg)
* { * {
* if (spdylay_select_next_protocol(out, outlen, in, inlen) == 1) { * int version;
* ((MyType*)arg)->spdy_version = spdylay_npn_get_version(*out, *outlen); * version = spdylay_select_next_protocol(out, outlen, in, inlen);
* if(version > 0) {
* ((MyType*)arg)->spdy_version = version;
* } * }
* return SSL_TLSEXT_ERR_OK; * return SSL_TLSEXT_ERR_OK;
* } * }

View File

@ -29,6 +29,7 @@
typedef struct { typedef struct {
const unsigned char *proto; const unsigned char *proto;
uint8_t len; uint8_t len;
uint16_t version;
} spdylay_npn_proto; } spdylay_npn_proto;
int spdylay_select_next_protocol(unsigned char **out, unsigned char *outlen, 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; int http_selected = 0;
unsigned int i = 0; unsigned int i = 0;
static const spdylay_npn_proto proto_list[] = { static const spdylay_npn_proto proto_list[] = {
{ (const unsigned char*)"spdy/2", 6 }, { (const unsigned char*)"spdy/2", 6, SPDYLAY_PROTO_SPDY2 },
{ (const unsigned char*)"spdy/3", 6 } { (const unsigned char*)"spdy/3", 6, SPDYLAY_PROTO_SPDY3 }
}; };
for(; i < inlen; i += in[i]+1) { for(; i < inlen; i += in[i]+1) {
int j; 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) { memcmp(&in[i+1], proto_list[j].proto, in[i]) == 0) {
*out = (unsigned char*)&in[i+1]; *out = (unsigned char*)&in[i+1];
*outlen = in[i]; *outlen = in[i];
return 1; return proto_list[j].version;
} }
} }
if(in[i] == 8 && memcmp(&in[i+1], "http/1.1", in[i]) == 0) { if(in[i] == 8 && memcmp(&in[i+1], "http/1.1", in[i]) == 0) {

View File

@ -36,8 +36,8 @@ static void spdy2()
}; };
unsigned char outlen; unsigned char outlen;
unsigned char* out; unsigned char* out;
CU_ASSERT(1 == spdylay_select_next_protocol(&out, &outlen, CU_ASSERT(SPDYLAY_PROTO_SPDY2 ==
spdy, sizeof(spdy))); spdylay_select_next_protocol(&out, &outlen, spdy, sizeof(spdy)));
CU_ASSERT(6 == outlen); CU_ASSERT(6 == outlen);
CU_ASSERT(memcmp("spdy/2", out, outlen) == 0); CU_ASSERT(memcmp("spdy/2", out, outlen) == 0);
} }