Commit e4f685ee authored by Jian Li's avatar Jian Li Committed by Commit Bot

Move common code for serving offline pages to OfflinePageRequestHandler

OfflinePageRequestJob and OfflinePageURLLoader (will be added in next
patch to support network servicification) will create and hold
OfflinePageRequestHandler. The specific behaviors for url request job
and url loader are encapsulated in OfflinePageRequestHandler::Delegate
which will be implemented accordingly.

OfflinePageRequestHandlerTest is also to pull out common testing code.
For now, only one type OfflinePageRequestJobBuilder is added to test
OfflinePageRequestJob. I will add a new type to test new URLLoader in
next patch.


Bug: 841617
Change-Id: I1cd9b8e03358bc18d6d08e2d038be579de10dc42
Reviewed-on: https://chromium-review.googlesource.com/1058449
Commit-Queue: Jian Li <jianli@chromium.org>
Reviewed-by: default avatarDmitry Titov <dimich@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560715}
parent f5604624
...@@ -3771,6 +3771,8 @@ jumbo_split_static_library("browser") { ...@@ -3771,6 +3771,8 @@ jumbo_split_static_library("browser") {
"offline_pages/offline_page_mhtml_archiver.h", "offline_pages/offline_page_mhtml_archiver.h",
"offline_pages/offline_page_model_factory.h", "offline_pages/offline_page_model_factory.h",
"offline_pages/offline_page_origin_utils.h", "offline_pages/offline_page_origin_utils.h",
"offline_pages/offline_page_request_handler.cc",
"offline_pages/offline_page_request_handler.h",
"offline_pages/offline_page_request_interceptor.cc", "offline_pages/offline_page_request_interceptor.cc",
"offline_pages/offline_page_request_interceptor.h", "offline_pages/offline_page_request_interceptor.h",
"offline_pages/offline_page_request_job.cc", "offline_pages/offline_page_request_job.cc",
......
// Copyright 2016 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "components/offline_pages/core/request_header/offline_page_header.h" #include "components/offline_pages/core/request_header/offline_page_header.h"
#include "content/public/browser/resource_request_info.h" #include "content/public/browser/resource_request_info.h"
#include "content/public/common/resource_type.h" #include "content/public/common/resource_type.h"
#include "net/url_request/url_request_job.h"
namespace base { namespace base {
class FilePath; class FilePath;
...@@ -24,16 +23,14 @@ class FilePath; ...@@ -24,16 +23,14 @@ class FilePath;
namespace net { namespace net {
class FileStream; class FileStream;
class HttpRequestHeaders;
class HttpResponseHeaders;
class IOBuffer; class IOBuffer;
} // namespace net } // namespace net
namespace previews {
class PreviewsDecider;
}
namespace offline_pages { namespace offline_pages {
// A request job that serves content from a trusted offline file, located either // A handler that serves content from a trusted offline file, located either
// in internal directory or in public directory with digest validated, when a // in internal directory or in public directory with digest validated, when a
// http/https URL is being navigated on disconnected or poor network. If no // http/https URL is being navigated on disconnected or poor network. If no
// trusted offline file can be found, fall back to the default network handling // trusted offline file can be found, fall back to the default network handling
...@@ -41,7 +38,7 @@ namespace offline_pages { ...@@ -41,7 +38,7 @@ namespace offline_pages {
// //
// The only header handled by this request job is: // The only header handled by this request job is:
// * "X-Chrome-offline" custom header. // * "X-Chrome-offline" custom header.
class OfflinePageRequestHandler : public net::URLRequestJob { class OfflinePageRequestHandler {
public: public:
// This enum is used for UMA reporting. It contains all possible outcomes of // This enum is used for UMA reporting. It contains all possible outcomes of
// handling requests that might service offline page in different network // handling requests that might service offline page in different network
...@@ -135,17 +132,48 @@ class OfflinePageRequestHandler : public net::URLRequestJob { ...@@ -135,17 +132,48 @@ class OfflinePageRequestHandler : public net::URLRequestJob {
bool archive_is_in_internal_dir; bool archive_is_in_internal_dir;
}; };
// Delegate that allows tests to overwrite certain behaviors. // Delegate that allows the consumer to overwrite certain behaviors.
// All methods are called from IO thread.
class Delegate { class Delegate {
public: public:
using WebContentsGetter = base::Callback<content::WebContents*(void)>;
using TabIdGetter = base::Callback<bool(content::WebContents*, int*)>; using TabIdGetter = base::Callback<bool(content::WebContents*, int*)>;
virtual ~Delegate() {} // Falls back to the default handling in the case that the offline content
// can't be found and served.
virtual void FallbackToDefault() = 0;
// Notifies that a start error has occurred.
virtual void NotifyStartError(int error) = 0;
// Notifies that the headers have been received. |file_size| indicates the
// total size to be read.
virtual void NotifyHeadersComplete(int64_t file_size) = 0;
// Notifies that ReadRawData() is completed. |bytes_read| is either >= 0 to
// indicate a successful read and count of bytes read, or < 0 to indicate an
// error.
virtual void NotifyReadRawDataComplete(int bytes_read) = 0;
// Sets |is_offline_page| flag in NavigationUIData.
virtual void SetOfflinePageNavigationUIData(bool is_offline_page) = 0;
// Returns true if the preview is allowed.
virtual bool ShouldAllowPreview() const = 0;
// Returns the page transition type for this navigation.
virtual int GetPageTransition() const = 0;
virtual content::ResourceRequestInfo::WebContentsGetter // Returns the getter to retrieve the web contents associated with this
GetWebContentsGetter(net::URLRequest* request) const = 0; // this navigation.
virtual WebContentsGetter GetWebContentsGetter() const = 0;
// Returns the getter to retrieve the ID of the tab where this navigation
// occurs.
virtual TabIdGetter GetTabIdGetter() const = 0; virtual TabIdGetter GetTabIdGetter() const = 0;
protected:
virtual ~Delegate() {}
}; };
class ThreadSafeArchiveValidator final class ThreadSafeArchiveValidator final
...@@ -163,32 +191,27 @@ class OfflinePageRequestHandler : public net::URLRequestJob { ...@@ -163,32 +191,27 @@ class OfflinePageRequestHandler : public net::URLRequestJob {
// state. // state.
static void ReportAggregatedRequestResult(AggregatedRequestResult result); static void ReportAggregatedRequestResult(AggregatedRequestResult result);
// Creates and returns a job to serve the offline page. Nullptr is returned if OfflinePageRequestHandler(
// offline page cannot or should not be served. Embedder must gaurantee that const GURL& url,
// |previews_decider| outlives the returned instance. const net::HttpRequestHeaders& extra_request_headers,
static OfflinePageRequestHandler* Create( Delegate* delegate);
net::URLRequest* request,
net::NetworkDelegate* network_delegate, ~OfflinePageRequestHandler();
previews::PreviewsDecider* previews_decider);
void Start();
~OfflinePageRequestHandler() override; void Kill();
bool IsServingOfflinePage() const;
// net::URLRequestJob overrides:
void Start() override; // Returns the http response headers to trigger a redirect.
void Kill() override; scoped_refptr<net::HttpResponseHeaders> GetRedirectHeaders();
int ReadRawData(net::IOBuffer* dest, int dest_size) override;
void GetResponseInfo(net::HttpResponseInfo* info) override; // Reads at most |dest_size| bytes of the raw data into |dest| buffer.
void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override; int ReadRawData(net::IOBuffer* dest, int dest_size);
bool CopyFragmentOnRedirect(const GURL& location) const override;
bool GetMimeType(std::string* mime_type) const override;
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
// Called when offline pages matching the request URL are found. The list is // Called when offline pages matching the request URL are found. The list is
// sorted based on creation date in descending order. // sorted based on creation date in descending order.
void OnOfflinePagesAvailable(const std::vector<Candidate>& candidates); void OnOfflinePagesAvailable(const std::vector<Candidate>& candidates);
void SetDelegateForTesting(std::unique_ptr<Delegate> delegate);
private: private:
enum class FileValidationResult { enum class FileValidationResult {
// The file passes the digest validation and thus can be trusted. // The file passes the digest validation and thus can be trusted.
...@@ -199,14 +222,9 @@ class OfflinePageRequestHandler : public net::URLRequestJob { ...@@ -199,14 +222,9 @@ class OfflinePageRequestHandler : public net::URLRequestJob {
FILE_VALIDATION_FAILED, FILE_VALIDATION_FAILED,
}; };
OfflinePageRequestHandler(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
previews::PreviewsDecider* previews_decider);
void StartAsync(); void StartAsync();
// Restarts the request job in order to fall back to the default handling. NetworkState GetNetworkState() const;
void FallbackToDefault();
AccessEntryPoint GetAccessEntryPoint() const; AccessEntryPoint GetAccessEntryPoint() const;
...@@ -218,11 +236,10 @@ class OfflinePageRequestHandler : public net::URLRequestJob { ...@@ -218,11 +236,10 @@ class OfflinePageRequestHandler : public net::URLRequestJob {
void OnTrustedOfflinePageFound(); void OnTrustedOfflinePageFound();
void VisitTrustedOfflinePage(); void VisitTrustedOfflinePage();
void SetOfflinePageNavigationUIData(bool is_offline_page);
void Redirect(const GURL& redirected_url); void Redirect(const GURL& redirected_url);
void OpenFile(const base::FilePath& file_path, void OpenFile(const base::FilePath& file_path,
const net::CompletionCallback& callback); const base::Callback<void(int)>& callback);
void UpdateDigestOnBackground( void UpdateDigestOnBackground(
scoped_refptr<net::IOBuffer> buffer, scoped_refptr<net::IOBuffer> buffer,
size_t len, size_t len,
...@@ -248,18 +265,14 @@ class OfflinePageRequestHandler : public net::URLRequestJob { ...@@ -248,18 +265,14 @@ class OfflinePageRequestHandler : public net::URLRequestJob {
void DidComputeActualDigestForServing(int result, void DidComputeActualDigestForServing(int result,
const std::string& actual_digest); const std::string& actual_digest);
std::unique_ptr<Delegate> delegate_; GURL url_;
Delegate* delegate_;
OfflinePageHeader offline_header_; OfflinePageHeader offline_header_;
NetworkState network_state_; NetworkState network_state_;
// For redirect simulation. // For redirect simulation.
scoped_refptr<net::HttpResponseHeaders> fake_headers_for_redirect_; scoped_refptr<net::HttpResponseHeaders> fake_headers_for_redirect_;
base::TimeTicks receive_redirect_headers_end_;
base::Time redirect_response_time_;
// Used to determine if an URLRequest is eligible for offline previews.
previews::PreviewsDecider* previews_decider_;
// To run any file related operations. // To run any file related operations.
scoped_refptr<base::TaskRunner> file_task_runner_; scoped_refptr<base::TaskRunner> file_task_runner_;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/offline_pages/offline_page_model_factory.h" #include "chrome/browser/offline_pages/offline_page_model_factory.h"
#include "chrome/browser/offline_pages/offline_page_request_job.h" #include "chrome/browser/offline_pages/offline_page_request_handler.h"
#include "chrome/browser/offline_pages/offline_page_utils.h" #include "chrome/browser/offline_pages/offline_page_utils.h"
#include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h" #include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h"
#include "chrome/browser/offline_pages/request_coordinator_factory.h" #include "chrome/browser/offline_pages/request_coordinator_factory.h"
...@@ -267,8 +267,9 @@ void OfflinePageTabHelper::TryLoadingOfflinePageOnNetError( ...@@ -267,8 +267,9 @@ void OfflinePageTabHelper::TryLoadingOfflinePageOnNetError(
// Do not report aborted error since the error page is not shown on this // Do not report aborted error since the error page is not shown on this
// error. // error.
if (error_code != net::ERR_ABORTED) { if (error_code != net::ERR_ABORTED) {
OfflinePageRequestJob::ReportAggregatedRequestResult( OfflinePageRequestHandler::ReportAggregatedRequestResult(
OfflinePageRequestJob::AggregatedRequestResult::SHOW_NET_ERROR_PAGE); OfflinePageRequestHandler::AggregatedRequestResult::
SHOW_NET_ERROR_PAGE);
} }
return; return;
} }
...@@ -293,8 +294,8 @@ void OfflinePageTabHelper::SelectPagesForURLDone( ...@@ -293,8 +294,8 @@ void OfflinePageTabHelper::SelectPagesForURLDone(
const std::vector<OfflinePageItem>& offline_pages) { const std::vector<OfflinePageItem>& offline_pages) {
// Bails out if no offline page is found. // Bails out if no offline page is found.
if (offline_pages.empty()) { if (offline_pages.empty()) {
OfflinePageRequestJob::ReportAggregatedRequestResult( OfflinePageRequestHandler::ReportAggregatedRequestResult(
OfflinePageRequestJob::AggregatedRequestResult:: OfflinePageRequestHandler::AggregatedRequestResult::
PAGE_NOT_FOUND_ON_FLAKY_NETWORK); PAGE_NOT_FOUND_ON_FLAKY_NETWORK);
return; return;
} }
......
...@@ -2824,7 +2824,7 @@ test("unit_tests") { ...@@ -2824,7 +2824,7 @@ test("unit_tests") {
sources += [ sources += [
"../browser/offline_pages/background_loader_offliner_unittest.cc", "../browser/offline_pages/background_loader_offliner_unittest.cc",
"../browser/offline_pages/offline_page_mhtml_archiver_unittest.cc", "../browser/offline_pages/offline_page_mhtml_archiver_unittest.cc",
"../browser/offline_pages/offline_page_request_job_unittest.cc", "../browser/offline_pages/offline_page_request_handler_unittest.cc",
"../browser/offline_pages/offline_page_tab_helper_unittest.cc", "../browser/offline_pages/offline_page_tab_helper_unittest.cc",
"../browser/offline_pages/offline_page_utils_unittest.cc", "../browser/offline_pages/offline_page_utils_unittest.cc",
"../browser/offline_pages/prefetch/offline_metrics_collector_impl_unittest.cc", "../browser/offline_pages/prefetch/offline_metrics_collector_impl_unittest.cc",
......
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