Seastar
High performance C++ framework for concurrent servers
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
common.hh
1/*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18/*
19 * Copyright 2024 ScyllaDB
20 */
21
22#pragma once
23
24#include <seastar/core/seastar.hh>
25#include <seastar/core/iostream.hh>
26#include <seastar/core/queue.hh>
27#include <seastar/net/api.hh>
28#include <seastar/util/log.hh>
29#include <seastar/websocket/parser.hh>
30
31namespace seastar::experimental::websocket {
32
33extern sstring magic_key_suffix;
34
35using handler_t = std::function<future<>(input_stream<char>&, output_stream<char>&)>;
36
37class server;
38
42
46class exception : public std::exception {
47 std::string _msg;
48public:
49 exception(std::string_view msg) : _msg(msg) {}
50 virtual const char* what() const noexcept {
51 return _msg.c_str();
52 }
53};
54
58class connection : public boost::intrusive::list_base_hook<> {
59protected:
61
66 queue<buff_t>* data;
67
68 public:
69 connection_source_impl(queue<buff_t>* data) : data(data) {}
70
71 virtual future<buff_t> get() override {
72 return data->pop_eventually().then_wrapped([](future<buff_t> f){
73 try {
74 return make_ready_future<buff_t>(std::move(f.get()));
75 } catch(...) {
76 return current_exception_as_future<buff_t>();
77 }
78 });
79 }
80
81 virtual future<> close() override {
82 data->push(buff_t(0));
83 return make_ready_future<>();
84 }
85 };
86
90 class connection_sink_impl final : public data_sink_impl {
91 queue<buff_t>* data;
92 public:
93 connection_sink_impl(queue<buff_t>* data) : data(data) {}
94
95 virtual future<> put(net::packet d) override {
96 net::fragment f = d.frag(0);
97 return data->push_eventually(temporary_buffer<char>{std::move(f.base), f.size});
98 }
99
100 size_t buffer_size() const noexcept override {
101 return data->max_size();
102 }
103
104 virtual future<> close() override {
105 data->push(buff_t(0));
106 return make_ready_future<>();
107 }
108 };
109
120
121 static const size_t PIPE_SIZE = 512;
123 input_stream<char> _read_buf;
124 output_stream<char> _write_buf;
125 bool _done = false;
126
127 websocket_parser _websocket_parser;
128 queue <temporary_buffer<char>> _input_buffer;
129 input_stream<char> _input;
130 queue <temporary_buffer<char>> _output_buffer;
131 output_stream<char> _output;
132
133 sstring _subprotocol;
134 handler_t _handler;
135public:
140 : _fd(std::move(fd))
141 , _read_buf(_fd.input())
142 , _write_buf(_fd.output())
143 , _input_buffer{PIPE_SIZE}
144 , _output_buffer{PIPE_SIZE}
145 {
147 std::make_unique<connection_source_impl>(&_input_buffer)}};
149 std::make_unique<connection_sink_impl>(&_output_buffer)}};
150 }
151
156 future<> close(bool send_close = true);
157
158protected:
159 future<> read_one();
160 future<> response_loop();
165};
166
167std::string sha1_base64(std::string_view source);
168std::string encode_base64(std::string_view source);
169
170extern logger websocket_logger;
171
173}
Definition: api.hh:183
Definition: iostream.hh:105
Definition: iostream.hh:164
Definition: iostream.hh:62
Definition: iostream.hh:70
Implementation of connection's data sink.
Definition: common.hh:90
Implementation of connection's data source.
Definition: common.hh:65
a server WebSocket connection
Definition: common.hh:58
connection(connected_socket &&fd)
Definition: common.hh:139
future handle_ping()
This function processess received PING frame. https://datatracker.ietf.org/doc/html/rfc6455#section-5...
future handle_pong()
This function processess received PONG frame. https://datatracker.ietf.org/doc/html/rfc6455#section-5...
future send_data(opcodes opcode, temporary_buffer< char > &&buff)
Packs buff in websocket frame and sends it to the client.
an error in handling a WebSocket connection
Definition: common.hh:46
A representation of a possibly not-yet-computed value.
Definition: future.hh:1197
futurize_t< FuncResult > then_wrapped(Func &&func) &noexcept
Schedule a block of code to run when the future is ready, allowing for exception handling.
Definition: future.hh:1458
value_type && get()
gets the value returned by the computation
Definition: future.hh:1299
Definition: packet.hh:87
Definition: queue.hh:45
opcodes
Possible type of a websocket frame.
Definition: parser.hh:32
Definition: packet.hh:46
STL namespace.