Skip to content

Commit

Permalink
quiche: when *recv_body() returns data, drain it before polling again
Browse files Browse the repository at this point in the history
Assisted-by: Lucas Pardue

Closes #8429
  • Loading branch information
bagder committed Feb 11, 2022
1 parent 053c27c commit 6883180
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 46 deletions.
106 changes: 60 additions & 46 deletions lib/vquic/quiche.c
Expand Up @@ -589,59 +589,73 @@ static ssize_t h3_stream_recv(struct Curl_easy *data,
return -1;
}

while(recvd < 0) {
int64_t s = quiche_h3_conn_poll(qs->h3c, qs->conn, &ev);
if(s < 0)
/* nothing more to do */
break;

if(s != stream->stream3_id) {
/* another transfer, ignore for now */
infof(data, "Got h3 for stream %u, expects %u",
s, stream->stream3_id);
continue;
if(qs->h3_recving) {
/* body receiving state */
rcode = quiche_h3_recv_body(qs->h3c, qs->conn, stream->stream3_id,
(unsigned char *)buf, buffersize);
if(rcode <= 0) {
recvd = -1;
qs->h3_recving = FALSE;
}

switch(quiche_h3_event_type(ev)) {
case QUICHE_H3_EVENT_HEADERS:
rc = quiche_h3_event_for_each_header(ev, cb_each_header, &headers);
if(rc) {
*curlcode = rc;
failf(data, "Error in HTTP/3 response header");
else
recvd = rcode;
}
else {
while(recvd < 0) {
int64_t s = quiche_h3_conn_poll(qs->h3c, qs->conn, &ev);
if(s < 0)
/* nothing more to do */
break;

if(s != stream->stream3_id) {
/* another transfer, ignore for now */
infof(data, "Got h3 for stream %u, expects %u",
s, stream->stream3_id);
continue;
}
recvd = headers.nlen;
break;
case QUICHE_H3_EVENT_DATA:
if(!stream->firstbody) {
/* add a header-body separator CRLF */
buf[0] = '\r';
buf[1] = '\n';
buf += 2;
buffersize -= 2;
stream->firstbody = TRUE;
recvd = 2; /* two bytes already */
}
else
recvd = 0;
rcode = quiche_h3_recv_body(qs->h3c, qs->conn, s, (unsigned char *)buf,
buffersize);
if(rcode <= 0) {
recvd = -1;

switch(quiche_h3_event_type(ev)) {
case QUICHE_H3_EVENT_HEADERS:
rc = quiche_h3_event_for_each_header(ev, cb_each_header, &headers);
if(rc) {
*curlcode = rc;
failf(data, "Error in HTTP/3 response header");
break;
}
recvd = headers.nlen;
break;
case QUICHE_H3_EVENT_DATA:
if(!stream->firstbody) {
/* add a header-body separator CRLF */
buf[0] = '\r';
buf[1] = '\n';
buf += 2;
buffersize -= 2;
stream->firstbody = TRUE;
recvd = 2; /* two bytes already */
}
else
recvd = 0;
rcode = quiche_h3_recv_body(qs->h3c, qs->conn, s, (unsigned char *)buf,
buffersize);
if(rcode <= 0) {
recvd = -1;
break;
}
qs->h3_recving = TRUE;
recvd += rcode;
break;

case QUICHE_H3_EVENT_FINISHED:
streamclose(conn, "End of stream");
recvd = 0; /* end of stream */
break;
default:
break;
}
recvd += rcode;
break;

case QUICHE_H3_EVENT_FINISHED:
streamclose(conn, "End of stream");
recvd = 0; /* end of stream */
break;
default:
break;
quiche_h3_event_free(ev);
}

quiche_h3_event_free(ev);
}
if(flush_egress(data, sockfd, qs)) {
*curlcode = CURLE_SEND_ERROR;
Expand Down
1 change: 1 addition & 0 deletions lib/vquic/quiche.h
Expand Up @@ -46,6 +46,7 @@ struct quicsocket {
uint32_t version;
SSL_CTX *sslctx;
SSL *ssl;
bool h3_recving; /* TRUE when in h3-body-reading state */
};

#endif
Expand Down

0 comments on commit 6883180

Please sign in to comment.