2
3
7#include <restinio/exception.hpp>
8#include <restinio/websocket/impl/utf8.hpp>
9#include <restinio/websocket/impl/ws_parser.hpp>
57 static constexpr const char* table[] =
60 "frame_header_is_valid",
61 "payload_part_is_valid",
64 "empty_mask_from_client_side",
65 "non_final_control_frame",
67 "payload_len_is_too_big",
68 "continuation_frame_without_data_frame",
69 "new_data_frame_without_finishing_previous",
74 return table[
static_cast<
unsigned int>(state)];
83
84
85
89 return opcode ==
opcode_t::connection_close_frame ||
100
101
102
106 return opcode ==
opcode_t::text_frame ||
115
116
117
118
138
139
143 return masked_byte ^ m_mask[ (m_processed_bytes_count++) % 4 ];
150 m_processed_bytes_count = 0;
152 m_mask = mask_array_t{
153 {::restinio::utils::impl::bitops::n_bits_from< std::uint8_t, 24 >(
155 ::restinio::utils::impl::bitops::n_bits_from< std::uint8_t, 16 >(
157 ::restinio::utils::impl::bitops::n_bits_from< std::uint8_t, 8 >(
159 ::restinio::utils::impl::bitops::n_bits_from< std::uint8_t, 0 >(
171
172
173
183
184
185
186
187
188
189
190
191
192
193
207
208
209
231 case opcode_t::connection_close_frame:
232 m_expected_close_code.reset(2);
244 m_unmasker.reset( frame.m_masking_key );
264 for( size_t i = 0; i < size; ++i )
267 static_cast<std::uint8_t>(data[i])
);
289 for( size_t i = 0; i < size; ++i )
292 static_cast<std::uint8_t>(data[i])
));
336 return this_frame_validation_state;
355
356
357
358
359
389 websocket_max_payload_size_without_ext )
400
401
402
403
404
408 byte = m_unmask_flag?
409 m_unmasker.unmask_byte( byte ): byte;
423 if( !m_expected_close_code.all_bytes_loaded() )
425 if( m_expected_close_code.add_byte_and_check_size(byte) )
427 uint16_t status_code{0};
429 read_number_from_big_endian_bytes(
430 status_code,m_expected_close_code.m_loaded_data );
448
449
450
451
452
453
454
455
456
457
458
463 opcode ==
opcode_t::continuation_frame )
487 if( close_code < 1000 ||
488 (close_code > 1011 && close_code < 3000) ||
497 if( close_code == 1004 ||
498 close_code == 1005 ||
520
521
530
531
532
533
534
535
550
551
552
Exception class for all exceptions thrown by RESTinio.
exception_t(const char *err)
Helper class for checking UTF-8 byte sequence during parsing URI or incoming byte stream.
bool process_byte(std::uint8_t byte) noexcept
bool finalized() const noexcept
Websocket message class with more detailed protocol information.
std::uint64_t payload_len() const
Get payload len.
bool m_rsv1_flag
Reserved flags.
bool m_final_flag
Final flag.
bool m_mask_flag
Mask flag.
Class for websocket protocol validations.
validation_state_t process_and_unmask_next_payload_part(char *data, size_t size)
Validate next part of current frame and reset source part to unmasked data.
bool validate_frame_header(const message_details_t &frame)
Validate frame header.
ws_protocol_validator_t()=default
validation_state_t m_validation_state
Current validation state.
previous_data_frame_t m_previous_data_frame
Previous unfinished data frame.
validation_state_t process_new_frame(const message_details_t &frame)
Start work with new frame.
bool is_state_still_valid() const
Check validation state is still valid.
working_state_t
Validator's orking states.
@ processing_frame
Frame is processing now.
@ empty_state
Waiting for new frame.
working_state_t m_working_state
Working state.
unmasker_t m_unmasker
Unmask payload coming from client side.
std::uint8_t process_payload_byte(std::uint8_t byte)
Process payload byte.
previous_data_frame_t
Previous unfinished data frame type.
validation_state_t process_next_payload_part(const char *data, size_t size)
Validate next part of current frame.
expected_data_t m_expected_close_code
Buffer for accumulating 2 bytes of close code.
void validate_close_code(uint16_t close_code)
Validate close code.
bool check_previous_frame_type(opcode_t opcode)
Check previous frame type.
ws_protocol_validator_t(bool do_unmask)
message_details_t m_current_frame
Current frame details.
void set_validation_state(validation_state_t state)
Try to set validation state.
validation_state_t finish_frame()
Make final checks of payload if it is necessary and reset state.
restinio::utils::utf8_checker_t m_utf8_checker
UTF-8 checker for text frames and close frames.
bool m_unmask_flag
This flag set if it's need to unmask payload parts.
void reset()
Reset to initial state.
bool is_data_frame(opcode_t opcode)
Check frame is data frame.
bool is_control_frame(opcode_t opcode)
Check frame is control frame.
const char * validation_state_str(validation_state_t state)
Helper function for logging validation states.
validation_state_t
States of validated frame.
@ non_final_control_frame
@ continuation_frame_without_data_frame
@ empty_mask_from_client_side
@ new_data_frame_without_finishing_previous
bool is_valid_opcode(opcode_t opcode)
void reset(uint32_t masking_key)
Reset to initial state.
size_t m_processed_bytes_count
Processed bytes counter.
mask_array_t m_mask
Bytes array with masking key.
unmasker_t(uint32_t masking_key)
uint8_t unmask_byte(uint8_t masked_byte)
Do unmask operation.