Newer
Older
if((conn->handler == &Curl_handler_http2_ssl) ||
(conn->handler == &Curl_handler_http2))
return CURLE_OK; /* already done */
if(conn->handler->flags & PROTOPT_SSL)
conn->handler = &Curl_handler_http2_ssl;
else
conn->handler = &Curl_handler_http2;
result = Curl_http2_init(conn);
if(result)
return result;
infof(conn->data, "Using HTTP2, server supports multi-use\n");
httpc->error_code = NGHTTP2_NO_ERROR;
httpc->closed = FALSE;
httpc->header_recvbuf = Curl_add_buffer_init();
httpc->nread_header_recvbuf = 0;
httpc->data = NULL;
httpc->datalen = 0;
httpc->upload_left = 0;
httpc->upload_mem = NULL;
httpc->upload_len = 0;
conn->bundle->server_supports_pipelining = TRUE;
return CURLE_OK;
CURLcode Curl_http2_switched(struct connectdata *conn,
const char *mem, size_t nread)
struct http_conn *httpc = &conn->proto.httpc;
int rv;
struct SessionHandle *data = conn->data;
struct HTTP *stream = conn->data->req.protop;
result = Curl_http2_setup(conn);
if(result)
return result;
httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET];
httpc->send_underlying = (sending)conn->send[FIRSTSOCKET];
conn->recv[FIRSTSOCKET] = http2_recv;
conn->send[FIRSTSOCKET] = http2_send;
rv = (int) ((Curl_send*)httpc->send_underlying)
(conn, FIRSTSOCKET,
NGHTTP2_CLIENT_CONNECTION_PREFACE,
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN,
&result);
if(result)
/* TODO: This may get CURLE_AGAIN */
if(rv != 24) {
failf(data, "Only sent partial HTTP2 packet");
return CURLE_SEND_ERROR;
}
if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
/* stream 1 is opened implicitly on upgrade */
stream->stream_id = 1;
/* queue SETTINGS frame (again) */
rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
httpc->binlen, NULL);
if(rv != 0) {
failf(data, "nghttp2_session_upgrade() failed: %s(%d)",
nghttp2_strerror(rv), rv);
}
}
else {
/* stream ID is unknown at this point */
stream->stream_id = -1;
rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
if(rv != 0) {
failf(data, "nghttp2_submit_settings() failed: %s(%d)",
nghttp2_strerror(rv), rv);
}
}
rv = (int)nghttp2_session_mem_recv(httpc->h2, (const uint8_t*)mem, nread);
if(rv != (int)nread) {
failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
nghttp2_strerror(rv), rv);
return CURLE_HTTP2;
}
/* Try to send some frames since we may read SETTINGS already. */
rv = nghttp2_session_send(httpc->h2);
if(rv != 0) {
failf(data, "nghttp2_session_send() failed: %s(%d)",
nghttp2_strerror(rv), rv);
return CURLE_HTTP2;
}