Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
DimitriPapadopoulos committed Apr 24, 2020
1 parent f65bed6 commit c60dc70
Showing 1 changed file with 54 additions and 27 deletions.
81 changes: 54 additions & 27 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,21 @@ int http_receive(
uint32_t header_size = 0;
uint32_t content_size = 0;
int chunked = 0;
struct phr_chunked_decoder decoder = {}; // zero-clear

buffer = malloc(capacity + 1); // room for terminal '\0'
if (buffer == NULL)
return ERR_HTTP_NO_MEM;

while (1) {
int n;
int minor_version, status;
const char *msg;
size_t msg_len;
struct phr_header headers[100]; // FIXME
size_t num_headers = ARRAY_SIZE(headers);

/* read SSL stream into buffer as long as ERR_SSL_AGAIN */
while ((n = safe_ssl_read(tunnel->ssl_handle,
(uint8_t *) buffer + bytes_read,
capacity - bytes_read)) == ERR_SSL_AGAIN)
Expand All @@ -240,23 +247,22 @@ int http_receive(

log_debug_details("%s:\n%s\n", __func__, buffer);

if (!header_size) {
/* Have we reached the end of the HTTP header? */
int minor_version, status;
const char *msg;
size_t msg_len;
struct phr_header headers[100]; // FIXME
size_t num_headers = ARRAY_SIZE(headers);

if (content_size == 0 && !chunked) {
/* parse the HTTP response header */
n = phr_parse_response(buffer, bytes_read,
&minor_version, &status,
&msg, &msg_len,
headers, &num_headers,
last_bytes_read);
&minor_version, &status,
&msg, &msg_len,
headers, &num_headers,
last_bytes_read);
if (n > 0) {
header_size = n;
log_error("*** header_size: %u\n", header_size);
n = parse_response_header(headers, num_headers,
&content_size, &chunked);
if (content_size)
log_error("*** content_size: %u\n", content_size);
if (chunked)
log_error("*** chunked: %d\n", chunked);
if (n < 0) {
free(buffer);
return n;
Expand All @@ -271,24 +277,45 @@ int http_receive(
} else if (n == -2) {
/* response is partial, continue the loop */
} else {
/* failed to parse the response */
/* failed to parse the response header */
assert(n == -1);
free(buffer);
return ERR_HTTP_INVALID;
}
}

if (header_size) {
/* Have we reached the end of the HTTP body? */
if (chunked) {
static const char EOB[7] = "\r\n0\r\n\r\n";

/* Last chunk terminator. Done naively. */
if (bytes_read >= sizeof(EOB) &&
!memcmp(&buffer[bytes_read - sizeof(EOB)],
EOB, sizeof(EOB)))
break;
} else {
if (bytes_read >= header_size + content_size)
break;
if (chunked) {
size_t bufsz = bytes_read - header_size;

switch (phr_decode_chunked(&decoder,
&buffer[header_size],
&bufsz) {
default:
/* body is complete, with garbage on tail */
case 0:
/* body is complete */
break;
case -2:
/* body is incomplete, continue the loop */
break;
case -1:
/* failed to parse the chunked body */
assert(m == -1);
free(buffer);
return ERR_HTTP_INVALID;
}
//~ /* parse the HTTP response chunked body */
//~ static const char EOB[7] = "\r\n0\r\n\r\n";

//~ /* Last chunk terminator. Done naively. */
//~ if (bytes_read >= sizeof(EOB) &&
//~ !memcmp(&buffer[bytes_read - sizeof(EOB)],
//~ EOB, sizeof(EOB)))
//~ break;
} else if (content_size > 0) {
/* read until the end of the HTTP response body */
if (bytes_read >= header_size + content_size) {
buffer[bytes_read] = '\0';
break;
}
}

Expand Down

0 comments on commit c60dc70

Please sign in to comment.