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

Unified Diff: content/browser/appcache/appcache_url_loader_job.cc

Issue 2902653002: Get main frame and subframe AppCache loads to work. (Closed)
Patch Set: Use weak ptr in the url loader job through out. Created 3 years, 6 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: content/browser/appcache/appcache_url_loader_job.cc
diff --git a/content/browser/appcache/appcache_url_loader_job.cc b/content/browser/appcache/appcache_url_loader_job.cc
index 09f15459e3bd1a54fd050e1c1669795c9991956b..f87c96bac3e1914478d86275c291d4939c868f0c 100644
--- a/content/browser/appcache/appcache_url_loader_job.cc
+++ b/content/browser/appcache/appcache_url_loader_job.cc
@@ -3,7 +3,10 @@
// found in the LICENSE file.
#include "content/browser/appcache/appcache_url_loader_job.h"
-#include "content/browser/appcache/appcache_entry.h"
+#include "content/browser/appcache/appcache_histograms.h"
+#include "content/browser/url_loader_factory_getter.h"
+#include "content/common/net_adapters.h"
+#include "content/public/common/resource_type.h"
namespace content {
@@ -12,42 +15,264 @@ AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {}
void AppCacheURLLoaderJob::Kill() {}
bool AppCacheURLLoaderJob::IsStarted() const {
- return false;
+ return delivery_type_ != AWAITING_DELIVERY_ORDERS;
}
-bool AppCacheURLLoaderJob::IsWaiting() const {
- return false;
+void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
+ int64_t cache_id,
+ const AppCacheEntry& entry,
+ bool is_fallback) {
+ delivery_type_ = APPCACHED_DELIVERY;
+
+ AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() -
+ start_time_tick_);
+
+ manifest_url_ = manifest_url;
+ cache_id_ = cache_id;
+ entry_ = entry;
+ is_fallback_ = is_fallback;
+
+ storage_->LoadResponseInfo(manifest_url_, entry_.response_id(), this);
michaeln 2017/06/09 02:06:18 Unfortunately, the rawptr is a problem We're goin
ananta 2017/06/09 04:48:19 I added a call to CancelDelegateCallbacks in the d
michaeln 2017/06/09 19:59:53 The other class is actually safe but its not at al
}
-bool AppCacheURLLoaderJob::IsDeliveringAppCacheResponse() const {
- return false;
+void AppCacheURLLoaderJob::DeliverNetworkResponse() {
+ delivery_type_ = NETWORK_DELIVERY;
+
+ AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() -
+ start_time_tick_);
+
+ // In network service land, if we are processing a navigation request, we
+ // need to inform the loader callback that we are not going to handle this
+ // request. The loader callback is valid only for navigation requests.
+ if (!loader_callback_.is_null()) {
+ std::move(loader_callback_).Run(StartLoaderCallback());
+ return;
+ }
+
+ url_loader_factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart(
michaeln 2017/06/09 01:48:29 We don't yet know if there will be a chain of hand
ananta 2017/06/09 04:48:19 Removed
+ mojo::MakeRequest(&url_loader_network_), routing_id_, request_id_,
+ mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_));
}
-bool AppCacheURLLoaderJob::IsDeliveringNetworkResponse() const {
- return false;
+void AppCacheURLLoaderJob::DeliverErrorResponse() {
+ delivery_type_ = ERROR_DELIVERY;
+
+ // TODO(ananta)
+ // Fill up the correct error code here and add support in NotifyError() to
+ // generate a proper error response.
+ NotifyCompleted(net::ERR_UNEXPECTED);
+
+ AppCacheHistograms::AddErrorJobStartDelaySample(base::TimeTicks::Now() -
+ start_time_tick_);
}
-bool AppCacheURLLoaderJob::IsDeliveringErrorResponse() const {
- return false;
+const GURL& AppCacheURLLoaderJob::GetURL() const {
+ return request_.url;
}
-bool AppCacheURLLoaderJob::IsCacheEntryNotFound() const {
- return false;
+AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() {
+ return this;
}
-void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
- int64_t cache_id,
- const AppCacheEntry& entry,
- bool is_fallback) {}
+void AppCacheURLLoaderJob::FollowRedirect() {
+ if (url_loader_network_)
+ url_loader_network_->FollowRedirect();
+}
+
+void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) {
+ NOTREACHED() << "We don't support SetPriority()";
+}
-void AppCacheURLLoaderJob::DeliverNetworkResponse() {}
+void AppCacheURLLoaderJob::Start(int routing_id,
+ int request_id,
+ mojom::URLLoaderRequest request,
+ mojom::URLLoaderClientPtr client) {
+ DCHECK(!binding_.is_bound());
+ binding_.Bind(std::move(request));
-void AppCacheURLLoaderJob::DeliverErrorResponse() {}
+ binding_.set_connection_error_handler(base::Bind(
+ &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
-const GURL& AppCacheURLLoaderJob::GetURL() const {
- return url_;
+ routing_id_ = routing_id;
+ request_id_ = request_id;
+
+ client_info_ = std::move(client);
+
+ // Send the cached AppCacheResponse if any.
+ if (info_.get())
+ SendResponseInfo();
+}
+
+void AppCacheURLLoaderJob::SetURLLoaderFactoryGetter(
+ URLLoaderFactoryGetter* url_loader_factory_getter) {
+ url_loader_factory_getter_ = url_loader_factory_getter;
+}
+
+AppCacheURLLoaderJob::AppCacheURLLoaderJob(const ResourceRequest& request,
+ AppCacheStorage* storage)
+ : request_(request),
+ storage_(storage),
+ start_time_tick_(base::TimeTicks::Now()),
+ cache_id_(kAppCacheNoCacheId),
+ is_fallback_(false),
+ buffer_(nullptr),
+ binding_(this),
+ routing_id_(-1),
+ request_id_(-1),
+ writable_handle_watcher_(FROM_HERE,
+ mojo::SimpleWatcher::ArmingPolicy::MANUAL) {}
+
+void AppCacheURLLoaderJob::OnResponseInfoLoaded(
+ AppCacheResponseInfo* response_info,
+ int64_t response_id) {
+ DCHECK(IsDeliveringAppCacheResponse());
+
+ if (response_info) {
+ info_ = response_info;
+ reader_.reset(
+ storage_->CreateResponseReader(manifest_url_, entry_.response_id()));
+
+ if (!loader_callback_.is_null()) {
michaeln 2017/06/09 01:48:30 in our current use case, navigation, this is never
ananta 2017/06/09 04:48:19 Replaced with a DCHECK
+ std::move(loader_callback_)
+ .Run(base::Bind(&AppCacheURLLoaderJob::Start, StaticAsWeakPtr(this),
+ 0, 0));
+ }
+
+ // TODO(ananta)
+ // Handle range requests.
+
+ response_body_stream_ = std::move(data_pipe_.producer_handle);
+
+ // Wait for the data pipe to be ready to accept data.
+ writable_handle_watcher_.Watch(
+ response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ base::Bind(&AppCacheURLLoaderJob::OnResponseBodyStreamReady,
michaeln 2017/06/09 01:48:29 is it possible/expected for OnResponseBodyStreamRe
ananta 2017/06/09 04:48:19 It is on the same thread?. Unless I am missing som
+ StaticAsWeakPtr(this)));
+
+ if (client_info_)
+ SendResponseInfo();
+
+ ReadMore();
+ } else {
+ // Error case here. We fallback to the network.
+ // TODO(ananta)
+ // Should we be invoking the loader callback here to give control to the
+ // next handler in the chain?.
michaeln 2017/06/09 01:48:29 The TODO comment seems stale or misplaced, for nav
ananta 2017/06/09 04:48:19 Thanks. Removed the comment.
+ DeliverNetworkResponse();
+ AppCacheHistograms::CountResponseRetrieval(
+ false, IsResourceTypeFrame(request_.resource_type),
+ manifest_url_.GetOrigin());
+
+ cache_entry_not_found_ = true;
+ }
+}
+
+void AppCacheURLLoaderJob::OnCacheLoaded(AppCache* cache, int64_t cache_id) {
+ NOTREACHED() << "Unhandled at the moment.";
+}
+
+void AppCacheURLLoaderJob::OnReadComplete(int result) {
+ DLOG(WARNING) << "AppCache read completed with result: " << result;
+
+ bool is_main_resource = IsResourceTypeFrame(request_.resource_type);
+
+ if (result == 0) {
+ NotifyCompleted(result);
+ AppCacheHistograms::CountResponseRetrieval(true, is_main_resource,
+ manifest_url_.GetOrigin());
michaeln 2017/06/09 01:48:30 you could early return here and avoid the if (resu
ananta 2017/06/09 04:48:19 Done.
+ } else if (result < 0) {
+ // TODO(ananta)
+ // Populate the relevant fields of the ResourceRequestCompletionStatus
+ // structure.
+ NotifyCompleted(result);
+ AppCacheHistograms::CountResponseRetrieval(false, is_main_resource,
+ manifest_url_.GetOrigin());
+ return;
+ }
+
+ if (result > 0) {
+ uint32_t bytes_written = static_cast<uint32_t>(result);
+ response_body_stream_ = pending_write_->Complete(bytes_written);
+ pending_write_ = nullptr;
+ ReadMore();
+ }
+}
+
+void AppCacheURLLoaderJob::OnConnectionError() {
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
+}
+
+void AppCacheURLLoaderJob::SendResponseInfo() {
+ DCHECK(client_info_);
+
+ // If this is null it means the response information was sent to the client.
+ if (!data_pipe_.consumer_handle.is_valid())
+ return;
+
+ const net::HttpResponseInfo* http_info = info_->http_response_info();
+
+ ResourceResponseHead response_head;
+ response_head.headers = http_info->headers;
+
+ // TODO(ananta)
+ // Copy more fields.
+ http_info->headers->GetMimeType(&response_head.mime_type);
+ http_info->headers->GetCharset(&response_head.charset);
+
+ response_head.request_time = http_info->request_time;
+ response_head.response_time = http_info->response_time;
+ response_head.content_length = info_->response_data_size();
+
+ client_info_->OnReceiveResponse(response_head, http_info->ssl_info,
+ mojom::DownloadedTempFilePtr());
+
+ client_info_->OnStartLoadingResponseBody(
+ std::move(data_pipe_.consumer_handle));
}
-AppCacheURLLoaderJob::AppCacheURLLoaderJob() {}
+void AppCacheURLLoaderJob::ReadMore() {
+ DCHECK(!pending_write_.get());
+
+ uint32_t num_bytes;
+ // TODO: we should use the abstractions in MojoAsyncResourceHandler.
+ MojoResult result = NetToMojoPendingBuffer::BeginWrite(
+ &response_body_stream_, &pending_write_, &num_bytes);
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ // The pipe is full. We need to wait for it to have more space.
+ writable_handle_watcher_.ArmOrNotify();
+ return;
+ } else if (result != MOJO_RESULT_OK) {
+ // The response body stream is in a bad state. Bail.
+ // TODO: How should this be communicated to our client?
michaeln 2017/06/09 01:48:29 Probably NotifyComplete(ERR)? As coded will progre
ananta 2017/06/09 04:48:19 Added a call to NotifyCompleted here.
+ writable_handle_watcher_.Cancel();
+ response_body_stream_.reset();
+ return;
+ }
+
+ CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes);
+ buffer_ = nullptr;
+ buffer_ = new NetToMojoIOBuffer(pending_write_.get());
michaeln 2017/06/09 01:48:29 Is the buffer_ data member is needed? It's only ac
ananta 2017/06/09 04:48:19 The buffer_ member should not be needed I think. R
+
+ reader_->ReadData(
+ buffer_.get(), info_->response_data_size(),
+ base::Bind(&AppCacheURLLoaderJob::OnReadComplete, StaticAsWeakPtr(this)));
+}
+
+void AppCacheURLLoaderJob::OnResponseBodyStreamReady(MojoResult result) {
+ // TODO: Handle a bad |result| value.
michaeln 2017/06/09 01:48:30 ditto probably NotifyComplete(ERR)
ananta 2017/06/09 04:48:19 Done.
+ DCHECK_EQ(result, MOJO_RESULT_OK);
+ ReadMore();
+}
+
+void AppCacheURLLoaderJob::NotifyCompleted(int error_code) {
+ // TODO(ananta)
+ // Fill other details in the ResourceRequestCompletionStatus structure.
+ // In case of an error we may need to call OnReceiveResponse on the client.
+ // That requires HTTP header generation etc.
michaeln 2017/06/09 01:48:29 I think we only need http header generation and a
ananta 2017/06/09 04:48:19 Thanks. moved this comment to the DeliverErrorResp
+ ResourceRequestCompletionStatus request_complete_data;
+ request_complete_data.error_code = error_code;
+ client_info_->OnComplete(request_complete_data);
+}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698