gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 111/220: ngtcp2: initial h3 request work


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 111/220: ngtcp2: initial h3 request work
Date: Thu, 12 Sep 2019 17:27:51 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit 368d444cc6d46d18747197d30dc483e93d53d8b7
Author: Daniel Stenberg <address@hidden>
AuthorDate: Mon Aug 12 11:10:56 2019 +0200

    ngtcp2: initial h3 request work
    
    Closes #4217
---
 lib/http.h         |   8 ++--
 lib/vquic/ngtcp2.c | 132 ++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 116 insertions(+), 24 deletions(-)

diff --git a/lib/http.h b/lib/http.h
index c27725d2a..945aceb56 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -174,14 +174,16 @@ struct HTTP {
   size_t pauselen; /* the number of bytes left in data */
   bool closed; /* TRUE on HTTP2 stream close */
   bool close_handled; /* TRUE if stream closure is handled by libcurl */
-  char *mem;     /* points to a buffer in memory to store received data */
-  size_t len;    /* size of the buffer 'mem' points to */
-  size_t memlen; /* size of data copied to mem */
 
   char **push_headers;       /* allocated array */
   size_t push_headers_used;  /* number of entries filled in */
   size_t push_headers_alloc; /* number of entries allocated */
 #endif
+#if defined(USE_NGHTTP2) || defined(USE_NGHTTP3)
+  char *mem;     /* points to a buffer in memory to store received data */
+  size_t len;    /* size of the buffer 'mem' points to */
+  size_t memlen; /* size of data copied to mem */
+#endif
 #if defined(USE_NGHTTP2) || defined(ENABLE_QUIC)
   /* fields used by both HTTP/2 and HTTP/3 */
   const uint8_t *upload_mem; /* points to a buffer to read from */
diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c
index c7a079817..fe8fe8ced 100644
--- a/lib/vquic/ngtcp2.c
+++ b/lib/vquic/ngtcp2.c
@@ -42,6 +42,7 @@
 #include "curl_memory.h"
 #include "memdebug.h"
 
+/* #define DEBUG_NGTCP2 1 */
 #define DEBUG_HTTP3
 #ifdef DEBUG_HTTP3
 #define H3BUGF(x) x
@@ -67,6 +68,7 @@ static ngtcp2_tstamp timestamp(void)
   return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS;
 }
 
+#ifdef DEBUG_NGTCP2
 static void quic_printf(void *user_data, const char *fmt, ...)
 {
   va_list ap;
@@ -76,6 +78,7 @@ static void quic_printf(void *user_data, const char *fmt, ...)
   va_end(ap);
   fprintf(stderr, "\n");
 }
+#endif
 
 static int setup_initial_crypto_context(struct connectdata *conn)
 {
@@ -169,7 +172,11 @@ static int setup_initial_crypto_context(struct connectdata 
*conn)
 static void quic_settings(ngtcp2_settings *s)
 {
   ngtcp2_settings_default(s);
+#ifdef DEBUG_NGTCP2
   s->log_printf = quic_printf;
+#else
+  s->log_printf = NULL;
+#endif
   s->initial_ts = timestamp();
   s->max_stream_data_bidi_local = QUIC_MAX_STREAMS;
   s->max_stream_data_bidi_remote = QUIC_MAX_STREAMS;
@@ -1137,7 +1144,8 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
  */
 int Curl_quic_ver(char *p, size_t len)
 {
-  return msnprintf(p, len, " ngtcp2/blabla nghttp3/bloblo");
+  return msnprintf(p, len, " ngtcp2/%s nghttp3/%s",
+                   NGTCP2_VERSION, NGHTTP3_VERSION);
 }
 
 static int ng_getsock(struct connectdata *conn, curl_socket_t *socks)
@@ -1215,16 +1223,27 @@ static int cb_h3_stream_close(nghttp3_conn *conn, 
int64_t stream_id,
 }
 
 static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id,
-                           const uint8_t *data, size_t datalen,
+                           const uint8_t *buf, size_t buflen,
                            void *user_data, void *stream_user_data)
 {
+  size_t ncopy;
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
   (void)conn;
   (void)stream_id;
-  (void)data;
-  (void)datalen;
   (void)user_data;
-  (void)stream_user_data;
-  fprintf(stderr, "cb_h3_recv_data CALLED\n");
+  fprintf(stderr, "cb_h3_recv_data CALLED with %d bytes\n",
+          buflen);
+
+  /* TODO: this needs to be handled properly */
+  DEBUGASSERT(buflen <= stream->len);
+
+  ncopy = CURLMIN(stream->len, buflen);
+  memcpy(stream->mem, buf, ncopy);
+  stream->len -= ncopy;
+  stream->memlen += ncopy;
+  stream->mem += ncopy;
+
   return 0;
 }
 
@@ -1241,14 +1260,48 @@ static int cb_h3_deferred_consume(nghttp3_conn *conn, 
int64_t stream_id,
   return 0;
 }
 
-static int cb_h3_begin_headers(nghttp3_conn *conn, int64_t stream_id,
-                               void *user_data, void *stream_user_data)
+/* Decode HTTP status code.  Returns -1 if no valid status code was
+   decoded. (duplicate from http2.c) */
+static int decode_status_code(const uint8_t *value, size_t len)
+{
+  int i;
+  int res;
+
+  if(len != 3) {
+    return -1;
+  }
+
+  res = 0;
+
+  for(i = 0; i < 3; ++i) {
+    char c = value[i];
+
+    if(c < '0' || c > '9') {
+      return -1;
+    }
+
+    res *= 10;
+    res += c - '0';
+  }
+
+  return res;
+}
+
+static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
+                             void *user_data, void *stream_user_data)
 {
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
   (void)conn;
   (void)stream_id;
   (void)user_data;
-  (void)stream_user_data;
-  fprintf(stderr, "cb_h3_begin_headers CALLED\n");
+
+  if(stream->memlen >= 2) {
+    memcpy(stream->mem, "\r\n", 2);
+    stream->len -= 2;
+    stream->memlen += 2;
+    stream->mem += 2;
+  }
   return 0;
 }
 
