1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-04-21 11:57:01 +02:00

Add support for HTTP/1.0.

HTTP/1.0 connections are closed by default after a single response. Other than that, treat 1.0 the same as 1.1.

HTTP/1.0 allows different date formats that we can't parse but for now, at least, we don't need any date headers from 1.0 requests.
This commit is contained in:
David Steele 2020-08-14 13:11:33 -04:00 committed by GitHub
parent 6bb111c170
commit fbee6ec170
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 26 additions and 7 deletions

View File

@ -103,6 +103,14 @@
<p>Allow <code>HttpClient</code>/<code>HttpSession</code> to work on plain sockets.</p>
</release-item>
<release-item>
<release-item-contributor-list>
<release-item-reviewer id="stephen.frost"/>
</release-item-contributor-list>
<p>Add support for <id>HTTP/1.0</id>.</p>
</release-item>
</release-development-list>
</release-core-list>

View File

@ -14,6 +14,7 @@ HTTP Request
HTTP constants
***********************************************************************************************************************************/
STRING_EXTERN(HTTP_VERSION_STR, HTTP_VERSION);
STRING_EXTERN(HTTP_VERSION_10_STR, HTTP_VERSION_10);
STRING_EXTERN(HTTP_VERB_DELETE_STR, HTTP_VERB_DELETE);
STRING_EXTERN(HTTP_VERB_GET_STR, HTTP_VERB_GET);

View File

@ -25,6 +25,8 @@ HTTP Constants
***********************************************************************************************************************************/
#define HTTP_VERSION "HTTP/1.1"
STRING_DECLARE(HTTP_VERSION_STR);
#define HTTP_VERSION_10 "HTTP/1.0"
STRING_DECLARE(HTTP_VERSION_10_STR);
#define HTTP_VERB_DELETE "DELETE"
STRING_DECLARE(HTTP_VERB_DELETE_STR);

View File

@ -243,9 +243,14 @@ httpResponseNew(HttpSession *session, const String *verb, bool contentCache)
if (strSize(status) < sizeof(HTTP_VERSION) + 4)
THROW_FMT(FormatError, "HTTP response '%s' has invalid length", strZ(strTrim(status)));
// Check status starts with the correct http version
if (!strBeginsWith(status, HTTP_VERSION_STR))
THROW_FMT(FormatError, "HTTP version of response '%s' must be " HTTP_VERSION, strZ(status));
// If HTTP/1.0 then the connection will be closed on content eof since connections are not reused by default
if (strBeginsWith(status, HTTP_VERSION_10_STR))
{
this->closeOnContentEof = true;
}
// Else check that the version is the default (1.1)
else if (!strBeginsWith(status, HTTP_VERSION_STR))
THROW_FMT(FormatError, "HTTP version of response '%s' must be " HTTP_VERSION " or " HTTP_VERSION_10, strZ(status));
// Read status code
status = strSub(status, sizeof(HTTP_VERSION));
@ -310,7 +315,6 @@ httpResponseNew(HttpSession *session, const String *verb, bool contentCache)
// prevents doing a retry on the next request when using the closed connection.
if (strEq(headerKey, HTTP_HEADER_CONNECTION_STR) && strEq(headerValue, HTTP_VALUE_CONNECTION_CLOSE_STR))
this->closeOnContentEof = true;
}
while (1);

View File

@ -257,13 +257,13 @@ testRun(void)
hrnServerScriptAccept(http);
hrnServerScriptExpectZ(http, "GET / HTTP/1.1\r\n\r\n");
hrnServerScriptReplyZ(http, "HTTP/1.0 200 OK\r\n");
hrnServerScriptReplyZ(http, "HTTP/1 200 OK\r\n");
hrnServerScriptClose(http);
TEST_ERROR(
httpRequestResponse(httpRequestNewP(client, strNew("GET"), strNew("/")), false), FormatError,
"HTTP version of response 'HTTP/1.0 200 OK' must be HTTP/1.1");
"HTTP version of response 'HTTP/1 200 OK' must be HTTP/1.1 or HTTP/1.0");
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("no space in status");
@ -410,7 +410,9 @@ testRun(void)
TEST_TITLE("head request with content-length but no content");
hrnServerScriptExpectZ(http, "HEAD / HTTP/1.1\r\n\r\n");
hrnServerScriptReplyZ(http, "HTTP/1.1 200 OK\r\ncontent-length:380\r\n\r\n");
hrnServerScriptReplyZ(http, "HTTP/1.0 200 OK\r\ncontent-length:380\r\n\r\n");
hrnServerScriptClose(http);
TEST_ASSIGN(response, httpRequestResponse(httpRequestNewP(client, strNew("HEAD"), strNew("/")), true), "request");
TEST_RESULT_UINT(httpResponseCode(response), 200, "check response code");
@ -423,6 +425,8 @@ testRun(void)
// -----------------------------------------------------------------------------------------------------------------
TEST_TITLE("head request with transfer encoding but no content");
hrnServerScriptAccept(http);
hrnServerScriptExpectZ(http, "HEAD / HTTP/1.1\r\n\r\n");
hrnServerScriptReplyZ(http, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");