Add Content-Length to HTTP requests
This commit is contained in:
@@ -3945,6 +3945,22 @@ void http_request_builder_target(HTTP_RequestBuilder builder,
|
||||
}
|
||||
}
|
||||
|
||||
HTTP_String s;
|
||||
|
||||
s = HTTP_STR("Connection: Close\r\n");
|
||||
byte_queue_write(&conn->output, s.ptr, s.len);
|
||||
|
||||
s = HTTP_STR("Content-Length: ");
|
||||
byte_queue_write(&conn->output, s.ptr, s.len);
|
||||
|
||||
conn->content_length_value_offset = byte_queue_offset(&conn->output);
|
||||
|
||||
#define TEN_SPACES " "
|
||||
_Static_assert(sizeof(TEN_SPACES) == 10+1);
|
||||
|
||||
s = HTTP_STR(TEN_SPACES "\r\n");
|
||||
byte_queue_write(&conn->output, s.ptr, s.len);
|
||||
|
||||
conn->state = HTTP_CLIENT_CONN_WAIT_HEADER;
|
||||
}
|
||||
|
||||
@@ -3984,9 +4000,8 @@ void http_request_builder_body(HTTP_RequestBuilder builder,
|
||||
|
||||
// Transition from WAIT_HEADER to WAIT_BODY if needed
|
||||
if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) {
|
||||
// End headers section
|
||||
// TODO: add Content-Length header
|
||||
byte_queue_write(&conn->output, "\r\n", 2);
|
||||
conn->content_length_offset = byte_queue_offset(&conn->output);
|
||||
conn->state = HTTP_CLIENT_CONN_WAIT_BODY;
|
||||
}
|
||||
|
||||
@@ -4040,8 +4055,8 @@ int http_request_builder_send(HTTP_RequestBuilder builder)
|
||||
goto error; // Early completion due to an error
|
||||
|
||||
if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) {
|
||||
// No body, just end headers
|
||||
byte_queue_write(&conn->output, "\r\n", 2);
|
||||
conn->content_length_offset = byte_queue_offset(&conn->output);
|
||||
conn->state = HTTP_CLIENT_CONN_WAIT_BODY;
|
||||
}
|
||||
|
||||
@@ -4051,6 +4066,14 @@ int http_request_builder_send(HTTP_RequestBuilder builder)
|
||||
if (byte_queue_error(&conn->output))
|
||||
goto error;
|
||||
|
||||
int content_length = byte_queue_size_from_offset(&conn->output, conn->content_length_offset);
|
||||
|
||||
char tmp[11];
|
||||
int len = snprintf(tmp, sizeof(tmp), "%d", content_length);
|
||||
assert(len > 0 && len < 11);
|
||||
|
||||
byte_queue_patch(&conn->output, conn->content_length_value_offset, tmp, len);
|
||||
|
||||
ConnectTarget target = url_to_connect_target(conn->url);
|
||||
bool secure = http_streq(conn->url.scheme, HTTP_STR("https"));
|
||||
if (socket_connect(&client->sockets, 1, &target, secure, conn->dont_verify_cert, conn) < 0)
|
||||
@@ -4263,6 +4286,7 @@ void http_client_process_events(HTTP_Client *client,
|
||||
|
||||
// Decouple from the socket
|
||||
socket_set_user(&client->sockets, events[i].handle, NULL);
|
||||
socket_close(&client->sockets, events[i].handle);
|
||||
|
||||
// Push to the ready queue
|
||||
assert(client->num_ready < HTTP_CLIENT_CAPACITY);
|
||||
|
||||
@@ -943,6 +943,16 @@ typedef struct {
|
||||
|
||||
// Parsed response once complete
|
||||
HTTP_Response response;
|
||||
|
||||
// This offset points to the first byte that comes
|
||||
// after the string "Content-Length: ".
|
||||
ByteQueueOffset content_length_value_offset;
|
||||
|
||||
// This one points to the first byte of the body.
|
||||
// This allows calculating the length of the request
|
||||
// content byte subtracting it from the offset reached
|
||||
// when the request is marked as done.
|
||||
ByteQueueOffset content_length_offset;
|
||||
} HTTP_ClientConn;
|
||||
|
||||
// Fields of this struct are private
|
||||
|
||||
+26
-3
@@ -316,6 +316,22 @@ void http_request_builder_target(HTTP_RequestBuilder builder,
|
||||
}
|
||||
}
|
||||
|
||||
HTTP_String s;
|
||||
|
||||
s = HTTP_STR("Connection: Close\r\n");
|
||||
byte_queue_write(&conn->output, s.ptr, s.len);
|
||||
|
||||
s = HTTP_STR("Content-Length: ");
|
||||
byte_queue_write(&conn->output, s.ptr, s.len);
|
||||
|
||||
conn->content_length_value_offset = byte_queue_offset(&conn->output);
|
||||
|
||||
#define TEN_SPACES " "
|
||||
_Static_assert(sizeof(TEN_SPACES) == 10+1);
|
||||
|
||||
s = HTTP_STR(TEN_SPACES "\r\n");
|
||||
byte_queue_write(&conn->output, s.ptr, s.len);
|
||||
|
||||
conn->state = HTTP_CLIENT_CONN_WAIT_HEADER;
|
||||
}
|
||||
|
||||
@@ -355,9 +371,8 @@ void http_request_builder_body(HTTP_RequestBuilder builder,
|
||||
|
||||
// Transition from WAIT_HEADER to WAIT_BODY if needed
|
||||
if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) {
|
||||
// End headers section
|
||||
// TODO: add Content-Length header
|
||||
byte_queue_write(&conn->output, "\r\n", 2);
|
||||
conn->content_length_offset = byte_queue_offset(&conn->output);
|
||||
conn->state = HTTP_CLIENT_CONN_WAIT_BODY;
|
||||
}
|
||||
|
||||
@@ -411,8 +426,8 @@ int http_request_builder_send(HTTP_RequestBuilder builder)
|
||||
goto error; // Early completion due to an error
|
||||
|
||||
if (conn->state == HTTP_CLIENT_CONN_WAIT_HEADER) {
|
||||
// No body, just end headers
|
||||
byte_queue_write(&conn->output, "\r\n", 2);
|
||||
conn->content_length_offset = byte_queue_offset(&conn->output);
|
||||
conn->state = HTTP_CLIENT_CONN_WAIT_BODY;
|
||||
}
|
||||
|
||||
@@ -422,6 +437,14 @@ int http_request_builder_send(HTTP_RequestBuilder builder)
|
||||
if (byte_queue_error(&conn->output))
|
||||
goto error;
|
||||
|
||||
int content_length = byte_queue_size_from_offset(&conn->output, conn->content_length_offset);
|
||||
|
||||
char tmp[11];
|
||||
int len = snprintf(tmp, sizeof(tmp), "%d", content_length);
|
||||
assert(len > 0 && len < 11);
|
||||
|
||||
byte_queue_patch(&conn->output, conn->content_length_value_offset, tmp, len);
|
||||
|
||||
ConnectTarget target = url_to_connect_target(conn->url);
|
||||
bool secure = http_streq(conn->url.scheme, HTTP_STR("https"));
|
||||
if (socket_connect(&client->sockets, 1, &target, secure, conn->dont_verify_cert, conn) < 0)
|
||||
|
||||
@@ -105,6 +105,16 @@ typedef struct {
|
||||
|
||||
// Parsed response once complete
|
||||
HTTP_Response response;
|
||||
|
||||
// This offset points to the first byte that comes
|
||||
// after the string "Content-Length: ".
|
||||
ByteQueueOffset content_length_value_offset;
|
||||
|
||||
// This one points to the first byte of the body.
|
||||
// This allows calculating the length of the request
|
||||
// content byte subtracting it from the offset reached
|
||||
// when the request is marked as done.
|
||||
ByteQueueOffset content_length_offset;
|
||||
} HTTP_ClientConn;
|
||||
|
||||
// Fields of this struct are private
|
||||
|
||||
Reference in New Issue
Block a user