OLD | NEW |
---|---|
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/appcache/appcache_url_loader_job.h" | 5 #include "content/browser/appcache/appcache_url_loader_job.h" |
6 #include "content/browser/appcache/appcache_entry.h" | 6 #include "content/browser/appcache/appcache_histograms.h" |
7 #include "content/browser/url_loader_factory_getter.h" | |
8 #include "content/public/common/resource_type.h" | |
9 #include "net/base/io_buffer.h" | |
7 | 10 |
8 namespace content { | 11 namespace content { |
9 | 12 |
10 AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {} | 13 AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {} |
11 | 14 |
12 void AppCacheURLLoaderJob::Kill() {} | 15 void AppCacheURLLoaderJob::Kill() {} |
13 | 16 |
14 bool AppCacheURLLoaderJob::IsStarted() const { | 17 bool AppCacheURLLoaderJob::IsStarted() const { |
15 return false; | 18 return delivery_type_ != AWAITING_DELIVERY_ORDERS; |
16 } | |
17 | |
18 bool AppCacheURLLoaderJob::IsWaiting() const { | |
19 return false; | |
20 } | |
21 | |
22 bool AppCacheURLLoaderJob::IsDeliveringAppCacheResponse() const { | |
23 return false; | |
24 } | |
25 | |
26 bool AppCacheURLLoaderJob::IsDeliveringNetworkResponse() const { | |
27 return false; | |
28 } | |
29 | |
30 bool AppCacheURLLoaderJob::IsDeliveringErrorResponse() const { | |
31 return false; | |
32 } | |
33 | |
34 bool AppCacheURLLoaderJob::IsCacheEntryNotFound() const { | |
35 return false; | |
36 } | 19 } |
37 | 20 |
38 void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url, | 21 void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url, |
39 int64_t cache_id, | 22 int64_t cache_id, |
40 const AppCacheEntry& entry, | 23 const AppCacheEntry& entry, |
41 bool is_fallback) {} | 24 bool is_fallback) { |
42 | 25 delivery_type_ = APPCACHED_DELIVERY; |
43 void AppCacheURLLoaderJob::DeliverNetworkResponse() {} | 26 |
44 | 27 AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() - |
45 void AppCacheURLLoaderJob::DeliverErrorResponse() {} | 28 start_time_tick_); |
29 | |
30 manifest_url_ = manifest_url; | |
31 cache_id_ = cache_id; | |
32 entry_ = entry; | |
33 is_fallback_ = is_fallback; | |
34 | |
35 storage_->LoadResponseInfo(manifest_url_, entry_.response_id(), this); | |
36 } | |
37 | |
38 void AppCacheURLLoaderJob::DeliverNetworkResponse() { | |
39 delivery_type_ = NETWORK_DELIVERY; | |
40 | |
41 AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() - | |
42 start_time_tick_); | |
43 | |
44 url_loader_factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart( | |
michaeln
2017/06/07 02:53:46
I think we want to defer to the network by calling
ananta
2017/06/08 05:58:39
I added call to the loader callback here. We retur
| |
45 mojo::MakeRequest(&url_loader_network_), routing_id_, request_id_, | |
46 mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_)); | |
47 } | |
48 | |
49 void AppCacheURLLoaderJob::DeliverErrorResponse() { | |
50 delivery_type_ = ERROR_DELIVERY; | |
51 | |
52 AppCacheHistograms::AddErrorJobStartDelaySample(base::TimeTicks::Now() - | |
53 start_time_tick_); | |
54 // TODO(ananta) | |
55 // Add support to send out an error response. | |
michaeln
2017/06/07 02:53:46
see BlobURLLoader::NotifyCompleted() for an exampl
ananta
2017/06/08 05:58:39
Added a small implementation of NotifyCompleted().
| |
56 } | |
46 | 57 |
47 const GURL& AppCacheURLLoaderJob::GetURL() const { | 58 const GURL& AppCacheURLLoaderJob::GetURL() const { |
48 return url_; | 59 return request_.url; |
49 } | 60 } |
50 | 61 |
51 AppCacheURLLoaderJob::AppCacheURLLoaderJob() {} | 62 AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() { |
63 return this; | |
64 } | |
65 | |
66 void AppCacheURLLoaderJob::FollowRedirect() { | |
67 if (url_loader_network_) | |
68 url_loader_network_->FollowRedirect(); | |
69 } | |
70 | |
71 void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority, | |
72 int32_t intra_priority_value) { | |
73 NOTREACHED() << "We don't support SetPriority()"; | |
74 } | |
75 | |
76 void AppCacheURLLoaderJob::BindEndpoints( | |
77 const ResourceRequest& request, | |
78 mojom::URLLoaderAssociatedRequest url_loader_request, | |
79 int32_t routing_id, | |
80 int32_t request_id, | |
81 mojom::URLLoaderClientPtrInfo client_info) { | |
82 request_ = request; | |
83 | |
84 DCHECK(!binding_.is_bound()); | |
85 binding_.Bind(std::move(url_loader_request)); | |
86 | |
87 binding_.set_connection_error_handler(base::Bind( | |
88 &AppCacheURLLoaderJob::OnConnectionError, base::Unretained(this))); | |
89 | |
90 routing_id_ = routing_id; | |
91 request_id_ = request_id; | |
92 | |
93 client_info_.Bind(std::move(client_info)); | |
94 | |
95 // Send the cached AppCacheResponse if any. | |
96 if (info_.get()) | |
97 SendResponseInfo(); | |
98 } | |
99 | |
100 void AppCacheURLLoaderJob::SetURLLoaderFactoryGetter( | |
101 URLLoaderFactoryGetter* url_loader_factory_getter) { | |
102 url_loader_factory_getter_ = url_loader_factory_getter; | |
103 } | |
104 | |
105 AppCacheURLLoaderJob::AppCacheURLLoaderJob(const ResourceRequest& request, | |
106 AppCacheStorage* storage) | |
107 : request_(request), | |
108 storage_(storage), | |
109 start_time_tick_(base::TimeTicks::Now()), | |
110 cache_id_(kAppCacheNoCacheId), | |
111 is_fallback_(false), | |
112 buffer_(nullptr), | |
113 binding_(this), | |
114 routing_id_(-1), | |
115 request_id_(-1) {} | |
116 | |
117 void AppCacheURLLoaderJob::OnResponseInfoLoaded( | |
118 AppCacheResponseInfo* response_info, | |
119 int64_t response_id) { | |
120 DCHECK(IsDeliveringAppCacheResponse()); | |
121 | |
122 if (response_info) { | |
michaeln
2017/06/07 02:53:46
We shouldn't consume the LoaderRequest until here,
ananta
2017/06/08 05:58:39
Thanks. makes sense. done
| |
123 info_ = response_info; | |
124 reader_.reset( | |
125 storage_->CreateResponseReader(manifest_url_, entry_.response_id())); | |
126 | |
127 // TODO(ananta) | |
128 // Handle range requests. | |
129 | |
130 buffer_ = | |
131 new net::IOBuffer(static_cast<size_t>(info_->response_data_size())); | |
jam
2017/06/07 01:42:17
what if the response is really big, this would end
ananta
2017/06/07 20:57:16
Done.
| |
132 reader_->ReadData(buffer_.get(), info_->response_data_size(), | |
133 base::Bind(&AppCacheURLLoaderJob::OnReadComplete, | |
134 StaticAsWeakPtr(this))); | |
135 if (client_info_) | |
136 SendResponseInfo(); | |
137 } else { | |
138 // Error case here. We fallback to the network. | |
139 DeliverNetworkResponse(); | |
michaeln
2017/06/07 02:53:45
We should call LoaderCallback(nullptr) here to go
ananta
2017/06/07 20:57:16
I don't think we can do that at this point. It is
michaeln
2017/06/08 02:54:01
I'm suggesting that we should defer calling the Lo
ananta
2017/06/08 05:58:39
Done.
| |
140 AppCacheHistograms::CountResponseRetrieval( | |
141 false, IsResourceTypeFrame(request_.resource_type), | |
142 manifest_url_.GetOrigin()); | |
143 | |
144 cache_entry_not_found_ = true; | |
145 } | |
146 } | |
147 | |
148 void AppCacheURLLoaderJob::OnCacheLoaded(AppCache* cache, int64_t cache_id) { | |
149 NOTREACHED() << "Unhandled at the moment."; | |
150 } | |
151 | |
152 void AppCacheURLLoaderJob::OnReadComplete(int result) { | |
153 DLOG(WARNING) << "AppCache read completed with result: " << result; | |
154 | |
155 bool is_main_resource = IsResourceTypeFrame(request_.resource_type); | |
156 | |
157 if (result == 0) { | |
158 AppCacheHistograms::CountResponseRetrieval(true, is_main_resource, | |
159 manifest_url_.GetOrigin()); | |
160 } else if (result < 0) { | |
161 // Error case here. We fallback to the network. | |
162 DeliverNetworkResponse(); | |
michaeln
2017/06/07 02:53:46
At this point, it's too late to fallback to the ne
ananta
2017/06/07 20:57:16
Added a call to oncomplete here. Will work on it i
| |
163 AppCacheHistograms::CountResponseRetrieval(false, is_main_resource, | |
164 manifest_url_.GetOrigin()); | |
165 return; | |
166 } | |
167 | |
168 if (result > 0) { | |
169 uint32_t bytes_written = static_cast<uint32_t>(result); | |
170 // TODO(ananta) | |
171 // Use the IO buffer net adapter to efficiently pass the data over to the | |
172 // cliet. | |
173 mojo::WriteDataRaw(data_pipe_.producer_handle.get(), buffer_->data(), | |
michaeln
2017/06/07 02:53:46
We're assuming a MOJO_RESULT_OK here, if the resou
ananta
2017/06/07 20:57:16
Code has changed to async
| |
174 &bytes_written, MOJO_WRITE_DATA_FLAG_NONE); | |
175 reader_->ReadData(buffer_.get(), info_->response_data_size(), | |
176 base::Bind(&AppCacheURLLoaderJob::OnReadComplete, | |
177 base::Unretained(this))); | |
178 } | |
179 } | |
180 | |
181 void AppCacheURLLoaderJob::OnConnectionError() { | |
182 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); | |
183 } | |
184 | |
185 void AppCacheURLLoaderJob::SendResponseInfo() { | |
186 DCHECK(client_info_); | |
187 | |
188 const net::HttpResponseInfo* http_info = info_->http_response_info(); | |
189 | |
190 ResourceResponseHead response_head; | |
191 response_head.headers = new net::HttpResponseHeaders(""); | |
192 | |
193 std::string name; | |
194 std::string value; | |
195 | |
196 for (size_t it = 0; | |
197 http_info->headers->EnumerateHeaderLines(&it, &name, &value);) { | |
michaeln
2017/06/07 02:53:46
HttpResponseHeaders is a refcounted object, would
ananta
2017/06/07 20:57:16
Thanks done.
| |
198 response_head.headers->AddHeader(name + ": " + value); | |
199 } | |
200 | |
201 // TODO(ananta) | |
202 // Copy more fields. | |
203 http_info->headers->GetMimeType(&response_head.mime_type); | |
204 http_info->headers->GetCharset(&response_head.charset); | |
205 | |
206 response_head.request_time = http_info->request_time; | |
207 response_head.response_time = http_info->response_time; | |
208 response_head.content_length = info_->response_data_size(); | |
209 | |
210 client_info_->OnReceiveResponse(response_head, http_info->ssl_info, | |
211 mojom::DownloadedTempFilePtr()); | |
212 | |
213 client_info_->OnStartLoadingResponseBody( | |
214 std::move(data_pipe_.consumer_handle)); | |
215 } | |
52 | 216 |
53 } // namespace content | 217 } // namespace content |
OLD | NEW |