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

Side by Side Diff: components/offline_pages/core/prefetch/generate_page_bundle_request.cc

Issue 2873383004: [Offline Prefetch] Send GeneratePageBundleRequest to the server (Closed)
Patch Set: Address feedback + fix trybots 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/offline_pages/core/prefetch/generate_page_bundle_request.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/strings/string_util.h"
11 #include "components/offline_pages/core/prefetch/prefetch_request_fetcher.h"
12 #include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
13 #include "components/offline_pages/core/prefetch/proto/operation.pb.h"
14 #include "net/url_request/url_request_context_getter.h"
15 #include "url/gurl.h"
16
17 namespace offline_pages {
18
19 namespace {
20 // TODO(jianli): Update when server is ready.
21 const GURL kOfflinePrefetchServiceUrl(
22 "http://localhost:12345/v1:GeneratePageBundle");
23 }
24
25 GeneratePageBundleRequest::GeneratePageBundleRequest(
26 const std::string& user_agent,
27 const std::string& gcm_registration_id,
28 int max_bundle_size_bytes,
29 const std::vector<std::string>& page_urls,
30 net::URLRequestContextGetter* request_context_getter,
31 const FinishedCallback& callback)
32 : callback_(callback) {
33 proto::GeneratePageBundleRequest request;
34 request.set_user_agent(user_agent);
35 request.set_max_bundle_size_bytes(max_bundle_size_bytes);
36 request.set_output_format(proto::FORMAT_MHTML);
37 request.set_gcm_registration_id(gcm_registration_id);
38
39 for (const auto& page_url : page_urls) {
40 proto::PageParameters* page = request.add_pages();
41 page->set_url(page_url);
42 page->set_transformation(proto::NO_TRANSFORMATION);
43 }
44
45 std::string upload_data;
46 request.SerializeToString(&upload_data);
47
48 fetcher_.reset(new PrefetchRequestFetcher(
49 kOfflinePrefetchServiceUrl, upload_data, request_context_getter,
50 base::Bind(&GeneratePageBundleRequest::OnCompleted,
51 // Fetcher is owned by this instance.
52 base::Unretained(this))));
53 }
54
55 GeneratePageBundleRequest::~GeneratePageBundleRequest() {}
56
57 void GeneratePageBundleRequest::OnCompleted(PrefetchRequestStatus status,
58 const std::string& data) {
59 proto::Operation operation;
60 if (!operation.ParseFromString(data)) {
61 DVLOG(1) << "Failed to parse GeneratePageBundle response";
62 NotifyParsingFailure();
63 return;
64 }
65
66 if (operation.done())
67 ParseDoneOperationResponse(operation);
68 else
69 ParsePendingOperationResponse(operation);
70 }
71
72 void GeneratePageBundleRequest::ParseDoneOperationResponse(
73 const proto::Operation& operation) {
74 if (operation.result_case() == proto::Operation::kError) {
75 DVLOG(1) << "Error found in GeneratePageBundle response";
76 NotifyParsingFailure();
77 return;
78 }
79
80 DCHECK_EQ(proto::Operation::kResponse, operation.result_case());
81 ParsePageBundleInAnyData(operation.response());
82 }
83
84 void GeneratePageBundleRequest::ParsePendingOperationResponse(
85 const proto::Operation& operation) {
86 if (!operation.has_metadata()) {
87 DVLOG(1) << "metadata not found in GeneratePageBundle response";
88 NotifyParsingFailure();
89 return;
90 }
91 ParsePageBundleInAnyData(operation.metadata());
92 }
93
94 void GeneratePageBundleRequest::ParsePageBundleInAnyData(
95 const proto::Any& any_data) {
96 if (!base::StartsWith(any_data.type_url(), "type.googleapis.com/",
dewittj 2017/05/11 21:51:48 We should probably stick type_url into a GURL and
jianli 2017/05/11 23:07:27 Changed to validate the full URL.
97 base::CompareCase::SENSITIVE) &&
98 !base::EndsWith(any_data.type_url(), ".PageBundle",
99 base::CompareCase::SENSITIVE)) {
100 DVLOG(1) << "Wrong type url in any data";
101 NotifyParsingFailure();
102 return;
103 }
104
105 proto::PageBundle page_bundle;
106 if (!page_bundle.ParseFromString(any_data.value())) {
107 DVLOG(1) << "Failed to parse PageBundle in any data";
108 NotifyParsingFailure();
109 return;
110 }
111
112 if (!page_bundle.archives_size()) {
113 DVLOG(1) << "No archive in PageBundle";
114 NotifyParsingFailure();
115 return;
116 }
117
118 std::vector<RenderPageInfo> pages;
119 for (int i = 0; i < page_bundle.archives_size(); ++i) {
120 const proto::Archive& archive = page_bundle.archives(i);
121
122 if (!archive.page_infos_size()) {
123 DVLOG(1) << "No page in archive";
124 NotifyParsingFailure();
125 return;
126 }
127
128 // Only one page is available in PageInfos.
129 const proto::PageInfo& page_info = archive.page_infos(0);
130
131 if (page_info.url().empty()) {
132 DVLOG(1) << "Empty page url";
133 NotifyParsingFailure();
134 return;
135 }
136
137 RenderPageInfo page;
138 page.url = page_info.url();
139 page.redirect_url = page_info.redirect_url();
140 if (page_info.has_status()) {
141 switch (page_info.status().code()) {
142 case proto::OK:
143 page.status = RenderStatus::RENDERED;
144 break;
145 case proto::NOT_FOUND:
146 page.status = RenderStatus::PENDING;
147 break;
148 case proto::FAILED_PRECONDITION:
149 page.status = RenderStatus::EXCEEDED_LIMIT;
150 break;
151 case proto::UNKNOWN:
152 page.status = RenderStatus::FAILED;
153 break;
154 default:
155 NOTREACHED();
156 break;
157 }
158 } else {
159 page.status = RenderStatus::RENDERED;
160 }
161
162 if (page.status == RenderStatus::RENDERED) {
163 page.body_name = archive.body_name();
164 page.body_length = archive.body_length();
165 page.render_time =
166 base::Time::FromJavaTime(page_info.render_time().seconds() * 1000 +
167 page_info.render_time().nanos() / 1000000);
168 }
169
170 DVLOG(1) << "Got page " << page.url << " " << static_cast<int>(page.status)
171 << " " << page.body_name << " " << page.body_length;
172 pages.push_back(page);
173 }
174
175 callback_.Run(PrefetchRequestStatus::SUCCESS, pages);
176 }
177
178 void GeneratePageBundleRequest::NotifyParsingFailure() {
179 callback_.Run(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
180 std::vector<RenderPageInfo>());
181 }
182
183 } // offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698