1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_
#define NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "net/base/auth.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
#include "net/base/privacy_mode.h"
#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_util.h"
#include "net/first_party_sets/first_party_set_metadata.h"
#include "net/first_party_sets/first_party_sets_cache_filter.h"
#include "net/http/http_request_info.h"
#include "net/socket/connection_attempts.h"
#include "net/url_request/url_request_job.h"
#if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
#include "net/device_bound_sessions/session_service.h"
#endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
namespace net {
class HttpRequestHeaders;
class HttpResponseHeaders;
class HttpResponseInfo;
class HttpTransaction;
class HttpUserAgentSettings;
class SSLPrivateKey;
struct TransportInfo;
struct LoadTimingInternalInfo;
class UploadDataStream;
// A URLRequestJob subclass that is built on top of HttpTransaction. It
// provides an implementation for both HTTP and HTTPS.
class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob {
public:
// Creates URLRequestJob for the specified HTTP, HTTPS, WS, or WSS URL.
// Returns a job that returns a redirect in the case of HSTS, and returns a
// job that fails for unencrypted requests if current settings dont allow
// them. Never returns nullptr.
static std::unique_ptr<URLRequestJob> Create(URLRequest* request);
URLRequestHttpJob(const URLRequestHttpJob&) = delete;
URLRequestHttpJob& operator=(const URLRequestHttpJob&) = delete;
void SetRequestHeadersCallback(RequestHeadersCallback callback) override;
void SetEarlyResponseHeadersCallback(
ResponseHeadersCallback callback) override;
void SetResponseHeadersCallback(ResponseHeadersCallback callback) override;
void SetIsSharedDictionaryReadAllowedCallback(
base::RepeatingCallback<bool()> callback) override;
// An enumeration of the results of a request with respect to IP Protection.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class IpProtectionJobResult {
// Request was not IP Protected.
kProtectionNotAttempted = 0,
// Request was IP Protected and carried via IP Protection proxies or, if
// the direct-only parameter is true, made directly.
kProtectionSuccess = 1,
// Request was IP Protected, but fell back to direct.
kDirectFallback = 2,
kMaxValue = kDirectFallback,
};
protected:
URLRequestHttpJob(URLRequest* request,
const HttpUserAgentSettings* http_user_agent_settings);
~URLRequestHttpJob() override;
// Overridden from URLRequestJob:
void SetPriority(RequestPriority priority) override;
void Start() override;
void Kill() override;
ConnectionAttempts GetConnectionAttempts() const override;
void CloseConnectionOnDestruction() override;
std::unique_ptr<SourceStream> SetUpSourceStream() override;
RequestPriority priority() const {
return priority_;
}
private:
// For CookieRequestScheme histogram enum.
FRIEND_TEST_ALL_PREFIXES(URLRequestHttpJobTest,
CookieSchemeRequestSchemeHistogram);
enum CompletionCause {
ABORTED,
FINISHED
};
// Used to indicate which kind of cookies are sent on which kind of requests,
// for use in histograms. A (non)secure set cookie means that the cookie was
// originally set by a (non)secure url. A (non)secure request means that the
// request url is (non)secure. An unset cookie scheme means that the cookie's
// source scheme was marked as "Unset" and thus cannot be compared with the
// request.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class CookieRequestScheme {
kUnsetCookieScheme = 0,
kNonsecureSetNonsecureRequest,
kSecureSetSecureRequest,
kNonsecureSetSecureRequest,
kSecureSetNonsecureRequest,
kMaxValue = kSecureSetNonsecureRequest // Keep as the last value.
};
typedef base::RefCountedData<bool> SharedBoolean;
// Shadows URLRequestJob's version of this method so we can grab cookies.
void NotifyHeadersComplete();
void DestroyTransaction();
// Computes the PrivacyMode that should be associated with this leg of the
// request. Must be recomputed on redirects.
PrivacyMode DeterminePrivacyMode() const;
void AddExtraHeaders();
void AddCookieHeaderAndStart();
void AnnotateAndMoveUserBlockedCookies(
CookieAccessResultList& maybe_included_cookies,
CookieAccessResultList& excluded_cookies) const;
void SaveCookiesAndNotifyHeadersComplete(int result);
#if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
// Process the DBSC header, if one exists.
void ProcessDeviceBoundSessionsHeader();
#endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
// Processes the Strict-Transport-Security header, if one exists.
void ProcessStrictTransportSecurityHeader();
// |result| should be OK, or the request is canceled.
void OnHeadersReceivedCallback(int result);
void OnStartCompleted(int result);
void OnReadCompleted(int result);
void NotifyBeforeStartTransactionCallback(
int result,
const std::optional<HttpRequestHeaders>& headers);
// This just forwards the call to URLRequestJob::NotifyConnected().
// We need it because that method is protected and cannot be bound in a
// callback in this class.
int NotifyConnectedCallback(const TransportInfo& info,
CompletionOnceCallback callback);
void RestartTransaction();
#if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
void RestartTransactionForRefresh(
const device_bound_sessions::SessionService::DeferralParams&
deferral_params,
device_bound_sessions::SessionService::RefreshResult result);
#endif
void RestartTransactionWithAuth(const AuthCredentials& credentials);
// Overridden from URLRequestJob:
void SetUpload(UploadDataStream* upload) override;
void SetExtraRequestHeaders(const HttpRequestHeaders& headers) override;
LoadState GetLoadState() const override;
bool GetMimeType(std::string* mime_type) const override;
bool GetCharset(std::string* charset) override;
void GetClientSideContentDecodingTypes(
std::vector<net::SourceStreamType>* types) const override;
void GetResponseInfo(HttpResponseInfo* info) override;
void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
void PopulateLoadTimingInternalInfo(
LoadTimingInternalInfo* load_timing_internal_info) const override;
bool GetTransactionRemoteEndpoint(IPEndPoint* endpoint) const override;
int GetResponseCode() const override;
void PopulateNetErrorDetails(NetErrorDetails* details) const override;
bool CopyFragmentOnRedirect(const GURL& location) const override;
bool IsSafeRedirect(const GURL& location) override;
bool NeedsAuth() override;
std::unique_ptr<AuthChallengeInfo> GetAuthChallengeInfo() override;
void SetAuth(const AuthCredentials& credentials) override;
void CancelAuth() override;
void ContinueWithCertificate(
scoped_refptr<X509Certificate> client_cert,
scoped_refptr<SSLPrivateKey> client_private_key) override;
void ContinueDespiteLastError() override;
int ReadRawData(IOBuffer* buf, int buf_size) override;
int64_t GetTotalReceivedBytes() const override;
int64_t GetTotalSentBytes() const override;
int64_t GetReceivedBodyBytes() const override;
void DoneReading() override;
void DoneReadingRedirectResponse() override;
void DoneReadingRetryResponse() override;
bool NeedsRetryWithStorageAccess() override;
void SetSharedDictionaryGetter(
SharedDictionaryGetter shared_dictionary_getter) override;
IPEndPoint GetResponseRemoteEndpoint() const override;
void NotifyURLRequestDestroyed() override;
void RecordTimer();
void ResetTimer();
// Starts the transaction if extensions using the webrequest API do not
// object.
void StartTransaction();
// If |result| is OK, calls StartTransactionInternal. Otherwise notifies
// cancellation.
void MaybeStartTransactionInternal(int result);
void StartTransactionInternal();
void RecordCompletionHistograms(CompletionCause reason);
void DoneWithRequest(CompletionCause reason);
// Callback functions for Cookie Monster
void SetCookieHeaderAndStart(const CookieOptions& options,
const CookieAccessResultList& cookie_list,
const CookieAccessResultList& excluded_list);
// Another Cookie Monster callback
void OnSetCookieResult(const CookieOptions& options,
std::optional<CanonicalCookie> cookie,
std::string cookie_string,
CookieAccessResult access_result);
int num_cookie_lines_left_ = 0;
CookieAndLineAccessResultList set_cookie_access_result_list_;
// Some servers send the body compressed, but specify the content length as
// the uncompressed size. If this is the case, we return true in order
// to request to work around this non-adherence to the HTTP standard.
// |rv| is the standard return value of a read function indicating the number
// of bytes read or, if negative, an error code.
bool ShouldFixMismatchedContentLength(int rv) const;
// Returns the effective response headers, considering that they may be
// overridden by `override_response_headers_` or
// `override_response_info_::headers`.
HttpResponseHeaders* GetResponseHeaders() const;
// Called after getting the FirstPartySetMetadata during Start for this job.
void OnGotFirstPartySetMetadata(
FirstPartySetMetadata first_party_set_metadata,
FirstPartySetsCacheFilter::MatchInfo match_info);
// Returns true iff this request leg should include the Cookie header. Note
// that cookies may still be eventually blocked by the CookieAccessDelegate
// even if this method returns true.
bool ShouldAddCookieHeader() const;
// Returns true if we should log how many partitioned cookies are included
// in a request.
bool ShouldRecordPartitionedCookieUsage() const;
RequestPriority priority_ = DEFAULT_PRIORITY;
HttpRequestInfo request_info_;
// Used for any logic, e.g. DNS-based scheme upgrade, that needs to synthesize
// response info to override the real response info. Transaction should be
// cleared before setting.
std::unique_ptr<HttpResponseInfo> override_response_info_;
// Auth states for proxy and origin server.
AuthState proxy_auth_state_ = AUTH_STATE_DONT_NEED_AUTH;
AuthState server_auth_state_ = AUTH_STATE_DONT_NEED_AUTH;
AuthCredentials auth_credentials_;
bool read_in_progress_ = false;
std::unique_ptr<HttpTransaction> transaction_;
// This needs to be declared after `transaction_` and
// `override_response_info_` because `response_info_` holds a pointer that's
// itself owned by one of those, so `response_info_` needs to be destroyed
// first.
raw_ptr<const HttpResponseInfo> response_info_ = nullptr;
base::Time request_creation_time_;
// True when we are done doing work.
bool done_ = false;
// The start time for the job, ignoring re-starts.
base::TimeTicks start_time_;
// When the transaction finished reading the request headers.
base::TimeTicks receive_headers_end_;
// We allow the network delegate to modify a copy of the response headers.
// This prevents modifications of headers that are shared with the underlying
// layers of the network stack.
scoped_refptr<HttpResponseHeaders> override_response_headers_;
// Ordinarily the original URL's fragment is copied during redirects, unless
// the destination URL already has one. However, the NetworkDelegate can
// override this behavior by setting |preserve_fragment_on_redirect_url_|:
// * If set to std::nullopt, the default behavior is used.
// * If the final URL in the redirect chain matches
// |preserve_fragment_on_redirect_url_|, its fragment unchanged. So this
// is basically a way for the embedder to force a redirect not to copy the
// original URL's fragment when the original URL had one.
std::optional<GURL> preserve_fragment_on_redirect_url_;
// Flag used to verify that |this| is not deleted while we are awaiting
// a callback from the NetworkDelegate. Used as a fail-fast mechanism.
// True if we are waiting a callback and
// NetworkDelegate::NotifyURLRequestDestroyed has not been called, yet,
// to inform the NetworkDelegate that it may not call back.
bool awaiting_callback_ = false;
raw_ptr<const HttpUserAgentSettings> http_user_agent_settings_;
// Keeps track of total received bytes over the network from transactions used
// by this job that have already been destroyed.
int64_t total_received_bytes_from_previous_transactions_ = 0;
// Keeps track of total sent bytes over the network from transactions used by
// this job that have already been destroyed.
int64_t total_sent_bytes_from_previous_transactions_ = 0;
RequestHeadersCallback request_headers_callback_;
ResponseHeadersCallback early_response_headers_callback_;
ResponseHeadersCallback response_headers_callback_;
base::RepeatingCallback<bool()> is_shared_dictionary_read_allowed_callback_;
// The First-Party Set metadata associated with this job. Set when the job is
// started.
FirstPartySetMetadata first_party_set_metadata_;
// The number of times this request was deferred due to a Device Bound
// Session.
size_t device_bound_session_deferral_count_ = 0;
// The time of the first deferral due to Device Bound Sessions. This
// is used to measure the total delay of Device Bound Session
// Deferral.
base::TimeTicks device_bound_session_first_deferral_;
// The content encoding types that need to be handled in the client side.
std::vector<net::SourceStreamType> client_side_content_decoding_types_;
base::WeakPtrFactory<URLRequestHttpJob> weak_factory_{this};
};
} // namespace net
#endif // NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_
|