@@ -1257,15 +1310,33 @@ static int cb_h3_recv_header(nghttp3_conn *conn, 
int64_t stream_id,
                              nghttp3_rcbuf *value, uint8_t flags,
                              void *user_data, void *stream_user_data)
 {
+  nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
+  nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
+  size_t ncopy;
   (void)conn;
   (void)stream_id;
   (void)token;
-  (void)name;
-  (void)value;
   (void)flags;
   (void)user_data;
-  (void)stream_user_data;
-  fprintf(stderr, "cb_h3_recv_header CALLED\n");
+
+  if(h3name.len == sizeof(":status") - 1 &&
+     !memcmp(":status", h3name.base, h3name.len)) {
+    int status = decode_status_code(h3val.base, h3val.len);
+    DEBUGASSERT(status != -1);
+    msnprintf(stream->mem, stream->len, "HTTP/3 %03d \r\n", status);
+  }
+  else {
+    /* store as a HTTP1-style header */
+    msnprintf(stream->mem, stream->len, "%.*s: %.*s\n",
+              h3name.len, h3name.base, h3val.len, h3val.base);
+  }
+
+  ncopy = strlen(stream->mem);
+  stream->len -= ncopy;
+  stream->memlen += ncopy;
+  stream->mem += ncopy;
   return 0;
 }
 
@@ -1288,9 +1359,9 @@ static nghttp3_conn_callbacks ngh3_callbacks = {
   cb_h3_stream_close,
   cb_h3_recv_data,
   cb_h3_deferred_consume,
-  cb_h3_begin_headers,
+  NULL, /* begin_headers */
   cb_h3_recv_header,
-  NULL, /* end_headers */
+  cb_h3_end_headers,
   NULL, /* begin_trailers */
   cb_h3_recv_header,
   NULL, /* end_trailers */
@@ -1373,8 +1444,15 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
                                 CURLcode *curlcode)
 {
   curl_socket_t sockfd = conn->sock[sockindex];
-  (void)buf;
-  (void)buffersize;
+  struct HTTP *stream = conn->data->req.protop;
+
+  fprintf(stderr, "ngh3_stream_recv CALLED (easy %p)\n", conn->data);
+
+  /* remember where to store incoming data for this stream and how big the
+     buffer is */
+  stream->mem = buf;
+  stream->len = buffersize;
+  stream->memlen = 0;
 
   if(process_ingress(conn, sockfd)) {
     infof(conn->data, "ngh3_stream_recv returns on ingress\n");
@@ -1386,8 +1464,16 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
     return -1;
   }
 
-  *curlcode = CURLE_AGAIN;
+  if(stream->memlen) {
+    /* data arrived */
+    *curlcode = CURLE_OK;
+    infof(conn->data, "ngh3_stream_recv returns %zd bytes\n",
+          stream->memlen);
+    return stream->memlen;
+  }
 
+  infof(conn->data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n");
+  *curlcode = CURLE_AGAIN;
   return -1;
 }
 
@@ -1398,8 +1484,6 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
 static CURLcode http_request(struct connectdata *conn, const void *mem,
                              size_t len)
 {
-  /*
-   */
   struct HTTP *stream = conn->data->req.protop;
   size_t nheader;
   size_t i;
@@ -1582,6 +1666,12 @@ static CURLcode http_request(struct connectdata *conn, 
const void *mem,
     }
   }
 
+  stream->header_recvbuf = Curl_add_buffer_init();
+  if(!stream->header_recvbuf) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
   switch(data->set.httpreq) {
   case HTTPREQ_POST:
   case HTTPREQ_POST_FORM:

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]