aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2014-01-30 23:26:20 +0900
committerDaniel Stenberg <daniel@haxx.se>2014-01-30 17:45:53 +0100
commit88705ef80efcb5ee3ef75aea6f037f56f7e6dda1 (patch)
treeeaa922a3d6811085e600bbf8759949c61594157e
parent0952c9abccce1dd8ee19a53d38570a2515df70a9 (diff)
http2: Use nghttp2_session_mem_recv and nghttp2_session_upgrade
-rw-r--r--lib/http2.c81
1 files changed, 39 insertions, 42 deletions
diff --git a/lib/http2.c b/lib/http2.c
index c4b5a08bd..214b46961 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -103,41 +103,6 @@ static ssize_t send_callback(nghttp2_session *h2,
return written;
}
-/*
- * The implementation of nghttp2_recv_callback type. Here we read data from
- * the network and write them in |buf|. The capacity of |buf| is |length|
- * bytes. Returns the number of bytes stored in |buf|. See the documentation
- * of nghttp2_recv_callback for the details.
- */
-static ssize_t recv_callback(nghttp2_session *h2,
- uint8_t *buf, size_t length, int flags,
- void *userp)
-{
- struct connectdata *conn = (struct connectdata *)userp;
- ssize_t nread;
- CURLcode rc;
-
- infof(conn->data, "recv_callback() was called with length %d\n", length);
-
- rc = Curl_read_plain(conn->sock[FIRSTSOCKET], (char *)buf, length,
- &nread);
- (void)h2;
- (void)flags;
-
- if(CURLE_AGAIN == rc) {
- infof(conn->data, "recv_callback() returns NGHTTP2_ERR_WOULDBLOCK\n");
- return NGHTTP2_ERR_WOULDBLOCK;
- }
- else if(rc) {
- failf(conn->data, "Failed receiving HTTP2 data: %d", rc);
- return NGHTTP2_ERR_CALLBACK_FAILURE;
- }
- else
- infof(conn->data, "recv_callback() returns %d to nghttp2\n", nread);
-
- return nread;
-}
-
static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
void *userp)
{
@@ -289,7 +254,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
*/
static const nghttp2_session_callbacks callbacks = {
send_callback, /* nghttp2_send_callback */
- recv_callback, /* nghttp2_recv_callback */
+ NULL, /* nghttp2_recv_callback */
on_frame_recv, /* nghttp2_on_frame_recv_callback */
on_invalid_frame_recv, /* nghttp2_on_invalid_frame_recv_callback */
on_data_chunk_recv, /* nghttp2_on_data_chunk_recv_callback */
@@ -382,6 +347,8 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
return result;
}
+#define H2_BUFSIZE 4096
+
/*
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
* a regular CURLcode value.
@@ -389,18 +356,48 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
static ssize_t http2_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len, CURLcode *err)
{
- int rc;
+ CURLcode rc;
+ ssize_t rv;
+ ssize_t nread;
+ char inbuf[H2_BUFSIZE];
+
(void)sockindex; /* we always do HTTP2 on sockindex 0 */
conn->proto.httpc.mem = mem;
conn->proto.httpc.len = len;
- rc = nghttp2_session_recv(conn->proto.httpc.h2);
+ infof(conn->data, "http2_recv\n");
- if(rc < 0) {
- failf(conn->data, "nghttp2_session_recv() returned %d\n",
- rc);
- *err = CURLE_RECV_ERROR;
+ for(;;) {
+ rc = Curl_read_plain(conn->sock[FIRSTSOCKET], inbuf, H2_BUFSIZE, &nread);
+
+ if(rc == CURLE_AGAIN) {
+ *err = rc;
+ return -1;
+ }
+ if(rc) {
+ failf(conn->data, "Failed receiving HTTP2 data");
+ *err = CURLE_RECV_ERROR;
+ return 0;
+ }
+ infof(conn->data, "nread=%zd\n", nread);
+ if(!nread) {
+ *err = CURLE_RECV_ERROR;
+ return 0; /* TODO EOF? */
+ }
+ rv = nghttp2_session_mem_recv(conn->proto.httpc.h2,
+ (const uint8_t *)inbuf, nread);
+
+ if(nghttp2_is_fatal((int)rv)) {
+ failf(conn->data, "nghttp2_session_mem_recv() returned %d:%s\n",
+ rv, nghttp2_strerror((int)rv));
+ *err = CURLE_RECV_ERROR;
+ return 0;
+ }
+ if(rv < nread) {
+ /* Happens when NGHTTP2_ERR_PAUSE is returned from user callback */
+ break;
+ }
}
return len - conn->proto.httpc.len;
}