Commit d2815554 authored by Xiaoling Bao's avatar Xiaoling Bao Committed by Commit Bot

Enable Mac network fetcher to handle binary data, and post additional headers to server.

1) Copy raw bytes from std::string to NSData when making request.
2) Copy raw bytes from NSMutableData to std::string when post response back to caller.
3) Forward additional post headers to NSMutableURLRequest so they can be actually sent.

Bug: 1106820
Change-Id: I4517abea4ffb087f4bd433dcea85ff0e1a0427d2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2304994
Commit-Queue: Xiaoling Bao <xiaolingbao@chromium.org>
Reviewed-by: default avatarSorin Jianu <sorin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789686}
parent 7e681d56
...@@ -95,6 +95,7 @@ using DownloadToFileCompleteCallback = ...@@ -95,6 +95,7 @@ using DownloadToFileCompleteCallback =
initWithResponseStartedCallback:std::move(responseStartedCallback) initWithResponseStartedCallback:std::move(responseStartedCallback)
progressCallback:progressCallback]) { progressCallback:progressCallback]) {
_postRequestCompleteCallback = std::move(postRequestCompleteCallback); _postRequestCompleteCallback = std::move(postRequestCompleteCallback);
_downloadedData.reset([[NSMutableData alloc] init]);
} }
return self; return self;
} }
...@@ -104,9 +105,6 @@ using DownloadToFileCompleteCallback = ...@@ -104,9 +105,6 @@ using DownloadToFileCompleteCallback =
- (void)URLSession:(NSURLSession*)session - (void)URLSession:(NSURLSession*)session
dataTask:(NSURLSessionDataTask*)dataTask dataTask:(NSURLSessionDataTask*)dataTask
didReceiveData:(NSData*)data { didReceiveData:(NSData*)data {
if (_downloadedData == nil) {
_downloadedData.reset([[NSMutableData alloc] init]);
}
[_downloadedData appendData:data]; [_downloadedData appendData:data];
int64_t current = 0; int64_t current = 0;
...@@ -169,18 +167,15 @@ using DownloadToFileCompleteCallback = ...@@ -169,18 +167,15 @@ using DownloadToFileCompleteCallback =
retryAfterResult = [xRetryAfter intValue]; retryAfterResult = [xRetryAfter intValue];
} }
NSString* dataToUse =
_downloadedData ? [[NSString alloc] initWithData:_downloadedData
encoding:NSUTF8StringEncoding]
: response.description;
_callbackRunner->PostTask( _callbackRunner->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(std::move(_postRequestCompleteCallback),
std::move(_postRequestCompleteCallback), std::make_unique<std::string>(
std::make_unique<std::string>(base::SysNSStringToUTF8(dataToUse)), reinterpret_cast<const char*>([_downloadedData bytes]),
error.code, base::SysNSStringToUTF8(etag), [_downloadedData length]),
base::SysNSStringToUTF8(cupServerProof), retryAfterResult)); error.code, base::SysNSStringToUTF8(etag),
base::SysNSStringToUTF8(cupServerProof),
retryAfterResult));
} }
@end @end
...@@ -303,10 +298,18 @@ void NetworkFetcher::PostRequest( ...@@ -303,10 +298,18 @@ void NetworkFetcher::PostRequest(
base::scoped_nsobject<NSMutableURLRequest> urlRequest( base::scoped_nsobject<NSMutableURLRequest> urlRequest(
[[NSMutableURLRequest alloc] initWithURL:net::NSURLWithGURL(url)]); [[NSMutableURLRequest alloc] initWithURL:net::NSURLWithGURL(url)]);
[urlRequest setHTTPMethod:@"POST"]; [urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:[base::SysUTF8ToNSString(post_data) base::scoped_nsobject<NSData> body(
dataUsingEncoding:NSUTF8StringEncoding]]; [[NSData alloc] initWithBytes:post_data.c_str() length:post_data.size()]);
[urlRequest setHTTPBody:body];
[urlRequest addValue:base::SysUTF8ToNSString(content_type) [urlRequest addValue:base::SysUTF8ToNSString(content_type)
forHTTPHeaderField:@"Content-Type"]; forHTTPHeaderField:@"Content-Type"];
// Post additional headers could overwrite existing headers with the same key,
// such as "Content-Type" above.
for (const auto& header : post_additional_headers) {
[urlRequest setValue:base::SysUTF8ToNSString(header.second)
forHTTPHeaderField:base::SysUTF8ToNSString(header.first)];
}
VLOG(1) << "Posting data: " << post_data.c_str(); VLOG(1) << "Posting data: " << post_data.c_str();
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:urlRequest]; NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:urlRequest];
......
...@@ -48,11 +48,13 @@ class ChromeUpdaterNetworkMacTest : public ::testing::Test { ...@@ -48,11 +48,13 @@ class ChromeUpdaterNetworkMacTest : public ::testing::Test {
EXPECT_LE(current, 100); EXPECT_LE(current, 100);
} }
void PostRequestCompleteCallback(std::unique_ptr<std::string> response_body, void PostRequestCompleteCallback(const std::string& expected_body,
std::unique_ptr<std::string> response_body,
int net_error, int net_error,
const std::string& header_etag, const std::string& header_etag,
const std::string& header_x_cup_server_proof, const std::string& header_x_cup_server_proof,
int64_t xheader_retry_after_sec) { int64_t xheader_retry_after_sec) {
EXPECT_STREQ(response_body->c_str(), expected_body.c_str());
EXPECT_EQ(net_error, 0); EXPECT_EQ(net_error, 0);
EXPECT_STREQ(header_etag.c_str(), "Wfhw789h"); EXPECT_STREQ(header_etag.c_str(), "Wfhw789h");
EXPECT_STREQ(header_x_cup_server_proof.c_str(), "server-proof"); EXPECT_STREQ(header_x_cup_server_proof.c_str(), "server-proof");
...@@ -73,8 +75,15 @@ class ChromeUpdaterNetworkMacTest : public ::testing::Test { ...@@ -73,8 +75,15 @@ class ChromeUpdaterNetworkMacTest : public ::testing::Test {
auto http_response = auto http_response =
std::make_unique<net::test_server::BasicHttpResponse>(); std::make_unique<net::test_server::BasicHttpResponse>();
http_response->set_code(net::HTTP_OK); http_response->set_code(net::HTTP_OK);
http_response->set_content("hello");
http_response->set_content_type("text/plain"); if (request.content.size() > 0) {
// Echo the posted data back if there's any.
http_response->set_content(request.content);
} else {
http_response->set_content("hello");
}
http_response->set_content_type("application/octet-stream");
http_response->AddCustomHeader("X-Retry-After", "67"); http_response->AddCustomHeader("X-Retry-After", "67");
http_response->AddCustomHeader("ETag", "Wfhw789h"); http_response->AddCustomHeader("ETag", "Wfhw789h");
http_response->AddCustomHeader("X-Cup-Server-Proof", "server-proof"); http_response->AddCustomHeader("X-Cup-Server-Proof", "server-proof");
...@@ -110,14 +119,16 @@ TEST_F(ChromeUpdaterNetworkMacTest, NetworkFetcherMacPostRequest) { ...@@ -110,14 +119,16 @@ TEST_F(ChromeUpdaterNetworkMacTest, NetworkFetcherMacPostRequest) {
ASSERT_TRUE(test_server.Start()); ASSERT_TRUE(test_server.Start());
const GURL url = test_server.GetURL("/echo"); const GURL url = test_server.GetURL("/echo");
constexpr char kPostData[] = {0x01, 0x00, 0x55, 0x33, 0xda, 0x10, 0x44};
const std::string post_data(kPostData, sizeof(kPostData));
fetcher->PostRequest( fetcher->PostRequest(
url, {}, {}, {}, url, post_data, {}, {},
base::BindOnce(&ChromeUpdaterNetworkMacTest::StartedCallback, base::BindOnce(&ChromeUpdaterNetworkMacTest::StartedCallback,
base::Unretained(this)), base::Unretained(this)),
base::BindRepeating(&ChromeUpdaterNetworkMacTest::ProgressCallback, base::BindRepeating(&ChromeUpdaterNetworkMacTest::ProgressCallback,
base::Unretained(this)), base::Unretained(this)),
base::BindOnce(&ChromeUpdaterNetworkMacTest::PostRequestCompleteCallback, base::BindOnce(&ChromeUpdaterNetworkMacTest::PostRequestCompleteCallback,
base::Unretained(this))); base::Unretained(this), post_data));
run_loop.Run(); run_loop.Run();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment