| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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 "sky/services/platform/weburlloader_impl.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "base/thread_task_runner_handle.h" | |
| 11 #include "mojo/common/common_type_converters.h" | |
| 12 #include "mojo/services/network/public/interfaces/network_service.mojom.h" | |
| 13 #include "sky/engine/public/platform/WebURLError.h" | |
| 14 #include "sky/engine/public/platform/WebURLLoadTiming.h" | |
| 15 #include "sky/engine/public/platform/WebURLLoaderClient.h" | |
| 16 #include "sky/engine/public/platform/WebURLResponse.h" | |
| 17 #include "sky/services/platform/net_constants.h" | |
| 18 #include "sky/services/platform/url_request_types.h" | |
| 19 | |
| 20 namespace sky { | |
| 21 namespace { | |
| 22 | |
| 23 static blink::WebURLResponse::HTTPVersion StatusLineToHTTPVersion( | |
| 24 const mojo::String& status_line) { | |
| 25 if (status_line.is_null()) | |
| 26 return blink::WebURLResponse::HTTP_0_9; | |
| 27 | |
| 28 if (StartsWithASCII(status_line, "HTTP/1.0", true)) | |
| 29 return blink::WebURLResponse::HTTP_1_0; | |
| 30 | |
| 31 if (StartsWithASCII(status_line, "HTTP/1.1", true)) | |
| 32 return blink::WebURLResponse::HTTP_1_1; | |
| 33 | |
| 34 return blink::WebURLResponse::Unknown; | |
| 35 } | |
| 36 | |
| 37 blink::WebURLResponse ToWebURLResponse(const mojo::URLResponsePtr& url_response)
{ | |
| 38 blink::WebURLResponse result; | |
| 39 result.initialize(); | |
| 40 result.setURL(GURL(url_response->url)); | |
| 41 result.setMIMEType(blink::WebString::fromUTF8(url_response->mime_type)); | |
| 42 result.setTextEncodingName(blink::WebString::fromUTF8(url_response->charset)); | |
| 43 result.setHTTPVersion(StatusLineToHTTPVersion(url_response->status_line)); | |
| 44 result.setHTTPStatusCode(url_response->status_code); | |
| 45 | |
| 46 // TODO(darin): Initialize timing properly. | |
| 47 blink::WebURLLoadTiming timing; | |
| 48 timing.initialize(); | |
| 49 result.setLoadTiming(timing); | |
| 50 | |
| 51 for (size_t i = 0; i < url_response->headers.size(); ++i) { | |
| 52 const auto& header = url_response->headers[i]; | |
| 53 result.setHTTPHeaderField(blink::WebString::fromUTF8(header->name), | |
| 54 blink::WebString::fromUTF8(header->value)); | |
| 55 } | |
| 56 | |
| 57 return result; | |
| 58 } | |
| 59 | |
| 60 } // namespace | |
| 61 | |
| 62 WebURLLoaderImpl::WebURLLoaderImpl(mojo::NetworkService* network_service) | |
| 63 : client_(NULL), | |
| 64 weak_factory_(this) { | |
| 65 network_service->CreateURLLoader(GetProxy(&url_loader_)); | |
| 66 } | |
| 67 | |
| 68 WebURLLoaderImpl::~WebURLLoaderImpl() { | |
| 69 } | |
| 70 | |
| 71 void WebURLLoaderImpl::loadAsynchronously(const blink::WebURLRequest& request, | |
| 72 blink::WebURLLoaderClient* client) { | |
| 73 client_ = client; | |
| 74 url_ = request.url(); | |
| 75 | |
| 76 mojo::URLRequestPtr url_request = mojo::URLRequest::From(request); | |
| 77 url_request->auto_follow_redirects = false; | |
| 78 url_loader_->Start(url_request.Pass(), | |
| 79 base::Bind(&WebURLLoaderImpl::OnReceivedResponse, | |
| 80 weak_factory_.GetWeakPtr())); | |
| 81 } | |
| 82 | |
| 83 void WebURLLoaderImpl::cancel() { | |
| 84 url_loader_.reset(); | |
| 85 response_body_stream_.reset(); | |
| 86 | |
| 87 mojo::URLResponsePtr failed_response(mojo::URLResponse::New()); | |
| 88 failed_response->url = mojo::String::From(url_); | |
| 89 failed_response->error = mojo::NetworkError::New(); | |
| 90 failed_response->error->code = kNetErrorAborted; | |
| 91 | |
| 92 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 93 FROM_HERE, | |
| 94 base::Bind(&WebURLLoaderImpl::OnReceivedResponse, | |
| 95 weak_factory_.GetWeakPtr(), | |
| 96 base::Passed(&failed_response))); | |
| 97 } | |
| 98 | |
| 99 void WebURLLoaderImpl::OnReceivedResponse(mojo::URLResponsePtr url_response) { | |
| 100 url_ = GURL(url_response->url); | |
| 101 | |
| 102 if (url_response->error) { | |
| 103 OnReceivedError(url_response.Pass()); | |
| 104 } else if (url_response->redirect_url) { | |
| 105 OnReceivedRedirect(url_response.Pass()); | |
| 106 } else { | |
| 107 base::WeakPtr<WebURLLoaderImpl> self(weak_factory_.GetWeakPtr()); | |
| 108 client_->didReceiveResponse(this, ToWebURLResponse(url_response)); | |
| 109 | |
| 110 // We may have been deleted during didReceiveResponse. | |
| 111 if (!self) | |
| 112 return; | |
| 113 | |
| 114 // Start streaming data | |
| 115 response_body_stream_ = url_response->body.Pass(); | |
| 116 ReadMore(); | |
| 117 } | |
| 118 } | |
| 119 | |
| 120 void WebURLLoaderImpl::OnReceivedError(mojo::URLResponsePtr url_response) { | |
| 121 blink::WebURLError web_error; | |
| 122 web_error.domain = blink::WebString::fromUTF8(kNetErrorDomain); | |
| 123 web_error.reason = url_response->error->code; | |
| 124 web_error.unreachableURL = GURL(url_response->url); | |
| 125 web_error.staleCopyInCache = false; | |
| 126 web_error.isCancellation = | |
| 127 url_response->error->code == kNetErrorAborted ? true : false; | |
| 128 | |
| 129 client_->didFail(this, web_error); | |
| 130 } | |
| 131 | |
| 132 void WebURLLoaderImpl::OnReceivedRedirect(mojo::URLResponsePtr url_response) { | |
| 133 blink::WebURLRequest new_request; | |
| 134 new_request.initialize(); | |
| 135 new_request.setURL(GURL(url_response->redirect_url)); | |
| 136 new_request.setHTTPMethod( | |
| 137 blink::WebString::fromUTF8(url_response->redirect_method)); | |
| 138 | |
| 139 client_->willSendRequest(this, new_request, ToWebURLResponse(url_response)); | |
| 140 // TODO(darin): Check if new_request was rejected. | |
| 141 | |
| 142 url_loader_->FollowRedirect( | |
| 143 base::Bind(&WebURLLoaderImpl::OnReceivedResponse, | |
| 144 weak_factory_.GetWeakPtr())); | |
| 145 } | |
| 146 | |
| 147 void WebURLLoaderImpl::ReadMore() { | |
| 148 const void* buf; | |
| 149 uint32_t buf_size; | |
| 150 MojoResult rv = mojo::BeginReadDataRaw(response_body_stream_.get(), | |
| 151 &buf, | |
| 152 &buf_size, | |
| 153 MOJO_READ_DATA_FLAG_NONE); | |
| 154 if (rv == MOJO_RESULT_OK) { | |
| 155 client_->didReceiveData(this, static_cast<const char*>(buf), buf_size, -1); | |
| 156 EndReadDataRaw(response_body_stream_.get(), buf_size); | |
| 157 WaitToReadMore(); | |
| 158 } else if (rv == MOJO_RESULT_SHOULD_WAIT) { | |
| 159 WaitToReadMore(); | |
| 160 } else if (rv == MOJO_RESULT_FAILED_PRECONDITION) { | |
| 161 // We reached end-of-file. | |
| 162 double finish_time = base::Time::Now().ToDoubleT(); | |
| 163 client_->didFinishLoading( | |
| 164 this, | |
| 165 finish_time, | |
| 166 blink::WebURLLoaderClient::kUnknownEncodedDataLength); | |
| 167 } else { | |
| 168 // TODO(darin): Oops! | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 void WebURLLoaderImpl::WaitToReadMore() { | |
| 173 handle_watcher_.Start( | |
| 174 response_body_stream_.get(), | |
| 175 MOJO_HANDLE_SIGNAL_READABLE, | |
| 176 MOJO_DEADLINE_INDEFINITE, | |
| 177 base::Bind(&WebURLLoaderImpl::OnResponseBodyStreamReady, | |
| 178 weak_factory_.GetWeakPtr())); | |
| 179 } | |
| 180 | |
| 181 void WebURLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { | |
| 182 ReadMore(); | |
| 183 } | |
| 184 | |
| 185 } // namespace sky | |
| OLD | NEW |