#include "third_party/blink/public/common/loader/throttling_url_loader.h"
#include <string_view>
#include <vector>
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/redirect_util.h"
#include "services/network/public/cpp/cors/cors.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/record_ontransfersizeupdate_utils.h"
#include "services/network/public/mojom/early_hints.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
namespace blink {
namespace {
void RemoveModifiedHeadersBeforeMerge(
net::HttpRequestHeaders* modified_headers) { … }
void MergeRemovedHeaders(std::vector<std::string>* removed_headers_A,
const std::vector<std::string>& removed_headers_B) { … }
#if DCHECK_IS_ON()
void CheckThrottleWillNotCauseCorsPreflight(
const std::set<std::string>& initial_headers,
const std::set<std::string>& initial_cors_exempt_headers,
const net::HttpRequestHeaders& headers,
const net::HttpRequestHeaders& cors_exempt_headers,
const std::vector<std::string> cors_exempt_header_list) { … }
#endif
void RecordHistogram(const std::string& stage,
base::Time start,
const std::string& metric_type) { … }
void RecordDeferTimeHistogram(const std::string& stage,
base::Time start,
const char* throttle_name) { … }
void RecordExecutionTimeHistogram(const std::string& stage, base::Time start) { … }
}
const char ThrottlingURLLoader::kFollowRedirectReason[] = …;
class ThrottlingURLLoader::ForwardingThrottleDelegate
: public URLLoaderThrottle::Delegate { … };
ThrottlingURLLoader::StartInfo::StartInfo(
scoped_refptr<network::SharedURLLoaderFactory> in_url_loader_factory,
int32_t in_request_id,
uint32_t in_options,
network::ResourceRequest* in_url_request,
scoped_refptr<base::SequencedTaskRunner> in_task_runner,
std::optional<std::vector<std::string>> in_cors_exempt_header_list)
: … { … }
ThrottlingURLLoader::StartInfo::~StartInfo() = default;
ThrottlingURLLoader::ResponseInfo::ResponseInfo(
network::mojom::URLResponseHeadPtr in_response_head)
: … { … }
ThrottlingURLLoader::ResponseInfo::~ResponseInfo() = default;
ThrottlingURLLoader::RedirectInfo::RedirectInfo(
const net::RedirectInfo& in_redirect_info,
network::mojom::URLResponseHeadPtr in_response_head)
: … { … }
ThrottlingURLLoader::RedirectInfo::~RedirectInfo() = default;
ThrottlingURLLoader::PriorityInfo::PriorityInfo(
net::RequestPriority in_priority,
int32_t in_intra_priority_value)
: … { … }
std::unique_ptr<ThrottlingURLLoader> ThrottlingURLLoader::CreateLoaderAndStart(
scoped_refptr<network::SharedURLLoaderFactory> factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
int32_t request_id,
uint32_t options,
network::ResourceRequest* url_request,
network::mojom::URLLoaderClient* client,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
scoped_refptr<base::SequencedTaskRunner> task_runner,
std::optional<std::vector<std::string>> cors_exempt_header_list,
ClientReceiverDelegate* client_receiver_delegate) { … }
ThrottlingURLLoader::~ThrottlingURLLoader() { … }
void ThrottlingURLLoader::FollowRedirectForcingRestart() { … }
void ThrottlingURLLoader::ResetForFollowRedirect(
network::ResourceRequest& resource_request,
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const net::HttpRequestHeaders& modified_cors_exempt_headers) { … }
void ThrottlingURLLoader::RestartWithFactory(
scoped_refptr<network::SharedURLLoaderFactory> factory,
uint32_t url_loader_options) { … }
void ThrottlingURLLoader::FollowRedirect(
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const net::HttpRequestHeaders& modified_cors_exempt_headers) { … }
void ThrottlingURLLoader::SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) { … }
network::mojom::URLLoaderClientEndpointsPtr ThrottlingURLLoader::Unbind() { … }
ThrottlingURLLoader::ThrottlingURLLoader(
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
network::mojom::URLLoaderClient* client,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
ClientReceiverDelegate* client_receiver_delegate)
: … { … }
void ThrottlingURLLoader::Start(
scoped_refptr<network::SharedURLLoaderFactory> factory,
int32_t request_id,
uint32_t options,
network::ResourceRequest* url_request,
scoped_refptr<base::SequencedTaskRunner> task_runner,
std::optional<std::vector<std::string>> cors_exempt_header_list) { … }
void ThrottlingURLLoader::StartNow() { … }
void ThrottlingURLLoader::RestartWithURLResetNow() { … }
bool ThrottlingURLLoader::HandleThrottleResult(URLLoaderThrottle* throttle,
bool throttle_deferred,
bool* should_defer) { … }
void ThrottlingURLLoader::StopDeferringForThrottle(
URLLoaderThrottle* throttle) { … }
void ThrottlingURLLoader::OnReceiveEarlyHints(
network::mojom::EarlyHintsPtr early_hints) { … }
void ThrottlingURLLoader::OnReceiveResponse(
network::mojom::URLResponseHeadPtr response_head,
mojo::ScopedDataPipeConsumerHandle body,
std::optional<mojo_base::BigBuffer> cached_metadata) { … }
void ThrottlingURLLoader::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
network::mojom::URLResponseHeadPtr response_head) { … }
void ThrottlingURLLoader::OnUploadProgress(
int64_t current_position,
int64_t total_size,
OnUploadProgressCallback ack_callback) { … }
void ThrottlingURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) { … }
void ThrottlingURLLoader::OnComplete(
const network::URLLoaderCompletionStatus& status) { … }
void ThrottlingURLLoader::OnClientConnectionError() { … }
void ThrottlingURLLoader::CancelWithError(int error_code,
std::string_view custom_reason) { … }
void ThrottlingURLLoader::CancelWithExtendedError(
int error_code,
int extended_reason_code,
std::string_view custom_reason) { … }
void ThrottlingURLLoader::Resume() { … }
void ThrottlingURLLoader::SetPriority(net::RequestPriority priority) { … }
void ThrottlingURLLoader::UpdateRequestHeaders(
network::ResourceRequest& resource_request) { … }
void ThrottlingURLLoader::UpdateDeferredResponseHead(
network::mojom::URLResponseHeadPtr new_response_head,
mojo::ScopedDataPipeConsumerHandle body) { … }
void ThrottlingURLLoader::PauseReadingBodyFromNet() { … }
void ThrottlingURLLoader::ResumeReadingBodyFromNet() { … }
void ThrottlingURLLoader::InterceptResponse(
mojo::PendingRemote<network::mojom::URLLoader> new_loader,
mojo::PendingReceiver<network::mojom::URLLoaderClient> new_client_receiver,
mojo::PendingRemote<network::mojom::URLLoader>* original_loader,
mojo::PendingReceiver<network::mojom::URLLoaderClient>*
original_client_receiver,
mojo::ScopedDataPipeConsumerHandle* body) { … }
void ThrottlingURLLoader::DisconnectClient(std::string_view custom_reason) { … }
const char* ThrottlingURLLoader::GetStageNameForHistogram(DeferredStage stage) { … }
ThrottlingURLLoader::ThrottleEntry::ThrottleEntry(
ThrottlingURLLoader* loader,
std::unique_ptr<URLLoaderThrottle> the_throttle)
: … { … }
ThrottlingURLLoader::ThrottleEntry::ThrottleEntry(ThrottleEntry&& other) =
default;
ThrottlingURLLoader::ThrottleEntry::~ThrottleEntry() { … }
ThrottlingURLLoader::ThrottleEntry& ThrottlingURLLoader::ThrottleEntry::
operator=(ThrottleEntry&& other) = default;
}