← Commit list

f6e8531c03

Stefan Eissing
Stefan Eissing
2026-01-07
SUCCESS Duration: 249s

Subject

http/3: add description for known server error codes

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/vquic/curl_ngtcp2.c+3 -1
@@ -1372,7 +1372,9 @@ static CURLcode recv_closed_stream(struct Curl_cfilter *cf,
(void)cf;
*pnread = 0;
if(stream->reset) {
- failf(data, "HTTP/3 stream %" PRId64 " reset by server", stream->id);
+ failf(data, "HTTP/3 stream %" PRId64 " reset by server (error 0x%" PRIx64
+ " %s)", stream->id, stream->error3,
+ vquic_h3_err_str(stream->error3));
return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
}
else if(!stream->resp_hds_complete) {
lib/vquic/curl_osslq.c+3 -3
@@ -2076,9 +2076,9 @@ static CURLcode recv_closed_stream(struct Curl_cfilter *cf,
(void)cf;
*pnread = 0;
if(stream->reset) {
- failf(data,
- "HTTP/3 stream %" PRId64 " reset by server",
- stream->s.id);
+ failf(data, "HTTP/3 stream %" PRId64 " reset by server (error 0x%" PRIx64
+ " %s)", stream->s.id, stream->error3,
+ vquic_h3_err_str(stream->error3));
return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
}
else if(!stream->resp_hds_complete) {
lib/vquic/curl_quiche.c+3 -1
@@ -855,7 +855,9 @@ static CURLcode recv_closed_stream(struct Curl_cfilter *cf,
DEBUGASSERT(stream);
*pnread = 0;
if(stream->reset) {
- failf(data, "HTTP/3 stream %" PRIu64 " reset by server", stream->id);
+ failf(data, "HTTP/3 stream %" PRId64 " reset by server (error 0x%" PRIx64
+ " %s)", stream->id, stream->error3,
+ vquic_h3_err_str(stream->error3));
result = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
CURL_TRC_CF(data, cf, "[%" PRIu64 "] cf_recv, was reset -> %d",
stream->id, result);
lib/vquic/vquic.c+50 -0
@@ -742,6 +742,56 @@ CURLcode Curl_conn_may_http3(struct Curl_easy *data,
return CURLE_OK;
}
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+const char *vquic_h3_err_str(uint64_t error_code)
+{
+ if(error_code <= UINT_MAX) {
+ switch((unsigned int)error_code) {
+ case CURL_H3_ERR_NO_ERROR:
+ return "NO_ERROR";
+ case CURL_H3_ERR_GENERAL_PROTOCOL_ERROR:
+ return "GENERAL_PROTOCOL_ERROR";
+ case CURL_H3_ERR_INTERNAL_ERROR:
+ return "INTERNAL_ERROR";
+ case CURL_H3_ERR_STREAM_CREATION_ERROR:
+ return "STREAM_CREATION_ERROR";
+ case CURL_H3_ERR_CLOSED_CRITICAL_STREAM:
+ return "CLOSED_CRITICAL_STREAM";
+ case CURL_H3_ERR_FRAME_UNEXPECTED:
+ return "FRAME_UNEXPECTED";
+ case CURL_H3_ERR_FRAME_ERROR:
+ return "FRAME_ERROR";
+ case CURL_H3_ERR_EXCESSIVE_LOAD:
+ return "EXCESSIVE_LOAD";
+ case CURL_H3_ERR_ID_ERROR:
+ return "ID_ERROR";
+ case CURL_H3_ERR_SETTINGS_ERROR:
+ return "SETTINGS_ERROR";
+ case CURL_H3_ERR_MISSING_SETTINGS:
+ return "MISSING_SETTINGS";
+ case CURL_H3_ERR_REQUEST_REJECTED:
+ return "REQUEST_REJECTED";
+ case CURL_H3_ERR_REQUEST_CANCELLED:
+ return "REQUEST_CANCELLED";
+ case CURL_H3_ERR_REQUEST_INCOMPLETE:
+ return "REQUEST_INCOMPLETE";
+ case CURL_H3_ERR_MESSAGE_ERROR:
+ return "MESSAGE_ERROR";
+ case CURL_H3_ERR_CONNECT_ERROR:
+ return "CONNECT_ERROR";
+ case CURL_H3_ERR_VERSION_FALLBACK:
+ return "VERSION_FALLBACK";
+ default:
+ break;
+ }
+ }
+ /* RFC 9114 ch. 8.1 + 9, reserved future error codes that are NO_ERROR */
+ if((error_code >= 0x21) && !((error_code - 0x21) % 0x1f))
+ return "NO_ERROR";
+ return "unknown";
+}
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
+
#if defined(USE_NGTCP2) || defined(USE_NGHTTP3)
static void *vquic_ngtcp2_malloc(size_t size, void *user_data)
lib/vquic/vquic_int.h+27 -0
@@ -32,6 +32,33 @@
#define MAX_PKT_BURST 10
#define MAX_UDP_PAYLOAD_SIZE 1452
+/* definitions from RFC 9114, ch 8.1 */
+typedef enum {
+ CURL_H3_ERR_NO_ERROR = 0x0100,
+ CURL_H3_ERR_GENERAL_PROTOCOL_ERROR = 0x0101,
+ CURL_H3_ERR_INTERNAL_ERROR = 0x0102,
+ CURL_H3_ERR_STREAM_CREATION_ERROR = 0x0103,
+ CURL_H3_ERR_CLOSED_CRITICAL_STREAM = 0x0104,
+ CURL_H3_ERR_FRAME_UNEXPECTED = 0x0105,
+ CURL_H3_ERR_FRAME_ERROR = 0x0106,
+ CURL_H3_ERR_EXCESSIVE_LOAD = 0x0107,
+ CURL_H3_ERR_ID_ERROR = 0x0108,
+ CURL_H3_ERR_SETTINGS_ERROR = 0x0109,
+ CURL_H3_ERR_MISSING_SETTINGS = 0x010a,
+ CURL_H3_ERR_REQUEST_REJECTED = 0x010b,
+ CURL_H3_ERR_REQUEST_CANCELLED = 0x010c,
+ CURL_H3_ERR_REQUEST_INCOMPLETE = 0x010d,
+ CURL_H3_ERR_MESSAGE_ERROR = 0x010e,
+ CURL_H3_ERR_CONNECT_ERROR = 0x010f,
+ CURL_H3_ERR_VERSION_FALLBACK = 0x0110,
+} vquic_h3_error;
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+const char *vquic_h3_err_str(uint64_t error_code);
+#else
+#define vquic_h3_err_str(x) ""
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
+
struct cf_quic_ctx {
curl_socket_t sockfd; /* connected UDP socket */
struct sockaddr_storage local_addr; /* address socket is bound to */