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:
parent
6bb111c170
commit
fbee6ec170
@ -103,6 +103,14 @@
|
|||||||
|
|
||||||
<p>Allow <code>HttpClient</code>/<code>HttpSession</code> to work on plain sockets.</p>
|
<p>Allow <code>HttpClient</code>/<code>HttpSession</code> to work on plain sockets.</p>
|
||||||
</release-item>
|
</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-development-list>
|
||||||
</release-core-list>
|
</release-core-list>
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ HTTP Request
|
|||||||
HTTP constants
|
HTTP constants
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
STRING_EXTERN(HTTP_VERSION_STR, HTTP_VERSION);
|
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_DELETE_STR, HTTP_VERB_DELETE);
|
||||||
STRING_EXTERN(HTTP_VERB_GET_STR, HTTP_VERB_GET);
|
STRING_EXTERN(HTTP_VERB_GET_STR, HTTP_VERB_GET);
|
||||||
|
@ -25,6 +25,8 @@ HTTP Constants
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
#define HTTP_VERSION "HTTP/1.1"
|
#define HTTP_VERSION "HTTP/1.1"
|
||||||
STRING_DECLARE(HTTP_VERSION_STR);
|
STRING_DECLARE(HTTP_VERSION_STR);
|
||||||
|
#define HTTP_VERSION_10 "HTTP/1.0"
|
||||||
|
STRING_DECLARE(HTTP_VERSION_10_STR);
|
||||||
|
|
||||||
#define HTTP_VERB_DELETE "DELETE"
|
#define HTTP_VERB_DELETE "DELETE"
|
||||||
STRING_DECLARE(HTTP_VERB_DELETE_STR);
|
STRING_DECLARE(HTTP_VERB_DELETE_STR);
|
||||||
|
@ -243,9 +243,14 @@ httpResponseNew(HttpSession *session, const String *verb, bool contentCache)
|
|||||||
if (strSize(status) < sizeof(HTTP_VERSION) + 4)
|
if (strSize(status) < sizeof(HTTP_VERSION) + 4)
|
||||||
THROW_FMT(FormatError, "HTTP response '%s' has invalid length", strZ(strTrim(status)));
|
THROW_FMT(FormatError, "HTTP response '%s' has invalid length", strZ(strTrim(status)));
|
||||||
|
|
||||||
// Check status starts with the correct http version
|
// 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_STR))
|
if (strBeginsWith(status, HTTP_VERSION_10_STR))
|
||||||
THROW_FMT(FormatError, "HTTP version of response '%s' must be " HTTP_VERSION, strZ(status));
|
{
|
||||||
|
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
|
// Read status code
|
||||||
status = strSub(status, sizeof(HTTP_VERSION));
|
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.
|
// 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))
|
if (strEq(headerKey, HTTP_HEADER_CONNECTION_STR) && strEq(headerValue, HTTP_VALUE_CONNECTION_CLOSE_STR))
|
||||||
this->closeOnContentEof = true;
|
this->closeOnContentEof = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
|
@ -257,13 +257,13 @@ testRun(void)
|
|||||||
hrnServerScriptAccept(http);
|
hrnServerScriptAccept(http);
|
||||||
|
|
||||||
hrnServerScriptExpectZ(http, "GET / HTTP/1.1\r\n\r\n");
|
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);
|
hrnServerScriptClose(http);
|
||||||
|
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
httpRequestResponse(httpRequestNewP(client, strNew("GET"), strNew("/")), false), FormatError,
|
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");
|
TEST_TITLE("no space in status");
|
||||||
@ -410,7 +410,9 @@ testRun(void)
|
|||||||
TEST_TITLE("head request with content-length but no content");
|
TEST_TITLE("head request with content-length but no content");
|
||||||
|
|
||||||
hrnServerScriptExpectZ(http, "HEAD / HTTP/1.1\r\n\r\n");
|
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_ASSIGN(response, httpRequestResponse(httpRequestNewP(client, strNew("HEAD"), strNew("/")), true), "request");
|
||||||
TEST_RESULT_UINT(httpResponseCode(response), 200, "check response code");
|
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");
|
TEST_TITLE("head request with transfer encoding but no content");
|
||||||
|
|
||||||
|
hrnServerScriptAccept(http);
|
||||||
|
|
||||||
hrnServerScriptExpectZ(http, "HEAD / HTTP/1.1\r\n\r\n");
|
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");
|
hrnServerScriptReplyZ(http, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user