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
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WEBSOCKET_STREAM_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WEBSOCKET_STREAM_H_
#include <stdint.h>
#include <optional>
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"
#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/websockets/websocket_channel_client.h"
#include "third_party/blink/renderer/modules/websockets/websocket_common.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "v8/include/v8.h"
namespace blink {
class ExceptionState;
class ExecutionContext;
class ScriptState;
class ScriptValue;
class WebSocketChannel;
class WebSocketCloseInfo;
class WebSocketOpenInfo;
class WebSocketStreamOptions;
// Implements of JavaScript-exposed WebSocketStream API. See design doc at
// https://docs.google.com/document/d/1XuxEshh5VYBYm1qRVKordTamCOsR-uGQBCYFcHXP4L0/edit
class MODULES_EXPORT WebSocketStream final
: public ScriptWrappable,
public ActiveScriptWrappable<WebSocketStream>,
public ExecutionContextLifecycleObserver,
public WebSocketChannelClient {
DEFINE_WRAPPERTYPEINFO();
public:
// IDL constructors
static WebSocketStream* Create(ScriptState*,
const String& url,
WebSocketStreamOptions*,
ExceptionState&);
static WebSocketStream* CreateForTesting(ScriptState*,
const String& url,
WebSocketStreamOptions*,
WebSocketChannel*,
ExceptionState&);
// The constructor only creates the object. It cannot fail. The private
// Connect() method is used by Create() to start connecting.
WebSocketStream(ExecutionContext*, ScriptState*);
~WebSocketStream() override;
// IDL properties
const KURL& url() const { return common_.Url(); }
ScriptPromise<WebSocketOpenInfo> opened(ScriptState*) const;
ScriptPromise<WebSocketCloseInfo> closed(ScriptState*) const;
// IDL functions
void close(WebSocketCloseInfo*, ExceptionState&);
// Implementation of WebSocketChannelClient
void DidConnect(const String& subprotocol, const String& extensions) override;
void DidReceiveTextMessage(const String&) override;
void DidReceiveBinaryMessage(
const Vector<base::span<const char>>& data) override;
void DidError() override;
void DidConsumeBufferedAmount(uint64_t consumed) override;
void DidStartClosingHandshake() override;
void DidClose(ClosingHandshakeCompletionStatus,
uint16_t /* code */,
const String& /* reason */) override;
// Implementation of ExecutionContextLifecycleObserver.
void ContextDestroyed() override;
// Implementation of ActiveScriptWrappable.
bool HasPendingActivity() const override;
void Trace(Visitor*) const override;
private:
class UnderlyingSource;
class UnderlyingSink;
static WebSocketStream* CreateInternal(ScriptState*,
const String& url,
WebSocketStreamOptions*,
WebSocketChannel*,
ExceptionState&);
void Connect(ScriptState*,
const String& url,
WebSocketStreamOptions*,
ExceptionState&);
// Closes the connection. If |maybe_reason| is an object with a valid "code"
// property and optionally a valid "reason" property, will use them as the
// code and reason, otherwise will close with unspecified close.
void CloseMaybeWithReason(ScriptValue maybe_reason, ExceptionState&);
void CloseWithUnspecifiedCode(ExceptionState&);
void CloseInternal(std::optional<uint16_t> code,
const String& reason,
ExceptionState& exception_state);
void OnAbort();
// Create a WebSocketError with the supplied arguments.
v8::Local<v8::Value> CreateWebSocketError(
String message,
std::optional<uint16_t> close_code = std::nullopt,
String reason = String());
static WebSocketCloseInfo* MakeCloseInfo(uint16_t close_code,
const String& reason);
const Member<ScriptState> script_state_;
const Member<ScriptPromiseProperty<WebSocketOpenInfo, IDLAny>> opened_;
const Member<ScriptPromiseProperty<WebSocketCloseInfo, IDLAny>> closed_;
Member<WebSocketChannel> channel_;
Member<UnderlyingSource> source_;
Member<UnderlyingSink> sink_;
Member<AbortSignal::AlgorithmHandle> abort_handle_;
WebSocketCommon common_;
// We need to distinguish between "closing during handshake" and "closing
// after handshake" in order to reject the |opened_resolver_| correctly.
bool was_ever_connected_ = false;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WEBSOCKET_STREAM_H_
|