Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Unified Diff: components/offline_pages/core/prefetch/generate_page_bundle_request.cc

Issue 2873383004: [Offline Prefetch] Send GeneratePageBundleRequest to the server (Closed)
Patch Set: Update Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/offline_pages/core/prefetch/generate_page_bundle_request.cc
diff --git a/components/offline_pages/core/prefetch/generate_page_bundle_request.cc b/components/offline_pages/core/prefetch/generate_page_bundle_request.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ab797fc2ced2fc15d4c2d000d6f91afa8b5cd10b
--- /dev/null
+++ b/components/offline_pages/core/prefetch/generate_page_bundle_request.cc
@@ -0,0 +1,183 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/offline_pages/core/prefetch/generate_page_bundle_request.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "components/offline_pages/core/prefetch/prefetch_request_fetcher.h"
+#include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
+#include "components/offline_pages/core/prefetch/proto/operation.pb.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+namespace {
+// TODO(jianli): Update when server is ready.
+const GURL kOfflinePrefetchServiceUrl(
+ "http://localhost:12345/v1:GeneratePageBundle");
+}
+
+GeneratePageBundleRequest::GeneratePageBundleRequest(
+ const std::string& user_agent,
+ const std::string& gcm_registration_id,
+ int max_bundle_size_bytes,
+ const std::vector<std::string>& page_urls,
dewittj 2017/05/11 21:51:48 why is this strings and not GURL?
+ net::URLRequestContextGetter* request_context_getter,
+ const FinishedCallback& callback)
+ : callback_(callback) {
+ proto::GeneratePageBundleRequest request;
+ request.set_user_agent(user_agent);
+ request.set_max_bundle_size_bytes(max_bundle_size_bytes);
+ request.set_output_format(proto::FORMAT_MHTML);
+ request.set_gcm_registration_id(gcm_registration_id);
+
+ for (const auto& page_url : page_urls) {
+ proto::PageParameters* page = request.add_pages();
+ page->set_url(page_url);
+ page->set_transformation(proto::NO_TRANSFORMATION);
+ }
+
+ std::string upload_data;
+ request.SerializeToString(&upload_data);
+
+ fetcher_.reset(new PrefetchRequestFetcher(
+ kOfflinePrefetchServiceUrl, upload_data, request_context_getter,
+ base::Bind(&GeneratePageBundleRequest::OnCompleted,
+ // Fetcher is owned by this instance.
+ base::Unretained(this))));
+}
+
+GeneratePageBundleRequest::~GeneratePageBundleRequest() {}
+
+void GeneratePageBundleRequest::OnCompleted(RequestStatus status,
+ const std::string& data) {
+ proto::Operation operation;
+ if (!operation.ParseFromString(data)) {
+ DVLOG(1) << "Failed to parse GeneratePageBundle response";
+ NotifyParsingFailure();
+ return;
+ }
+
+ if (operation.done())
+ ParseDoneOperationResponse(operation);
+ else
+ ParsePendingOperationResponse(operation);
+}
+
+void GeneratePageBundleRequest::ParseDoneOperationResponse(
+ const proto::Operation& operation) {
+ if (operation.result_case() == proto::Operation::kError) {
dewittj 2017/05/11 18:46:43 kError is not defined?
jianli 2017/05/11 20:45:14 It is defined in the generated file operation.pb.h
+ DVLOG(1) << "Error found in GeneratePageBundle response";
+ NotifyParsingFailure();
+ return;
+ }
+
+ DCHECK_EQ(proto::Operation::kResponse, operation.result_case());
+ ParsePageBundleInAnyData(operation.response());
+}
+
+void GeneratePageBundleRequest::ParsePendingOperationResponse(
+ const proto::Operation& operation) {
+ if (!operation.has_metadata()) {
+ DVLOG(1) << "metadata not found in GeneratePageBundle response";
dewittj 2017/05/11 18:46:43 Is metadata guaranteed?
jianli 2017/05/11 20:45:14 Yes. The server will return something in metadata
+ NotifyParsingFailure();
+ return;
+ }
+ ParsePageBundleInAnyData(operation.metadata());
+}
+
+void GeneratePageBundleRequest::ParsePageBundleInAnyData(
+ const proto::Any& any_data) {
+ if (!base::StartsWith(any_data.type_url(), "type.googleapis.com/",
+ base::CompareCase::SENSITIVE) &&
+ !base::EndsWith(any_data.type_url(), ".PageBundle",
+ base::CompareCase::SENSITIVE)) {
+ DVLOG(1) << "Wrong type url in any data";
+ NotifyParsingFailure();
+ return;
+ }
+
+ proto::PageBundle page_bundle;
+ if (!page_bundle.ParseFromString(any_data.value())) {
+ DVLOG(1) << "Failed to parse PageBundle in any data";
+ NotifyParsingFailure();
+ return;
+ }
+
+ if (!page_bundle.archives_size()) {
+ DVLOG(1) << "No archive in PageBundle";
+ NotifyParsingFailure();
+ return;
+ }
+
+ std::vector<PageInfo> pages;
+ for (int i = 0; i < page_bundle.archives_size(); ++i) {
+ const proto::Archive& archive = page_bundle.archives(i);
+
+ if (!archive.page_infos_size()) {
+ DVLOG(1) << "No page in archive";
+ NotifyParsingFailure();
+ return;
+ }
+
+ // Only one page is available in PageInfos.
+ const proto::PageInfo& page_info = archive.page_infos(0);
+
+ if (page_info.url().empty()) {
+ DVLOG(1) << "Empty page url";
+ NotifyParsingFailure();
+ return;
+ }
+
+ PageInfo page;
+ page.url = page_info.url();
+ page.redirect_url = page_info.redirect_url();
+ if (page_info.has_status()) {
+ switch (page_info.status().code()) {
+ case proto::OK:
+ page.status = RenderStatus::RENDERED;
+ break;
+ case proto::NOT_FOUND:
+ page.status = RenderStatus::PENDING_TO_RENDER;
+ break;
+ case proto::FAILED_PRECONDITION:
+ page.status = RenderStatus::EXCEEDED_LIMIT;
+ break;
+ case proto::UNKNOWN:
+ page.status = RenderStatus::FAILED_TO_RENDER;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ } else {
+ page.status = RenderStatus::RENDERED;
+ }
+
+ if (page.status == RenderStatus::RENDERED) {
+ page.body_name = archive.body_name();
+ page.body_length = archive.body_length();
+ page.render_time =
+ base::Time::FromJavaTime(page_info.render_time().seconds() * 1000 +
+ page_info.render_time().nanos() / 1000000);
+ }
+
+ DVLOG(1) << "Got page " << page.url << " " << static_cast<int>(page.status)
+ << " " << page.body_name << " " << page.body_length;
+ pages.push_back(page);
+ }
+
+ callback_.Run(RequestStatus::SUCCESS, pages);
+}
+
+void GeneratePageBundleRequest::NotifyParsingFailure() {
+ callback_.Run(RequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ std::vector<PageInfo>());
+}
+
+} // offline_pages

Powered by Google App Engine
This is Rietveld 408576698