]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http2: enhance error messages on Curl_dyn* upon receiving headers
authorPeng-Yu Chen <pengyu@libstarrify.so>
Sun, 2 Mar 2025 17:15:21 +0000 (17:15 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 3 Mar 2025 09:30:54 +0000 (10:30 +0100)
This is a partial fix of #16535. The error message format is borrowed
from the existing code[1].

Sample message before:
    curl: (56) process_pending_input: nghttp2_session_mem_recv() returned -902:The user callback function failed

Sample message after:
    curl: (56) Error receiving HTTP2 header: 100(A value or data field grew larger than allowed)

[1]: https://github.com/curl/curl/blob/df672695e5992ad9b99819e9950de682e243cb48/lib/http2.c#L1999-L2000

Closes #16536

lib/http2.c

index 45436ff83a817b56a3dbac8462f1374af19c851d..b8cace3a4e8859a80ec4709dcb524f9536347944 100644 (file)
@@ -1500,6 +1500,12 @@ static int on_begin_headers(nghttp2_session *session,
   return 0;
 }
 
+static void report_header_error(struct Curl_easy *data, CURLcode result)
+{
+  failf(data, "Error receiving HTTP2 header: %d(%s)", result,
+        curl_easy_strerror(result));
+}
+
 /* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
 static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
                      const uint8_t *name, size_t namelen,
@@ -1599,8 +1605,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
     result = Curl_dynhds_add(&stream->resp_trailers,
                              (const char *)name, namelen,
                              (const char *)value, valuelen);
-    if(result)
+    if(result) {
+      report_header_error(data_s, result);
       return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
 
     return 0;
   }
@@ -1611,13 +1619,17 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
     char buffer[32];
     result = Curl_http_decode_status(&stream->status_code,
                                      (const char *)value, valuelen);
-    if(result)
+    if(result) {
+      report_header_error(data_s, result);
       return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
     msnprintf(buffer, sizeof(buffer), HTTP_PSEUDO_STATUS ":%u\r",
               stream->status_code);
     result = Curl_headers_push(data_s, buffer, CURLH_PSEUDO);
-    if(result)
+    if(result) {
+      report_header_error(data_s, result);
       return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
     Curl_dyn_reset(&ctx->scratch);
     result = Curl_dyn_addn(&ctx->scratch, STRCONST("HTTP/2 "));
     if(!result)
@@ -1627,8 +1639,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
     if(!result)
       h2_xfer_write_resp_hd(cf, data_s, stream, Curl_dyn_ptr(&ctx->scratch),
                             Curl_dyn_len(&ctx->scratch), FALSE);
-    if(result)
+    if(result) {
+      report_header_error(data_s, result);
       return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
     /* if we receive data for another handle, wake that up */
     if(CF_DATA_CURRENT(cf) != data_s)
       Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
@@ -1652,8 +1666,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
   if(!result)
     h2_xfer_write_resp_hd(cf, data_s, stream, Curl_dyn_ptr(&ctx->scratch),
                           Curl_dyn_len(&ctx->scratch), FALSE);
-  if(result)
+  if(result) {
+    report_header_error(data_s, result);
     return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
   /* if we receive data for another handle, wake that up */
   if(CF_DATA_CURRENT(cf) != data_s)
     Curl_expire(data_s, 0, EXPIRE_RUN_NOW);