blob: 6d15fdd4b208fddeed197ad17c7e694dff33ab8a [file]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_WEBID_NETWORK_REQUEST_MANAGER_H_
#define CONTENT_BROWSER_WEBID_NETWORK_REQUEST_MANAGER_H_
#include <optional>
#include <string>
#include "base/functional/callback.h"
#include "content/common/content_export.h"
#include "content/public/browser/frame_tree_node_id.h"
#include "content/public/browser/weak_document_ptr.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"
namespace base {
class DictValue;
}
namespace content::webid {
enum class ParseStatus {
kSuccess,
kHttpNotFoundError,
kNoResponseError,
kInvalidResponseError,
// ParseStatus::kEmptyListError only applies to well known and account list
// responses. It is used to classify a successful response where the list in
// the response is empty.
kEmptyListError,
kInvalidContentTypeError,
kBlockedByConnectionAllowlist,
};
struct FetchStatus {
ParseStatus parse_status;
int response_code;
bool cors_error = false;
// Whether this fetch was fulfilled by the accounts pushed to the browser.
// Only set to true for accounts fetches in the FedCM API where lightweight
// FedCM is enabled.
bool from_accounts_push = false;
};
GURL ExtractEndpoint(const GURL& provider,
const base::DictValue& response,
const char* key);
CONTENT_EXPORT std::optional<GURL> ComputeWellKnownUrl(const GURL& provider,
const std::string& path);
// Computes the "web-identity.well-known" subdomain well-known URL for
// `provider`, e.g. https://web-identity.well-known.<eTLD+1><path>. Returns
// std::nullopt if `provider` has no eTLD+1 (e.g. an IP literal) or for
// localhost.
CONTENT_EXPORT std::optional<GURL> ComputeWebIdentitySubdomainWellKnownUrl(
const GURL& provider,
const std::string& path);
// Base class containing some methods for creating fetches in webid APIs.
class CONTENT_EXPORT NetworkRequestManager {
public:
using DownloadCallback =
base::OnceCallback<void(std::optional<std::string> response_body,
int response_code,
const std::string& mime_type,
bool cors_error)>;
using ParseJsonCallback =
base::OnceCallback<void(FetchStatus, std::optional<base::DictValue>)>;
NetworkRequestManager(
const url::Origin& relying_party_origin,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
network::mojom::ClientSecurityStatePtr client_security_state,
network::mojom::RequestDestination destination,
FrameTreeNodeId frame_tree_node_id,
WeakDocumentPtr initiator_document);
virtual ~NetworkRequestManager();
NetworkRequestManager(const NetworkRequestManager&) = delete;
NetworkRequestManager& operator=(const NetworkRequestManager&) = delete;
enum class CredentialedResourceRequestType {
kNoOrigin,
kOriginWithoutCORS,
kOriginWithCORS
};
protected:
virtual net::NetworkTrafficAnnotationTag CreateTrafficAnnotation() = 0;
// Starts download request using `url_loader`. Calls `parse_json_callback`
// when the download result has been parsed.
void DownloadJsonAndParse(
std::unique_ptr<network::ResourceRequest> resource_request,
std::optional<std::string> post_data,
ParseJsonCallback parse_json_callback,
bool allow_http_error_results = false,
const std::string& content_type = "application/x-www-form-urlencoded");
// Starts download result using `url_loader`. Calls `download_callback` when
// the download completes.
void DownloadUrl(
std::unique_ptr<network::ResourceRequest> resource_request,
std::optional<std::string> post_data,
DownloadCallback download_callback,
size_t max_download_size,
bool allow_http_error_results = false,
const std::string& content_type = "application/x-www-form-urlencoded");
// Called when download initiated by DownloadUrl() completes.
void OnDownloadedUrl(std::unique_ptr<network::SimpleURLLoader> url_loader,
DownloadCallback callback,
std::optional<std::string> response_body);
// Called when the download request is going to be blocked.
void OnRequestBlocked(DownloadCallback callback, int response_code);
std::unique_ptr<network::ResourceRequest> CreateUncredentialedResourceRequest(
const GURL& target_url,
bool send_origin,
bool follow_redirects = false) const;
std::unique_ptr<network::ResourceRequest> CreateCredentialedResourceRequest(
const GURL& target_url,
CredentialedResourceRequestType type) const;
url::Origin relying_party_origin_;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
network::mojom::ClientSecurityStatePtr client_security_state_;
const network::mojom::RequestDestination destination_;
const FrameTreeNodeId frame_tree_node_id_;
const WeakDocumentPtr initiator_document_;
private:
// Maps each SimpleURLLoader instance to a unique, unguessable token
// (request_id) used for tracking and associating network requests
// with DevTools instrumentation.
base::flat_map<network::SimpleURLLoader*, base::UnguessableToken>
urlloader_devtools_request_id_map_;
base::WeakPtrFactory<NetworkRequestManager> weak_ptr_factory_{this};
};
} // namespace content::webid
#endif // CONTENT_BROWSER_WEBID_NETWORK_REQUEST_MANAGER_H_