36 const std::string &websocket_key)
38 static const char guid[] =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
40 h.
update(websocket_key + guid);
73 return "WS-OPCODE-" + std::to_string(opcode);
86 const size_t size = buf.
size();
87 std::uint8_t *data = buf.
data();
88 for (
size_t i = 0; i < size; ++i)
89 data[i] ^=
mask8[i & 0x3];
123 const unsigned int opcode)
190 :
cli_rng(std::move(cli_rng_arg))
202 const size_t payload_len = buf.
size();
211 std::uint8_t head = s.
opcode() & 0xF;
214 buf.
prepend(&head,
sizeof(head));
225 len8 =
static_cast<std::uint8_t
>(len);
226 else if (len <= 65535)
229 const std::uint16_t len16 = htons(
static_cast<std::uint16_t
>(len));
230 buf.
prepend(&len16,
sizeof(len16));
236 buf.
prepend(&len64,
sizeof(len64));
241 buf.
prepend(&len8,
sizeof(len8));
260 throw websocket_error(
"Receiver::buf_unframed: internal error");
279 s.
fin_ = bool(head[0] & 0x80);
281 throw websocket_error(
"Receiver: reserved bits are set");
283 throw websocket_error(
"Receiver: bad masking direction");
286 const std::uint8_t pl = head[1] & 0x7f;
294 if (b.
size() <
sizeof(len16))
296 b.
read(&len16,
sizeof(len16));
302 if (b.
size() <
sizeof(len64))
304 b.
read(&len64,
sizeof(len64));
325 buf = std::move(inbuf);
359 throw websocket_error(
"Receiver::reset_buf: bad size");
374 throw websocket_error(
"Receiver: message incomplete");
451 os <<
"Sec-WebSocket-Version: 13\r\n";
452 if (!
conf->protocol.empty())
453 os <<
"Sec-WebSocket-Protocol: " <<
conf->protocol <<
"\r\n";
454 os <<
"Connection: Upgrade\r\n";
455 os <<
"Upgrade: websocket\r\n";
456 if (!
conf->origin.empty())
457 os <<
"Origin: " <<
conf->origin <<
"\r\n";
472 throw websocket_error(
"no config");
473 if (!
conf->digest_factory)
474 throw websocket_error(
"no digest factory in config");
480 std::uint8_t data[16];
481 conf->rng->rand_bytes(data,
sizeof(data));
522 os <<
"Upgrade: websocket\r\n";
523 os <<
"Connection: Upgrade\r\n";
526 if (!
conf->protocol.empty())
527 os <<
"Sec-WebSocket-Protocol: " <<
conf->protocol <<
"\r\n";
537 throw websocket_error(
"no config");
538 if (!
conf->digest_factory)
539 throw websocket_error(
"no digest factory in config");
std::string encode(const V &data) const
void clear()
Clears the contents of the buffer.
void add_flags(const BufferFlags flags)
Sets the specified flags for the buffer.
BufferAllocatedType & realign(const size_t headroom)
Realign the buffer with the specified headroom.
void append(const B &other)
Append data from another buffer to this buffer.
void prepend(const T *data, const size_t size)
Prepend data to the buffer.
bool allocated() const
Returns true if the data memory is defined (allocated).
size_t size() const
Returns the size of the buffer in T objects.
T * data()
Get a mutable pointer to the start of the array.
void advance(const size_t delta)
Advances the buffer by the specified delta.
auto * read_alloc(const size_t size)
Allocate memory and read data from the buffer into the allocated memory.
size_t offset() const
Returns the current offset (headroom) into the buffer.
void read(NCT *data, const size_t size)
Read data from the buffer into the specified memory location.
std::string final_base64()
void update(const std::string &str)
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
T rand_get()
Create a data object filled with random bytes.
Abstract base class for cryptographically strong random number generators.
bool confirm_websocket_key(const std::string &ws_accept) const
static Config::Ptr validate_conf(Config::Ptr conf)
std::string websocket_key
void client_headers(std::ostream &os)
PerRequest(Config::Ptr conf_arg)
void generate_websocket_key()
static std::string opcode_to_string(const unsigned int opcode)
static constexpr size_t MAX_HEAD
void verify_message_complete() const
void add_buf(BufferAllocated &&inbuf)
Receiver(const bool is_client_arg)
void prepend_payload_length(Buffer &buf, const size_t len) const
void frame(Buffer &buf, const Status &s) const
Sender(StrongRandomAPI::Ptr cli_rng_arg)
StrongRandomAPI::Ptr cli_rng
void set_websocket_key(const std::string &websocket_key)
void server_headers(std::ostream &os)
PerRequest(Config::Ptr conf_arg)
static Config::Ptr validate_conf(Config::Ptr conf)
std::string websocket_accept
unsigned int opcode() const
uint16_t close_status_code_
auto close_status_code() const
Status(unsigned int opcode, bool fin=true, uint16_t close_status_code=0)
std::string to_string() const
bool operator!=(const Status &rhs) const
bool operator==(const Status &rhs) const
Status(const Status &ref, const unsigned int opcode)
#define OPENVPN_EXCEPTION(C)
constexpr BufferFlags GROW(1u<< 2)
if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
std::uint64_t rev64(const std::uint64_t value)
std::string accept_confirmation(DigestFactory &digest_factory, const std::string &websocket_key)
BufferType< unsigned char > Buffer
Implementation of the base classes for random number generators.
size_t compress_threshold
DigestFactory::Ptr digest_factory
DigestFactory::Ptr digest_factory
void xor_buf(Buffer &buf) const
MaskingKey(std::uint32_t mask)
void prepend_mask(Buffer &buf) const