Commit 5c9266c5 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Background download: Propagates URL chain and response headers.

This CL propagates URL chain and response headers for in memory download
backend that is used in incognito mode for background fetch.

Bug: 863949
Change-Id: I07baff393111aaa2bd2ce2ef9965a78d299be125
Reviewed-on: https://chromium-review.googlesource.com/1142466Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Commit-Queue: Xing Liu <xingliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576282}
parent e10d9a58
......@@ -16,11 +16,10 @@
namespace download {
InMemoryDownload::InMemoryDownload(const std::string& guid, const GURL& url)
InMemoryDownload::InMemoryDownload(const std::string& guid)
: guid_(guid),
state_(State::INITIAL),
paused_(false),
url_chain_({url}),
bytes_downloaded_(0u) {}
InMemoryDownload::~InMemoryDownload() = default;
......@@ -33,7 +32,7 @@ InMemoryDownloadImpl::InMemoryDownloadImpl(
network::mojom::URLLoaderFactory* url_loader_factory,
BlobTaskProxy::BlobContextGetter blob_context_getter,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
: InMemoryDownload(guid, request_params.url),
: InMemoryDownload(guid),
request_params_(request_params),
traffic_annotation_(traffic_annotation),
url_loader_factory_(url_loader_factory),
......@@ -180,16 +179,38 @@ void InMemoryDownloadImpl::SendRequest() {
request->headers = request_params_.request_headers;
request->load_flags = net::LOAD_DISABLE_CACHE;
url_chain_.push_back(request_params_.url);
loader_ =
network::SimpleURLLoader::Create(std::move(request), traffic_annotation_);
loader_->SetOnRedirectCallback(base::BindRepeating(
&InMemoryDownloadImpl::OnRedirect, weak_ptr_factory_.GetWeakPtr()));
loader_->SetOnResponseStartedCallback(
base::BindRepeating(&InMemoryDownloadImpl::OnResponseStarted,
weak_ptr_factory_.GetWeakPtr()));
// TODO(xingliu): Use SimpleURLLoader's retry when it won't hit CHECK in
// SharedURLLoaderFactory.
loader_->DownloadAsStream(url_loader_factory_, this);
}
void InMemoryDownloadImpl::OnRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
std::vector<std::string>* to_be_removed_headers) {
url_chain_.push_back(redirect_info.new_url);
}
void InMemoryDownloadImpl::OnResponseStarted(
const GURL& final_url,
const network::ResourceResponseHead& response_head) {
response_headers_ = response_head.headers;
}
void InMemoryDownloadImpl::Reset() {
data_.clear();
url_chain_.clear();
response_headers_.reset();
bytes_downloaded_ = 0u;
completion_notified_ = false;
resume_callback_.Reset();
......
......@@ -111,7 +111,7 @@ class InMemoryDownload {
}
protected:
InMemoryDownload(const std::string& guid, const GURL& url);
InMemoryDownload(const std::string& guid);
// GUID of the download.
const std::string guid_;
......@@ -125,8 +125,6 @@ class InMemoryDownload {
base::Time completion_time_;
// The URL request chain of this download.
// TODO(crbug.com/863949): Update the URL chain once all redirects in the
// request have been identified.
std::vector<GURL> url_chain_;
// HTTP response headers.
......@@ -188,6 +186,15 @@ class InMemoryDownloadImpl : public network::SimpleURLLoaderStreamConsumer,
// Sends a new network request.
void SendRequest();
// Called when the server redirects to another URL.
void OnRedirect(const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
std::vector<std::string>* to_be_removed_headers);
// Called when the response of the final URL is received.
void OnResponseStarted(const GURL& final_url,
const network::ResourceResponseHead& response_head);
// Resets local states.
void Reset();
......
......@@ -28,7 +28,7 @@ class TestInMemoryDownload : public InMemoryDownload {
public:
TestInMemoryDownload(const std::string& guid,
InMemoryDownload::Delegate* delegate)
: InMemoryDownload(guid, GURL()), delegate_(delegate) {
: InMemoryDownload(guid), delegate_(delegate) {
DCHECK(delegate_) << "Delegate can't be nullptr.";
}
......
......@@ -18,6 +18,8 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::NiceMock;
namespace download {
namespace {
......@@ -151,7 +153,7 @@ class InMemoryDownloadTest : public testing::Test {
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<InMemoryDownloadImpl> download_;
MockDelegate mock_delegate_;
NiceMock<MockDelegate> mock_delegate_;
// Used by SimpleURLLoader network backend.
network::TestURLLoaderFactory url_loader_factory_;
......@@ -176,6 +178,46 @@ TEST_F(InMemoryDownloadTest, DownloadTest) {
VerifyBlobData(kTestDownloadData, blob.get());
}
TEST_F(InMemoryDownloadTest, RedirectResponseHeaders) {
RequestParams request_params;
request_params.url = GURL("https://example.com/firsturl");
CreateDownload(request_params);
// Add a redirect.
net::RedirectInfo redirect_info;
redirect_info.new_url = GURL("https://example.com/redirect12345");
network::TestURLLoaderFactory::Redirects redirects = {
{redirect_info, network::ResourceResponseHead()}};
// Add some random header.
network::ResourceResponseHead response_head;
response_head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
response_head.headers->AddHeader("X-Random-Test-Header: 123");
// The size must match for download as stream from SimpleUrlLoader.
network::URLLoaderCompletionStatus status;
status.decoded_body_length = base::size(kTestDownloadData) - 1;
url_loader_factory()->AddResponse(request_params.url, response_head,
kTestDownloadData, status, redirects);
download()->Start();
delegate()->WaitForCompletion();
EXPECT_EQ(InMemoryDownload::State::COMPLETE, download()->state());
// Verify the response headers and URL chain. The URL chain should contain
// the original URL and redirect URL, and should not contain the final URL.
std::vector<GURL> expected_url_chain = {request_params.url,
redirect_info.new_url};
EXPECT_EQ(download()->url_chain(), expected_url_chain);
EXPECT_EQ(download()->response_headers()->raw_headers(),
response_head.headers->raw_headers());
// Verfiy the data persisted to disk after redirect chain.
auto blob = download()->ResultAsBlob();
VerifyBlobData(kTestDownloadData, blob.get());
}
} // namespace
} // namespace download
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