1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

http2: handle 101 responses and switch to HTTP2

This commit is contained in:
Daniel Stenberg 2013-09-12 13:51:04 +02:00
parent 8bcf677a30
commit 8d3608f2ad
4 changed files with 67 additions and 5 deletions

View File

@ -2872,10 +2872,27 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
k->header = TRUE; k->header = TRUE;
k->headerline = 0; /* restart the header line counter */ k->headerline = 0; /* restart the header line counter */
/* if we did wait for this do enable write now! */ /* "A user agent MAY ignore unexpected 1xx status responses." */
if(k->exp100) { switch(k->httpcode) {
k->exp100 = EXP100_SEND_DATA; case 100:
k->keepon |= KEEP_SEND; /* if we did wait for this do enable write now! */
if(k->exp100) {
k->exp100 = EXP100_SEND_DATA;
k->keepon |= KEEP_SEND;
}
break;
case 101:
/* Switching Protocols */
if(k->upgr101 == UPGR101_REQUESTED) {
infof(data, "Received 101\n");
k->upgr101 = UPGR101_RECEIVED;
/* switch to http2 now */
Curl_http2_switched(conn);
}
break;
default:
break;
} }
} }
else { else {

View File

@ -37,6 +37,32 @@
/* include memdebug.h last */ /* include memdebug.h last */
#include "memdebug.h" #include "memdebug.h"
/*
* HTTP2 handler interface. This isn't added to the general list of protocols
* but will be used at run-time when the protocol is dynamically switched from
* HTTP to HTTP2.
*/
const struct Curl_handler Curl_handler_http2 = {
"HTTP2", /* scheme */
ZERO_NULL, /* setup_connection */
ZERO_NULL, /* do_it */
ZERO_NULL , /* done */
ZERO_NULL, /* do_more */
ZERO_NULL, /* connect_it */
ZERO_NULL, /* connecting */
ZERO_NULL, /* doing */
ZERO_NULL, /* proto_getsock */
ZERO_NULL, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_HTTP, /* defport */
0, /* protocol */
PROTOPT_NONE /* flags */
};
/* /*
* Store nghttp2 version info in this buffer, Prefix with a space. Return * Store nghttp2 version info in this buffer, Prefix with a space. Return
* total length written. * total length written.
@ -138,6 +164,7 @@ CURLcode Curl_http2_request(Curl_send_buffer *req,
ssize_t binlen; ssize_t binlen;
char *base64; char *base64;
size_t blen; size_t blen;
struct SingleRequest *k = &conn->data->req;
if(!conn->proto.httpc.h2) { if(!conn->proto.httpc.h2) {
/* The nghttp2 session is not yet setup, do it */ /* The nghttp2 session is not yet setup, do it */
@ -176,7 +203,16 @@ CURLcode Curl_http2_request(Curl_send_buffer *req,
NGHTTP2_PROTO_VERSION_ID, base64); NGHTTP2_PROTO_VERSION_ID, base64);
free(base64); free(base64);
k->upgr101 = UPGR101_REQUESTED;
return result; return result;
} }
void Curl_http2_switched(struct connectdata *conn)
{
/* we are switched! */
conn->handler = &Curl_handler_http2;
infof(conn->data, "We have switched to HTTP2\n");
}
#endif #endif

View File

@ -34,8 +34,10 @@ int Curl_http2_ver(char *p, size_t len);
CURLcode Curl_http2_request(Curl_send_buffer *req, CURLcode Curl_http2_request(Curl_send_buffer *req,
struct connectdata *conn); struct connectdata *conn);
void Curl_http2_switched(struct connectdata *conn);
#else /* USE_NGHTTP2 */ #else /* USE_NGHTTP2 */
#define Curl_http2_request(x,y) CURLE_OK #define Curl_http2_request(x,y) CURLE_OK
#define Curl_http2_switched(x)
#endif #endif
#endif /* HEADER_CURL_HTTP2_H */ #endif /* HEADER_CURL_HTTP2_H */

View File

@ -580,7 +580,6 @@ struct Curl_async {
typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *); typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *);
typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool); typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
enum expect100 { enum expect100 {
EXP100_SEND_DATA, /* enough waiting, just send the body now */ EXP100_SEND_DATA, /* enough waiting, just send the body now */
EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */ EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */
@ -589,6 +588,13 @@ enum expect100 {
EXP100_FAILED /* used on 417 Expectation Failed */ EXP100_FAILED /* used on 417 Expectation Failed */
}; };
enum upgrade101 {
UPGR101_INIT, /* default state */
UPGR101_REQUESTED, /* upgrade requested */
UPGR101_RECEIVED, /* response received */
UPGR101_WORKING /* talking upgraded protocol */
};
/* /*
* Request specific data in the easy handle (SessionHandle). Previously, * Request specific data in the easy handle (SessionHandle). Previously,
* these members were on the connectdata struct but since a conn struct may * these members were on the connectdata struct but since a conn struct may
@ -639,6 +645,7 @@ struct SingleRequest {
'RTSP/1.? XXX' line */ 'RTSP/1.? XXX' line */
struct timeval start100; /* time stamp to wait for the 100 code from */ struct timeval start100; /* time stamp to wait for the 100 code from */
enum expect100 exp100; /* expect 100 continue state */ enum expect100 exp100; /* expect 100 continue state */
enum upgrade101 upgr101; /* 101 upgrade state */
int auto_decoding; /* What content encoding. sec 3.5, RFC2616. */ int auto_decoding; /* What content encoding. sec 3.5, RFC2616. */