1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-12 10:04:14 +02:00

Encode path before passing to HttpRequest.

GCS requires mixed encoding in the path so encoding inside HttpRequest does not work.

Instead, require the path to be correctly encoded before being passed to HttpRequest.
This commit is contained in:
David Steele 2021-02-19 09:05:32 -05:00
parent 1b4b3538cc
commit 66a4ff496a
4 changed files with 18 additions and 8 deletions

View File

@ -108,7 +108,7 @@ httpRequestProcess(HttpRequest *this, bool waitForResponse, bool contentCache)
String *requestStr =
strNewFmt(
"%s %s%s%s " HTTP_VERSION CRLF_Z HTTP_HEADER_USER_AGENT ":" PROJECT_NAME "/" PROJECT_VERSION CRLF_Z,
strZ(this->verb), strZ(httpUriEncode(this->path, true)), this->query == NULL ? "" : "?",
strZ(this->verb), strZ(this->path), this->query == NULL ? "" : "?",
this->query == NULL ? "" : strZ(httpQueryRenderP(this->query)));
// Add headers
@ -257,7 +257,7 @@ httpRequestError(const HttpRequest *this, HttpResponse *response)
// Output path/query
strCatZ(error, ":\n*** Path/Query ***:");
strCatFmt(error, "\n%s", strZ(httpUriEncode(this->path, true)));
strCatFmt(error, "\n%s", strZ(this->path));
if (this->query != NULL)
strCatFmt(error, "?%s", strZ(httpQueryRenderP(this->query, .redact = true)));

View File

@ -234,6 +234,9 @@ storageAzureRequestAsync(StorageAzure *this, const String *verb, StorageAzureReq
httpHeaderAdd(requestHeader, HTTP_HEADER_CONTENT_MD5_STR, STR(md5Hash));
}
// Encode path
const String *const path = httpUriEncode(param.path, true);
// Make a copy of the query so it can be modified
HttpQuery *query =
this->sasKey != NULL && param.query == NULL ?
@ -241,13 +244,13 @@ storageAzureRequestAsync(StorageAzure *this, const String *verb, StorageAzureReq
httpQueryDupP(param.query, .redactList = this->queryRedactList);
// Generate authorization header
storageAzureAuth(this, verb, httpUriEncode(param.path, true), query, httpDateFromTime(time(NULL)), requestHeader);
storageAzureAuth(this, verb, path, query, httpDateFromTime(time(NULL)), requestHeader);
// Send request
MEM_CONTEXT_PRIOR_BEGIN()
{
result = httpRequestNewP(
this->httpClient, verb, param.path, .query = query, .header = requestHeader, .content = param.content);
this->httpClient, verb, path, .query = query, .header = requestHeader, .content = param.content);
}
MEM_CONTEXT_END();
}

View File

@ -407,9 +407,12 @@ storageS3RequestAsync(StorageS3 *this, const String *verb, const String *path, S
this->signingKeyDate = YYYYMMDD_STR;
}
// Encode path
path = httpUriEncode(path, true);
// Generate authorization header
storageS3Auth(
this, verb, httpUriEncode(path, true), param.query, storageS3DateTime(time(NULL)), requestHeader,
this, verb, path, param.query, storageS3DateTime(time(NULL)), requestHeader,
param.content == NULL || bufEmpty(param.content) ?
HASH_TYPE_SHA256_ZERO_STR : bufHex(cryptoHashOne(HASH_TYPE_SHA256_STR, param.content)));

View File

@ -546,7 +546,7 @@ testRun(void)
response,
httpRequestResponse(
httpRequestNewP(
client, strNew("GET"), strNew("/path/file 1.txt"),
client, strNew("GET"), httpUriEncode(strNew("/path/file 1.txt"), true),
.header = httpHeaderAdd(httpHeaderNew(NULL), strNew("content-length"), strNew("30")),
.content = BUFSTRDEF("012345678901234567890123456789")), true),
"request");
@ -570,7 +570,9 @@ testRun(void)
hrnServerScriptReplyZ(http, "HTTP/1.1 200 OK\r\ncontent-length:32\r\n\r\n01234567890123456789012345678901");
TEST_ASSIGN(
response, httpRequestResponse(httpRequestNewP(client, strNew("GET"), strNew("/path/file 1.txt")), true),
response,
httpRequestResponse(
httpRequestNewP(client, strNew("GET"), httpUriEncode(strNew("/path/file 1.txt"), true)), true),
"request");
TEST_RESULT_STR_Z(strNewBuf(httpResponseContent(response)), "01234567890123456789012345678901", "check response");
TEST_RESULT_UINT(httpResponseRead(response, bufNew(1), true), 0, "call internal read to check eof");
@ -584,7 +586,9 @@ testRun(void)
hrnServerScriptClose(http);
TEST_ASSIGN(
response, httpRequestResponse(httpRequestNewP(client, strNew("GET"), strNew("/path/file 1.txt")), false),
response,
httpRequestResponse(
httpRequestNewP(client, strNew("GET"), httpUriEncode(strNew("/path/file 1.txt"), true)), false),
"request");
TEST_RESULT_PTR_NE(response->session, NULL, "session is busy");
TEST_ERROR(ioRead(httpResponseIoRead(response), bufNew(32)), FileReadError, "unexpected EOF reading HTTP content");