forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
websocket_adapter.h
106 lines (89 loc) · 4.14 KB
/
websocket_adapter.h
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
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_FIDO_CABLE_WEBSOCKET_ADAPTER_H_
#define DEVICE_FIDO_CABLE_WEBSOCKET_ADAPTER_H_
#include <vector>
#include "base/callback_forward.h"
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/optional.h"
#include "base/sequence_checker.h"
#include "device/fido/cable/v2_handshake.h"
#include "services/network/public/mojom/network_context.mojom.h"
namespace device {
namespace cablev2 {
// WebSocketAdapter implements several network::mojom interfaces needed to
// create a WebSocket connection and translates the Mojo interface into a
// callback-based one.
class COMPONENT_EXPORT(DEVICE_FIDO) WebSocketAdapter
: public network::mojom::WebSocketHandshakeClient,
network::mojom::WebSocketClient {
public:
using TunnelReadyCallback = base::OnceCallback<
void(bool, base::Optional<std::array<uint8_t, kRoutingIdSize>>)>;
using TunnelDataCallback =
base::RepeatingCallback<void(base::Optional<base::span<const uint8_t>>)>;
WebSocketAdapter(
// on_tunnel_ready is called once with a boolean that indicates whether
// the WebSocket successfully connected and an optional routing ID.
TunnelReadyCallback on_tunnel_ready,
// on_tunnel_ready is called repeatedly, after successful connection, with
// the contents of WebSocket messages. Framing is preserved so a single
// message written by the server will result in a single callback.
TunnelDataCallback on_tunnel_data);
~WebSocketAdapter() override;
WebSocketAdapter(const WebSocketAdapter&) = delete;
WebSocketAdapter& operator=(const WebSocketAdapter&) = delete;
mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
BindNewHandshakeClientPipe();
// Write writes data to the WebSocket server. The amount of data that can be
// written at once is limited by the size of an internal Mojo buffer which
// defaults to 64KiB. Exceeding that will cause the function to return false.
bool Write(base::span<const uint8_t> data);
// WebSocketHandshakeClient:
void OnOpeningHandshakeStarted(
network::mojom::WebSocketHandshakeRequestPtr request) override;
void OnConnectionEstablished(
mojo::PendingRemote<network::mojom::WebSocket> socket,
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver,
network::mojom::WebSocketHandshakeResponsePtr response,
mojo::ScopedDataPipeConsumerHandle readable,
mojo::ScopedDataPipeProducerHandle writable) override;
// WebSocketClient:
void OnDataFrame(bool finish,
network::mojom::WebSocketMessageType type,
uint64_t data_len) override;
void OnDropChannel(bool was_clean,
uint16_t code,
const std::string& reason) override;
void OnClosingHandshake() override;
private:
void OnMojoPipeDisconnect();
void OnDataPipeReady(MojoResult result,
const mojo::HandleSignalsState& state);
void Close();
void FlushPendingMessage();
bool closed_ = false;
// pending_message_ contains a partial message that is being reassembled.
std::vector<uint8_t> pending_message_;
// pending_message_i_ contains the number of valid bytes of
// |pending_message_|.
size_t pending_message_i_ = 0;
// pending_message_finished_ is true if |pending_message_| is the full size of
// an application frame and thus should be passed up once filled with bytes.
bool pending_message_finished_ = false;
TunnelReadyCallback on_tunnel_ready_;
const TunnelDataCallback on_tunnel_data_;
mojo::Receiver<network::mojom::WebSocketHandshakeClient> handshake_receiver_{
this};
mojo::Receiver<network::mojom::WebSocketClient> client_receiver_{this};
mojo::Remote<network::mojom::WebSocket> socket_remote_;
mojo::ScopedDataPipeConsumerHandle read_pipe_;
mojo::SimpleWatcher read_pipe_watcher_;
mojo::ScopedDataPipeProducerHandle write_pipe_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace cablev2
} // namespace device
#endif // DEVICE_FIDO_CABLE_WEBSOCKET_ADAPTER_H_