mirror of
https://github.com/curl/curl.git
synced 2026-08-26 13:33:33 +03:00
http/3: add description for known server error codes
When a server resets a stream with an error code, list that code and its known name in the failure message of the transfer. Ref: #20195 Closes #20202
This commit is contained in:
parent
c25fdaf081
commit
f6e8531c03
5 changed files with 86 additions and 5 deletions
|
|
@ -1372,7 +1372,9 @@ static CURLcode recv_closed_stream(struct Curl_cfilter *cf,
|
||||||
(void)cf;
|
(void)cf;
|
||||||
*pnread = 0;
|
*pnread = 0;
|
||||||
if(stream->reset) {
|
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;
|
return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
|
||||||
}
|
}
|
||||||
else if(!stream->resp_hds_complete) {
|
else if(!stream->resp_hds_complete) {
|
||||||
|
|
|
||||||
|
|
@ -2076,9 +2076,9 @@ static CURLcode recv_closed_stream(struct Curl_cfilter *cf,
|
||||||
(void)cf;
|
(void)cf;
|
||||||
*pnread = 0;
|
*pnread = 0;
|
||||||
if(stream->reset) {
|
if(stream->reset) {
|
||||||
failf(data,
|
failf(data, "HTTP/3 stream %" PRId64 " reset by server (error 0x%" PRIx64
|
||||||
"HTTP/3 stream %" PRId64 " reset by server",
|
" %s)", stream->s.id, stream->error3,
|
||||||
stream->s.id);
|
vquic_h3_err_str(stream->error3));
|
||||||
return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
|
return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
|
||||||
}
|
}
|
||||||
else if(!stream->resp_hds_complete) {
|
else if(!stream->resp_hds_complete) {
|
||||||
|
|
|
||||||
|
|
@ -855,7 +855,9 @@ static CURLcode recv_closed_stream(struct Curl_cfilter *cf,
|
||||||
DEBUGASSERT(stream);
|
DEBUGASSERT(stream);
|
||||||
*pnread = 0;
|
*pnread = 0;
|
||||||
if(stream->reset) {
|
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;
|
result = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3;
|
||||||
CURL_TRC_CF(data, cf, "[%" PRIu64 "] cf_recv, was reset -> %d",
|
CURL_TRC_CF(data, cf, "[%" PRIu64 "] cf_recv, was reset -> %d",
|
||||||
stream->id, result);
|
stream->id, result);
|
||||||
|
|
|
||||||
|
|
@ -742,6 +742,56 @@ CURLcode Curl_conn_may_http3(struct Curl_easy *data,
|
||||||
return CURLE_OK;
|
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)
|
#if defined(USE_NGTCP2) || defined(USE_NGHTTP3)
|
||||||
|
|
||||||
static void *vquic_ngtcp2_malloc(size_t size, void *user_data)
|
static void *vquic_ngtcp2_malloc(size_t size, void *user_data)
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,33 @@
|
||||||
#define MAX_PKT_BURST 10
|
#define MAX_PKT_BURST 10
|
||||||
#define MAX_UDP_PAYLOAD_SIZE 1452
|
#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 {
|
struct cf_quic_ctx {
|
||||||
curl_socket_t sockfd; /* connected UDP socket */
|
curl_socket_t sockfd; /* connected UDP socket */
|
||||||
struct sockaddr_storage local_addr; /* address socket is bound to */
|
struct sockaddr_storage local_addr; /* address socket is bound to */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue