struct curltime started_at; /* time the current attempt started */
struct curltime handshake_at; /* time connect handshake finished */
struct uint_hash streams; /* hash `data->mid` to `stream_ctx` */
- struct dynbuf scratch; /* temp buffer for header construction */
+ struct dynbuf h1hdr; /* temp buffer for header construction */
struct bufq writebuf; /* temp buffer for writing bodies */
curl_off_t data_recvd;
BIT(initialized);
debug_log_init = 1;
}
#endif
- curlx_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER);
+ curlx_dyn_init(&ctx->h1hdr, CURL_MAX_HTTP_HEADER);
Curl_uint32_hash_init(&ctx->streams, 63, h3_stream_hash_free);
Curl_bufq_init2(&ctx->writebuf, H3_STREAM_CHUNK_SIZE, H3_STREAM_RECV_CHUNKS,
BUFQ_OPT_SOFT_LIMIT);
Curl_ssl_peer_cleanup(&ctx->peer);
vquic_ctx_free(&ctx->q);
Curl_uint32_hash_destroy(&ctx->streams);
- curlx_dyn_free(&ctx->scratch);
+ curlx_dyn_free(&ctx->h1hdr);
Curl_bufq_free(&ctx->writebuf);
}
curlx_free(ctx);
struct h3_stream_ctx *stream;
};
+static bool is_valid_h3_header(const uint8_t *hdr, size_t hlen)
+{
+ while(hlen--) {
+ switch(*hdr++) {
+ case '\n':
+ case '\r':
+ case '\0':
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
static int cb_each_header(uint8_t *name, size_t name_len,
uint8_t *value, size_t value_len,
void *argp)
struct Curl_easy *data = x->data;
struct h3_stream_ctx *stream = x->stream;
struct cf_quiche_ctx *ctx = cf->ctx;
- CURLcode result;
+ CURLcode result = CURLE_OK;
if(!stream || stream->xfer_result)
return 1; /* abort iteration */
- if((name_len == 7) && !strncmp(HTTP_PSEUDO_STATUS, (char *)name, 7)) {
- curlx_dyn_reset(&ctx->scratch);
+ if((name_len == 7) && !strncmp(HTTP_PSEUDO_STATUS, (char *)name, 7) &&
+ is_valid_h3_header(value, value_len)) {
+ curlx_dyn_reset(&ctx->h1hdr);
result = Curl_http_decode_status(&stream->status_code,
(const char *)value, value_len);
if(!result)
- result = curlx_dyn_addn(&ctx->scratch, STRCONST("HTTP/3 "));
+ result = curlx_dyn_addn(&ctx->h1hdr, STRCONST("HTTP/3 "));
if(!result)
- result = curlx_dyn_addn(&ctx->scratch,
- (const char *)value, value_len);
+ result = curlx_dyn_addn(&ctx->h1hdr, (const char *)value, value_len);
if(!result)
- result = curlx_dyn_addn(&ctx->scratch, STRCONST(" \r\n"));
+ result = curlx_dyn_addn(&ctx->h1hdr, STRCONST(" \r\n"));
if(!result)
- cf_quiche_write_hd(cf, data, stream, curlx_dyn_ptr(&ctx->scratch),
- curlx_dyn_len(&ctx->scratch), FALSE);
+ cf_quiche_write_hd(cf, data, stream, curlx_dyn_ptr(&ctx->h1hdr),
+ curlx_dyn_len(&ctx->h1hdr), FALSE);
CURL_TRC_CF(data, cf, "[%" PRId64 "] status: %s",
- stream->id, curlx_dyn_ptr(&ctx->scratch));
+ stream->id, curlx_dyn_ptr(&ctx->h1hdr));
}
else {
- /* store as an HTTP1-style header */
- CURL_TRC_CF(data, cf, "[%" PRId64 "] header: %.*s: %.*s",
- stream->id, (int)name_len, name,
- (int)value_len, value);
- curlx_dyn_reset(&ctx->scratch);
- result = curlx_dyn_addn(&ctx->scratch,
- (const char *)name, name_len);
- if(!result)
- result = curlx_dyn_addn(&ctx->scratch, STRCONST(": "));
- if(!result)
- result = curlx_dyn_addn(&ctx->scratch,
- (const char *)value, value_len);
- if(!result)
- result = curlx_dyn_addn(&ctx->scratch, STRCONST("\r\n"));
- if(!result)
- cf_quiche_write_hd(cf, data, stream, curlx_dyn_ptr(&ctx->scratch),
- curlx_dyn_len(&ctx->scratch), FALSE);
+ if(is_valid_h3_header(value, value_len) &&
+ is_valid_h3_header(name, name_len)) {
+ /* store as an HTTP1-style header */
+ CURL_TRC_CF(data, cf, "[%" PRId64 "] header: %.*s: %.*s",
+ stream->id, (int)name_len, name,
+ (int)value_len, value);
+ curlx_dyn_reset(&ctx->h1hdr);
+ result = curlx_dyn_addn(&ctx->h1hdr, (const char *)name, name_len);
+ if(!result)
+ result = curlx_dyn_addn(&ctx->h1hdr, STRCONST(": "));
+ if(!result)
+ result = curlx_dyn_addn(&ctx->h1hdr, (const char *)value, value_len);
+ if(!result)
+ result = curlx_dyn_addn(&ctx->h1hdr, STRCONST("\r\n"));
+ if(!result)
+ cf_quiche_write_hd(cf, data, stream, curlx_dyn_ptr(&ctx->h1hdr),
+ curlx_dyn_len(&ctx->h1hdr), FALSE);
+ }
+ else
+ CURL_TRC_CF(x->data, x->cf, "[%" PRIu64 "] ignore %zu bytes bad header",
+ stream->id, value_len + name_len);
}
if(result) {