Skip to content

CDRIVER-4454 Some HTTP Fixes #1103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/libmongoc/src/mongoc/mcd-azure.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ mcd_azure_imds_request_init (mcd_azure_imds_request *req)
_mongoc_http_request_init (&req->req);
// The HTTP host of the IMDS server
req->req.host = "169.254.169.254";
req->req.port = 80;
// No body
req->req.body = "";
// We GET
Expand Down
40 changes: 38 additions & 2 deletions src/libmongoc/src/mongoc/mongoc-http.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ _mongoc_http_render_request_head (const mongoc_http_request_t *req)
bson_free (path);

/* Always add Host header. */
bson_string_append_printf (string, "Host: %s\r\n", req->host);
bson_string_append_printf (string, "Host: %s:%d\r\n", req->host, req->port);
/* Always add Connection: close header to ensure server closes connection. */
bson_string_append_printf (string, "Connection: close\r\n");
/* Add Content-Length if body is included. */
Expand Down Expand Up @@ -175,7 +175,7 @@ _mongoc_http_send (const mongoc_http_request_t *req,
goto fail;
}

if (req->body) {
if (req->body && req->body_len) {
iovec.iov_base = (void *) req->body;
iovec.iov_len = req->body_len;
if (!_mongoc_stream_writev_full (stream, &iovec, 1, timeout_ms, error)) {
Expand Down Expand Up @@ -206,6 +206,42 @@ _mongoc_http_send (const mongoc_http_request_t *req,
}

http_response_str = (char *) http_response_buf.data;
const char *const resp_end_ptr =
http_response_str + http_response_buf.datalen;

const char *proto_leader = "HTTP/1.0 ";
ptr = strstr (http_response_str, proto_leader);
if (!ptr) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"No HTTP version leader in HTTP response");
goto fail;
}

ptr += strlen (proto_leader);
ssize_t remain = resp_end_ptr - ptr;
if (remain < 4) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Short read in HTTP response");
goto fail;
}

char status_buf[4] = {0};
memcpy (status_buf, ptr, 3);
char *status_endptr;
res->status = strtol (status_buf, &status_endptr, 10);
if (status_endptr != status_buf + 3) {
bson_set_error (error,
MONGOC_ERROR_STREAM,
MONGOC_ERROR_STREAM_SOCKET,
"Invalid HTTP response status string %*.s",
4,
status_buf);
goto fail;
}

/* Find the end of the headers. */
ptr = strstr (http_response_str, header_delimiter);
Expand Down
2 changes: 1 addition & 1 deletion src/libmongoc/tests/test-mcd-azure-imds.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ _test_http_req (void)
"/metadata/identity/oauth2/"
"token?api-version=2018-02-01&resource=https%3A%2F%2Fvault."
"azure.net HTTP/1.0\r\n"
"Host: 169.254.169.254\r\n"
"Host: 169.254.169.254:80\r\n"
"Connection: close\r\n"
"Metadata: true\r\n"
"Accept: application/json\r\n"
Expand Down
7 changes: 7 additions & 0 deletions src/libmongoc/tests/test-mongoc-http.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,13 @@ test_mongoc_http (void *unused)
req.method = "GET";
req.host = "example.com";
req.port = 80;
// Empty body is okay
req.body = "";
req.body_len = 0;
r = _mongoc_http_send (&req, 10000, false, NULL, &res, &error);
ASSERT_CMPINT (res.status, ==, 200);
ASSERT_OR_PRINT (r, error);
ASSERT_CMPINT (res.body_len, >, 0);
_mongoc_http_response_cleanup (&res);

/* Basic POST request with a body. */
Expand All @@ -46,7 +51,9 @@ test_mongoc_http (void *unused)
req.body_len = 4;
req.port = 80;
r = _mongoc_http_send (&req, 10000, false, NULL, &res, &error);
ASSERT_CMPINT (res.status, ==, 200);
ASSERT_OR_PRINT (r, error);
ASSERT_CMPINT (res.body_len, >, 0);
_mongoc_http_response_cleanup (&res);
}

Expand Down