#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/modules/websockets/websocket_channel_impl.h"
#include <string.h>
#include <algorithm>
#include <atomic>
#include <limits>
#include <memory>
#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/types/strong_alias.h"
#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink.h"
#include "third_party/blink/public/platform/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/websocket_handshake_throttle.h"
#include "third_party/blink/renderer/bindings/core/v8/capture_source_location.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_client.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/base_fetch_context.h"
#include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
#include "third_party/blink/renderer/core/loader/subresource_filter.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/websockets/inspector_websocket_events.h"
#include "third_party/blink/renderer/modules/websockets/websocket_channel_client.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/unique_identifier.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
#include "v8/include/v8.h"
namespace blink {
namespace {
std::atomic_size_t g_connection_count;
enum WebSocketOpCode { … };
}
void WebSocketChannelImpl::MessageDataDeleter::operator()(char* p) const { … }
WebSocketChannelImpl::MessageData WebSocketChannelImpl::CreateMessageData(
v8::Isolate* isolate,
size_t message_size) { … }
class WebSocketChannelImpl::BlobLoader final
: public GarbageCollected<WebSocketChannelImpl::BlobLoader>,
public FileReaderClient { … };
WebSocketChannelImpl::BlobLoader::BlobLoader(
scoped_refptr<BlobDataHandle> blob_data_handle,
WebSocketChannelImpl* channel,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: … { … }
void WebSocketChannelImpl::BlobLoader::Cancel() { … }
FileErrorCode WebSocketChannelImpl::BlobLoader::DidStartLoading(uint64_t) { … }
FileErrorCode WebSocketChannelImpl::BlobLoader::DidReceiveData(
base::span<const uint8_t> data) { … }
void WebSocketChannelImpl::BlobLoader::DidFinishLoading() { … }
void WebSocketChannelImpl::BlobLoader::DidFail(FileErrorCode error_code) { … }
struct WebSocketChannelImpl::ConnectInfo { … };
WebSocketChannelImpl* WebSocketChannelImpl::CreateForTesting(
ExecutionContext* execution_context,
WebSocketChannelClient* client,
std::unique_ptr<SourceLocation> location,
std::unique_ptr<WebSocketHandshakeThrottle> handshake_throttle) { … }
WebSocketChannelImpl* WebSocketChannelImpl::Create(
ExecutionContext* execution_context,
WebSocketChannelClient* client,
std::unique_ptr<SourceLocation> location) { … }
WebSocketChannelImpl::WebSocketChannelImpl(
ExecutionContext* execution_context,
WebSocketChannelClient* client,
std::unique_ptr<SourceLocation> location)
: … { … }
WebSocketChannelImpl::~WebSocketChannelImpl() = default;
bool WebSocketChannelImpl::Connect(const KURL& url, const String& protocol) { … }
WebSocketChannel::SendResult WebSocketChannelImpl::Send(
const std::string& message,
base::OnceClosure completion_callback) { … }
void WebSocketChannelImpl::Send(
scoped_refptr<BlobDataHandle> blob_data_handle) { … }
WebSocketChannel::SendResult WebSocketChannelImpl::Send(
const DOMArrayBuffer& buffer,
size_t byte_offset,
size_t byte_length,
base::OnceClosure completion_callback) { … }
void WebSocketChannelImpl::Close(int code, const String& reason) { … }
void WebSocketChannelImpl::Fail(const String& reason,
mojom::ConsoleMessageLevel level,
std::unique_ptr<SourceLocation> location) { … }
void WebSocketChannelImpl::Disconnect() { … }
void WebSocketChannelImpl::CancelHandshake() { … }
void WebSocketChannelImpl::ApplyBackpressure() { … }
void WebSocketChannelImpl::RemoveBackpressure() { … }
void WebSocketChannelImpl::OnOpeningHandshakeStarted(
network::mojom::blink::WebSocketHandshakeRequestPtr request) { … }
void WebSocketChannelImpl::OnFailure(const WTF::String& message,
int net_error,
int response_code) { … }
void WebSocketChannelImpl::OnConnectionEstablished(
mojo::PendingRemote<network::mojom::blink::WebSocket> websocket,
mojo::PendingReceiver<network::mojom::blink::WebSocketClient>
client_receiver,
network::mojom::blink::WebSocketHandshakeResponsePtr response,
mojo::ScopedDataPipeConsumerHandle readable,
mojo::ScopedDataPipeProducerHandle writable) { … }
void WebSocketChannelImpl::OnDataFrame(
bool fin,
network::mojom::blink::WebSocketMessageType type,
uint64_t data_length) { … }
void WebSocketChannelImpl::OnDropChannel(bool was_clean,
uint16_t code,
const String& reason) { … }
void WebSocketChannelImpl::OnClosingHandshake() { … }
void WebSocketChannelImpl::Trace(Visitor* visitor) const { … }
WebSocketChannelImpl::Message::Message(v8::Isolate* isolate,
const std::string& text,
base::OnceClosure completion_callback,
DidCallSendMessage did_call_send_message)
: … { … }
WebSocketChannelImpl::Message::Message(
scoped_refptr<BlobDataHandle> blob_data_handle)
: … { … }
WebSocketChannelImpl::Message::Message(MessageData data, size_t size)
: … { … }
WebSocketChannelImpl::Message::Message(v8::Isolate* isolate,
base::span<const char> message,
base::OnceClosure completion_callback,
DidCallSendMessage did_call_send_message)
: … { … }
WebSocketChannelImpl::Message::Message(uint16_t code, const String& reason)
: … { … }
WebSocketChannelImpl::Message::Message(MessageType type,
base::span<const char> pending_payload,
base::OnceClosure completion_callback)
: … { … }
WebSocketChannelImpl::Message::Message(Message&&) = default;
WebSocketChannelImpl::Message& WebSocketChannelImpl::Message::operator=(
Message&&) = default;
WebSocketChannelImpl::State WebSocketChannelImpl::GetState() const { … }
WebSocketChannelImpl::MessageType WebSocketChannelImpl::Message::Type() const { … }
scoped_refptr<BlobDataHandle>
WebSocketChannelImpl::Message::GetBlobDataHandle() { … }
base::span<const char>& WebSocketChannelImpl::Message::MutablePendingPayload() { … }
WebSocketChannelImpl::Message::DidCallSendMessage
WebSocketChannelImpl::Message::GetDidCallSendMessage() const { … }
void WebSocketChannelImpl::Message::SetDidCallSendMessage(
WebSocketChannelImpl::Message::DidCallSendMessage did_call_send_message) { … }
uint16_t WebSocketChannelImpl::Message::Code() const { … }
String WebSocketChannelImpl::Message::Reason() const { … }
base::OnceClosure WebSocketChannelImpl::Message::CompletionCallback() { … }
WebSocketChannelImpl::ConnectionCountTrackerHandle::CountStatus
WebSocketChannelImpl::ConnectionCountTrackerHandle::IncrementAndCheckStatus() { … }
void WebSocketChannelImpl::ConnectionCountTrackerHandle::Decrement() { … }
bool WebSocketChannelImpl::MaybeSendSynchronously(
network::mojom::blink::WebSocketMessageType frame_type,
base::span<const char>* data) { … }
void WebSocketChannelImpl::ProcessSendQueue() { … }
bool WebSocketChannelImpl::SendMessageData(base::span<const char>* data) { … }
void WebSocketChannelImpl::AbortAsyncOperations() { … }
void WebSocketChannelImpl::HandleDidClose(bool was_clean,
uint16_t code,
const String& reason) { … }
void WebSocketChannelImpl::OnCompletion(
const std::optional<WebString>& console_message) { … }
void WebSocketChannelImpl::DidFinishLoadingBlob(MessageData data, size_t size) { … }
void WebSocketChannelImpl::BlobTooLarge() { … }
void WebSocketChannelImpl::DidFailLoadingBlob(FileErrorCode error_code) { … }
void WebSocketChannelImpl::TearDownFailedConnection() { … }
bool WebSocketChannelImpl::ShouldDisallowConnection(const KURL& url) { … }
BaseFetchContext* WebSocketChannelImpl::GetBaseFetchContext() const { … }
void WebSocketChannelImpl::OnReadable(MojoResult result,
const mojo::HandleSignalsState& state) { … }
void WebSocketChannelImpl::ConsumePendingDataFrames() { … }
void WebSocketChannelImpl::ConsumeDataFrame(
bool fin,
network::mojom::blink::WebSocketMessageType type,
const char* data,
size_t size) { … }
void WebSocketChannelImpl::OnWritable(MojoResult result,
const mojo::HandleSignalsState& state) { … }
MojoResult WebSocketChannelImpl::ProduceData(
base::span<const char>* data,
uint64_t* consumed_buffered_amount) { … }
String WebSocketChannelImpl::GetTextMessage(
const Vector<base::span<const char>>& chunks,
wtf_size_t size) { … }
void WebSocketChannelImpl::OnConnectionError(const base::Location& set_from,
uint32_t custom_reason,
const std::string& description) { … }
void WebSocketChannelImpl::Dispose() { … }
std::ostream& operator<<(std::ostream& ostream,
const WebSocketChannelImpl* channel) { … }
}