blob: 3a42fa36d90f0971cf7c0cebfb8104114cf46fd2 [file] [log] [blame]
// 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();
}
// 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;
if (error) {
delegate->DidFail(client_, *error, data.size(), 0, 0);
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