Always accept SPDY/3 style name/value pairs from spdylay_submit_* and

translate them into SPDY/2 as needed.
This commit is contained in:
Tatsuhiro Tsujikawa
2012-03-06 23:43:45 +09:00
parent 7d9a7b3069
commit 00abfc8dd3
8 changed files with 187 additions and 44 deletions

View File

@@ -563,24 +563,7 @@ void* spdylay_session_get_stream_user_data(spdylay_session *session,
* the lowest priority is 3. If the |session| is initialized with the
* version SPDYLAY_PROTO_SPDY3, the lowest priority is 7.
*
* If |session| is initialized with the version SPDYLAY_PROTO_SPDY2,
* |nv| must include following name/value pairs:
*
* "method"
* HTTP method (e.g., "GET", "POST", "HEAD", etc)
* "scheme"
* URI scheme (e.g., "https")
* "url"
* Absolute path and parameters of this request (e.g., "/foo",
* "/foo;bar;haz?h=j&y=123")
* "version"
* HTTP version (e.g., "HTTP/1.1")
*
* The "host" name/value pair (this is the same as the HTTP "Host"
* header field) is also required by some hosts.
*
* If |session| is initialized with the version SPDYLAY_PROTO_SPDY3,
* |nv| must include following name/value pairs:
* The |nv| must include following name/value pairs:
*
* ":method"
* HTTP method (e.g., "GET", "POST", "HEAD", etc)
@@ -596,6 +579,10 @@ void* spdylay_session_get_stream_user_data(spdylay_session *session,
* "example.org:443"). This is the same as the HTTP "Host" header
* field.
*
* If the |session| is initialized with the version
* SPDYLAY_PROTO_SPDY2, the above names are translated to "method",
* "scheme", "url", "version" and "host" respectively.
*
* This function creates copies of all name/value pairs in |nv|. It
* also lower-cases all names in |nv|.
*
@@ -637,22 +624,17 @@ int spdylay_submit_request(spdylay_session *session, uint8_t pri,
* Submits SYN_REPLY frame and optionally one or more DATA frames
* against stream |stream_id|.
*
* If |session| is initialized with the version SPDYLAY_PROTO_SPDY2,
* |nv| must include following name/value pairs:
*
* "status"
* HTTP status code (e.g., "200" or "200 OK")
* "version"
* HTTP response version (e.g., "HTTP/1.1")
*
* If |session| is initialized with the version SPDYLAY_PROTO_SPDY3,
* |nv| must include following name/value pairs:
* The |nv| must include following name/value pairs:
*
* ":status"
* HTTP status code (e.g., "200" or "200 OK")
* ":version"
* HTTP response version (e.g., "HTTP/1.1")
*
* If the |session| is initialized with the version
* SPDYLAY_PROTO_SPDY2, the above names are translated to "status" and
* "version" respectively.
*
* This function creates copies of all name/value pairs in |nv|. It
* also lower-cases all names in |nv|.
*

View File

@@ -376,6 +376,43 @@ char** spdylay_frame_nv_norm_copy(const char **nv)
return nv_copy;
}
/* Table to translate SPDY/3 header names to SPDY/2. */
static char *spdylay_nv_3to2[] = {
":host", "host",
":method", "method",
":path", "url",
":scheme", "scheme",
":status", "status",
":version", "version",
NULL
};
void spdylay_frame_nv_3to2(char **nv)
{
int i, j;
for(i = 0; nv[i]; i += 2) {
for(j = 0; spdylay_nv_3to2[j]; j += 2) {
if(strcmp(nv[i], spdylay_nv_3to2[j]) == 0) {
nv[i] = spdylay_nv_3to2[j+1];
break;
}
}
}
}
void spdylay_frame_nv_2to3(char **nv)
{
int i, j;
for(i = 0; nv[i]; i += 2) {
for(j = 0; spdylay_nv_3to2[j]; j += 2) {
if(strcmp(nv[i], spdylay_nv_3to2[j+1]) == 0) {
nv[i] = spdylay_nv_3to2[j];
break;
}
}
}
}
void spdylay_frame_syn_stream_init(spdylay_syn_stream *frame,
uint16_t version, uint8_t flags,
int32_t stream_id, int32_t assoc_stream_id,

View File

@@ -595,6 +595,16 @@ void spdylay_frame_nv_downcase(char **nv);
*/
char** spdylay_frame_nv_norm_copy(const char **nv);
/*
* Translates the |nv| in SPDY/3 header names into SPDY/2.
*/
void spdylay_frame_nv_3to2(char **nv);
/*
* Translates the |nv| in SPDY/2 header names into SPDY/3.
*/
void spdylay_frame_nv_2to3(char **nv);
/*
* Makes copy of |iv| and return the copy. The |niv| is the number of
* entries in |iv|. This function returns the pointer to the copy if

View File

@@ -552,12 +552,18 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
stream_id = session->next_stream_id;
item->frame->syn_stream.stream_id = stream_id;
session->next_stream_id += 2;
if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_3to2(item->frame->syn_stream.nv);
}
framebuflen = spdylay_frame_pack_syn_stream(&session->aob.framebuf,
&session->aob.framebufmax,
&session->nvbuf,
&session->nvbuflen,
&item->frame->syn_stream,
&session->hd_deflater);
if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_2to3(item->frame->syn_stream.nv);
}
if(framebuflen < 0) {
return framebuflen;
}
@@ -576,12 +582,18 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
item->frame->syn_reply.stream_id)) {
return SPDYLAY_ERR_INVALID_FRAME;
}
if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_3to2(item->frame->syn_reply.nv);
}
framebuflen = spdylay_frame_pack_syn_reply(&session->aob.framebuf,
&session->aob.framebufmax,
&session->nvbuf,
&session->nvbuflen,
&item->frame->syn_reply,
&session->hd_deflater);
if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_2to3(item->frame->syn_reply.nv);
}
if(framebuflen < 0) {
return framebuflen;
}
@@ -620,12 +632,18 @@ static ssize_t spdylay_session_prep_frame(spdylay_session *session,
item->frame->headers.stream_id)) {
return SPDYLAY_ERR_INVALID_FRAME;
}
if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_3to2(item->frame->headers.nv);
}
framebuflen = spdylay_frame_pack_headers(&session->aob.framebuf,
&session->aob.framebufmax,
&session->nvbuf,
&session->nvbuflen,
&item->frame->headers,
&session->hd_deflater);
if(session->version == SPDYLAY_PROTO_SPDY2) {
spdylay_frame_nv_2to3(item->frame->headers.nv);
}
if(framebuflen < 0) {
return framebuflen;
}