chromium/services/network/websocket.cc

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/network/websocket.h"

#include <inttypes.h>
#include <string.h>

#include <memory>
#include <tuple>
#include <utility>

#include "base/check.h"
#include "base/check_op.h"
#include "base/containers/span.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "build/build_config.h"
#include "net/base/auth.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/cookies/static_cookie_policy.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/ssl/ssl_info.h"
#include "net/storage_access_api/status.h"
#include "net/url_request/url_request_context.h"
#include "net/websockets/websocket_basic_stream.h"
#include "net/websockets/websocket_channel.h"
#include "net/websockets/websocket_errors.h"
#include "net/websockets/websocket_frame.h"  // for WebSocketFrameHeader::OpCode
#include "net/websockets/websocket_handshake_request_info.h"
#include "net/websockets/websocket_handshake_response_info.h"
#include "services/network/public/cpp/ip_address_space_util.h"
#include "services/network/throttling/throttling_controller.h"
#include "services/network/throttling/throttling_network_interceptor.h"
#include "services/network/websocket_factory.h"
#include "services/network/websocket_interceptor.h"

namespace network {
namespace {

// What is considered a "small message" for the purposes of small message
// reassembly.
constexpr uint64_t kSmallMessageThreshhold =;

// The capacity of the data pipe to use for received messages, in bytes. Optimal
// value depends on the platform. |2^n - delta| is better than 2^n on Linux. See
// crrev.com/c/1792208.
constexpr uint32_t kReceiveDataPipeCapacity =;

// Convert a mojom::WebSocketMessageType to a
// net::WebSocketFrameHeader::OpCode
net::WebSocketFrameHeader::OpCode MessageTypeToOpCode(
    mojom::WebSocketMessageType type) {}

mojom::WebSocketMessageType OpCodeToMessageType(
    net::WebSocketFrameHeader::OpCode opCode) {}

mojom::WebSocketHandshakeResponsePtr ToMojo(
    std::unique_ptr<net::WebSocketHandshakeResponseInfo> response,
    bool has_raw_headers_access) {}

}  // namespace

// Implementation of net::WebSocketEventInterface. Receives events from our
// WebSocketChannel object.
class WebSocket::WebSocketEventHandler final
    : public net::WebSocketEventInterface {};

WebSocket::WebSocketEventHandler::WebSocketEventHandler(WebSocket* impl)
    :{}

WebSocket::WebSocketEventHandler::~WebSocketEventHandler() {}

void WebSocket::WebSocketEventHandler::OnCreateURLRequest(
    net::URLRequest* url_request) {}

void WebSocket::WebSocketEventHandler::OnURLRequestConnected(
    net::URLRequest* request,
    const net::TransportInfo& info) {}

void WebSocket::WebSocketEventHandler::OnAddChannelResponse(
    std::unique_ptr<net::WebSocketHandshakeResponseInfo> response,
    const std::string& selected_protocol,
    const std::string& extensions) {}

void WebSocket::WebSocketEventHandler::OnDataFrame(
    bool fin,
    net::WebSocketFrameHeader::OpCode type,
    base::span<const char> payload) {}

void WebSocket::WebSocketEventHandler::OnSendDataFrameDone() {}

bool WebSocket::WebSocketEventHandler::HasPendingDataFrames() {}

void WebSocket::WebSocketEventHandler::OnClosingHandshake() {}

void WebSocket::WebSocketEventHandler::OnDropChannel(
    bool was_clean,
    uint16_t code,
    const std::string& reason) {}

void WebSocket::WebSocketEventHandler::OnFailChannel(
    const std::string& message,
    int net_error,
    std::optional<int> response_code) {}

void WebSocket::WebSocketEventHandler::OnStartOpeningHandshake(
    std::unique_ptr<net::WebSocketHandshakeRequestInfo> request) {}

void WebSocket::WebSocketEventHandler::OnSSLCertificateError(
    std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
    const GURL& url,
    int net_error,
    const net::SSLInfo& ssl_info,
    bool fatal) {}

int WebSocket::WebSocketEventHandler::OnAuthRequired(
    const net::AuthChallengeInfo& auth_info,
    scoped_refptr<net::HttpResponseHeaders> response_headers,
    const net::IPEndPoint& remote_endpoint,
    base::OnceCallback<void(const net::AuthCredentials*)> callback,
    std::optional<net::AuthCredentials>* credentials) {}

struct WebSocket::CloseInfo {};

WebSocket::WebSocket(
    WebSocketFactory* factory,
    const GURL& url,
    const std::vector<std::string>& requested_protocols,
    const net::SiteForCookies& site_for_cookies,
    net::StorageAccessApiStatus storage_access_api_status,
    const net::IsolationInfo& isolation_info,
    std::vector<mojom::HttpHeaderPtr> additional_headers,
    const url::Origin& origin,
    uint32_t options,
    net::NetworkTrafficAnnotationTag traffic_annotation,
    HasRawHeadersAccess has_raw_headers_access,
    mojo::PendingRemote<mojom::WebSocketHandshakeClient> handshake_client,
    mojo::PendingRemote<mojom::URLLoaderNetworkServiceObserver>
        url_loader_network_observer,
    mojo::PendingRemote<mojom::WebSocketAuthenticationHandler> auth_handler,
    mojo::PendingRemote<mojom::TrustedHeaderClient> header_client,
    std::optional<WebSocketThrottler::PendingConnection>
        pending_connection_tracker,
    base::TimeDelta delay,
    const std::optional<base::UnguessableToken>& throttling_profile_id)
    :{}

WebSocket::~WebSocket() {}

// static
const void* const WebSocket::kUserDataKey =;

void WebSocket::SendMessage(mojom::WebSocketMessageType type,
                            uint64_t data_length) {}

void WebSocket::StartReceiving() {}

void WebSocket::StartClosingHandshake(uint16_t code,
                                      const std::string& reason) {}

bool WebSocket::AllowCookies(const GURL& url) const {}

bool WebSocket::RevokeIfNonceMatches(const base::UnguessableToken& nonce) {}

int WebSocket::OnBeforeStartTransaction(
    const net::HttpRequestHeaders& headers,
    net::NetworkDelegate::OnBeforeStartTransactionCallback callback) {}

int WebSocket::OnHeadersReceived(
    net::CompletionOnceCallback callback,
    const net::HttpResponseHeaders* original_response_headers,
    scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
    std::optional<GURL>* preserve_fragment_on_redirect_url) {}

// static
WebSocket* WebSocket::ForRequest(const net::URLRequest& request) {}

void WebSocket::OnConnectionError(const base::Location& set_from) {}

void WebSocket::AddChannel(
    const GURL& socket_url,
    const std::vector<std::string>& requested_protocols,
    const net::SiteForCookies& site_for_cookies,
    net::StorageAccessApiStatus storage_access_api_status,
    const net::IsolationInfo& isolation_info,
    std::vector<mojom::HttpHeaderPtr> additional_headers) {}

void WebSocket::OnWritable(MojoResult result,
                           const mojo::HandleSignalsState& state) {}

void WebSocket::SendPendingDataFrames(InterruptionReason resume_reason) {}

void WebSocket::SendDataFrame(base::span<const char>* payload) {}

void WebSocket::OnReadable(MojoResult result,
                           const mojo::HandleSignalsState& state) {}

void WebSocket::ReadAndSendFromDataPipe(InterruptionReason resume_reason) {}

bool WebSocket::ReadAndSendFrameFromDataPipe(DataFrame* data_frame) {}

void WebSocket::ResumeDataPipeReading() {}

void WebSocket::OnSSLCertificateErrorResponse(
    std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
    const net::SSLInfo& ssl_info,
    int net_error) {}

void WebSocket::OnAuthRequiredComplete(
    base::OnceCallback<void(const net::AuthCredentials*)> callback,
    const std::optional<net::AuthCredentials>& credentials) {}

void WebSocket::OnBeforeSendHeadersComplete(
    net::NetworkDelegate::OnBeforeStartTransactionCallback callback,
    int result,
    const std::optional<net::HttpRequestHeaders>& headers) {}

void WebSocket::OnHeadersReceivedComplete(
    net::CompletionOnceCallback callback,
    scoped_refptr<net::HttpResponseHeaders>* out_headers,
    std::optional<GURL>* out_preserve_fragment_on_redirect_url,
    int result,
    const std::optional<std::string>& headers,
    const std::optional<GURL>& preserve_fragment_on_redirect_url) {}

void WebSocket::Reset() {}

}  // namespace network