| // Copyright 2016 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 "third_party/blink/renderer/platform/testing/weburl_loader_mock.h" |
| |
| #include <utility> |
| |
| #include "third_party/blink/public/platform/url_conversion.h" |
| #include "third_party/blink/public/platform/web_data.h" |
| #include "third_party/blink/public/platform/web_security_origin.h" |
| #include "third_party/blink/public/platform/web_url_error.h" |
| #include "third_party/blink/public/platform/web_url_loader_client.h" |
| #include "third_party/blink/renderer/platform/shared_buffer.h" |
| #include "third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h" |
| #include "third_party/blink/renderer/platform/wtf/time.h" |
| |
| namespace blink { |
| |
| namespace { |
| |
| void AssertFallbackLoaderAvailability(const WebURL& url, |
| const WebURLLoader* default_loader) { |
| DCHECK(KURL(url).ProtocolIsData()) |
| << "shouldn't be falling back: " << url.GetString().Utf8(); |
| DCHECK(default_loader) << "default_loader wasn't set: " |
| << url.GetString().Utf8(); |
| } |
| |
| } // namespace |
| |
| WebURLLoaderMock::WebURLLoaderMock(WebURLLoaderMockFactoryImpl* factory, |
| std::unique_ptr<WebURLLoader> default_loader) |
| : factory_(factory), |
| default_loader_(std::move(default_loader)), |
| weak_factory_(this) {} |
| |
| WebURLLoaderMock::~WebURLLoaderMock() { |
| Cancel(); |
| } |
| |
| void WebURLLoaderMock::ServeAsynchronousRequest( |
| WebURLLoaderTestDelegate* delegate, |
| const WebURLResponse& response, |
| const WebData& data, |
| const base::Optional<WebURLError>& error) { |
| DCHECK(!using_default_loader_); |
| if (!client_) |
| return; |
| |
| // If no delegate is provided then create an empty one. The default behavior |
| // will just proxy to the client. |
| std::unique_ptr<WebURLLoaderTestDelegate> default_delegate; |
| if (!delegate) { |
| default_delegate = std::make_unique<WebURLLoaderTestDelegate>(); |
| delegate = default_delegate.get(); |
| } |
| |
| if (error) { |
| delegate->DidFail(client_, *error, data.size(), 0, 0); |
| return; |
| } |
| |
| // didReceiveResponse() and didReceiveData() might end up getting ::cancel() |
| // to be called which will make the ResourceLoader to delete |this|. |
| base::WeakPtr<WebURLLoaderMock> self = weak_factory_.GetWeakPtr(); |
| |
| delegate->DidReceiveResponse(client_, response); |
| if (!self) |
| return; |
| |
| data.ForEachSegment([this, &delegate, &self](const char* segment, |
| size_t segment_size, |
| size_t segment_offset) { |
| delegate->DidReceiveData(client_, segment, segment_size); |
| // DidReceiveData() may clear the |self| weak ptr. We stop iterating |
| // when that happens. |
| return self; |
| }); |
| |
| if (!self) |
| return; |
| |
| delegate->DidFinishLoading(client_, TimeTicks(), data.size(), data.size(), |
| data.size()); |
| } |
| |
| WebURL WebURLLoaderMock::ServeRedirect( |
| const WebURLRequest& request, |
| const WebURLResponse& redirect_response) { |
| KURL redirect_url(redirect_response.HttpHeaderField("Location")); |
| |
| base::WeakPtr<WebURLLoaderMock> self = weak_factory_.GetWeakPtr(); |
| |
| bool report_raw_headers = false; |
| bool follow = client_->WillFollowRedirect( |
| redirect_url, redirect_url, |
| WebSecurityOrigin::Create(WebURL(redirect_url)), WebString(), |
| network::mojom::ReferrerPolicy::kDefault, request.HttpMethod(), |
| redirect_response, report_raw_headers); |
| // |this| might be deleted in willFollowRedirect(). |
| if (!self) |
| return redirect_url; |
| |
| if (!follow) |
| Cancel(); |
| |
| return redirect_url; |
| } |
| |
| void WebURLLoaderMock::LoadSynchronously( |
| const WebURLRequest& request, |
| WebURLLoaderClient* client, |
| WebURLResponse& response, |
| base::Optional<WebURLError>& error, |
| WebData& data, |
| int64_t& encoded_data_length, |
| int64_t& encoded_body_length, |
| blink::WebBlobInfo& downloaded_blob) { |
| if (factory_->IsMockedURL(request.Url())) { |
| factory_->LoadSynchronously(request, &response, &error, &data, |
| &encoded_data_length); |
| return; |
| } |
| AssertFallbackLoaderAvailability(request.Url(), default_loader_.get()); |
| using_default_loader_ = true; |
| default_loader_->LoadSynchronously(request, client, response, error, data, |
| encoded_data_length, encoded_body_length, |
| downloaded_blob); |
| } |
| |
| void WebURLLoaderMock::LoadAsynchronously(const WebURLRequest& request, |
| WebURLLoaderClient* client) { |
| DCHECK(client); |
| if (factory_->IsMockedURL(request.Url())) { |
| client_ = client; |
| factory_->LoadAsynchronouly(request, this); |
| return; |
| } |
| AssertFallbackLoaderAvailability(request.Url(), default_loader_.get()); |
| using_default_loader_ = true; |
| default_loader_->LoadAsynchronously(request, client); |
| } |
| |
| void WebURLLoaderMock::Cancel() { |
| if (using_default_loader_) { |
| default_loader_->Cancel(); |
| return; |
| } |
| client_ = nullptr; |
| factory_->CancelLoad(this); |
| } |
| |
| void WebURLLoaderMock::SetDefersLoading(bool deferred) { |
| is_deferred_ = deferred; |
| if (using_default_loader_) { |
| default_loader_->SetDefersLoading(deferred); |
| return; |
| } |
| |
| // Ignores setDefersLoading(false) safely. |
| if (!deferred) |
| return; |
| |
| // setDefersLoading(true) is not implemented. |
| NOTIMPLEMENTED(); |
| } |
| |
| void WebURLLoaderMock::DidChangePriority(WebURLRequest::Priority new_priority, |
| int intra_priority_value) {} |
| |
| base::WeakPtr<WebURLLoaderMock> WebURLLoaderMock::GetWeakPtr() { |
| return weak_factory_.GetWeakPtr(); |
| } |
| |
| } // namespace blink |