mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-02-14 16:57:12 +01:00
300 lines
10 KiB
C++
300 lines
10 KiB
C++
/*
|
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the WebSocket++ Project nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#ifndef WEBSOCKETPP_PROCESSOR_BASE_HPP
|
|
#define WEBSOCKETPP_PROCESSOR_BASE_HPP
|
|
|
|
#include <websocketpp/close.hpp>
|
|
#include <websocketpp/utilities.hpp>
|
|
#include <websocketpp/uri.hpp>
|
|
|
|
#include <websocketpp/common/cpp11.hpp>
|
|
#include <websocketpp/common/system_error.hpp>
|
|
|
|
#include <string>
|
|
|
|
namespace websocketpp {
|
|
namespace processor {
|
|
|
|
/// Constants related to processing WebSocket connections
|
|
namespace constants {
|
|
|
|
static char const upgrade_token[] = "websocket";
|
|
static char const connection_token[] = "Upgrade";
|
|
static char const handshake_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
|
|
} // namespace constants
|
|
|
|
|
|
/// Processor class related error codes
|
|
namespace error_cat {
|
|
enum value {
|
|
BAD_REQUEST = 0, // Error was the result of improperly formatted user input
|
|
INTERNAL_ERROR = 1, // Error was a logic error internal to WebSocket++
|
|
PROTOCOL_VIOLATION = 2,
|
|
MESSAGE_TOO_BIG = 3,
|
|
PAYLOAD_VIOLATION = 4 // Error was due to receiving invalid payload data
|
|
};
|
|
} // namespace error_cat
|
|
|
|
/// Error code category and codes used by all processor types
|
|
namespace error {
|
|
enum processor_errors {
|
|
/// Catch-all error for processor policy errors that don't fit in other
|
|
/// categories
|
|
general = 1,
|
|
|
|
/// Error was the result of improperly formatted user input
|
|
bad_request,
|
|
|
|
/// Processor encountered a protocol violation in an incoming message
|
|
protocol_violation,
|
|
|
|
/// Processor encountered a message that was too large
|
|
message_too_big,
|
|
|
|
/// Processor encountered invalid payload data.
|
|
invalid_payload,
|
|
|
|
/// The processor method was called with invalid arguments
|
|
invalid_arguments,
|
|
|
|
/// Opcode was invalid for requested operation
|
|
invalid_opcode,
|
|
|
|
/// Control frame too large
|
|
control_too_big,
|
|
|
|
/// Illegal use of reserved bit
|
|
invalid_rsv_bit,
|
|
|
|
/// Fragmented control message
|
|
fragmented_control,
|
|
|
|
/// Continuation without message
|
|
invalid_continuation,
|
|
|
|
/// Clients may not send unmasked frames
|
|
masking_required,
|
|
|
|
/// Servers may not send masked frames
|
|
masking_forbidden,
|
|
|
|
/// Payload length not minimally encoded
|
|
non_minimal_encoding,
|
|
|
|
/// Not supported on 32 bit systems
|
|
requires_64bit,
|
|
|
|
/// Invalid UTF-8 encoding
|
|
invalid_utf8,
|
|
|
|
/// Operation required not implemented functionality
|
|
not_implemented,
|
|
|
|
/// Invalid HTTP method
|
|
invalid_http_method,
|
|
|
|
/// Invalid HTTP version
|
|
invalid_http_version,
|
|
|
|
/// Invalid HTTP status
|
|
invalid_http_status,
|
|
|
|
/// Missing Required Header
|
|
missing_required_header,
|
|
|
|
/// Embedded SHA-1 library error
|
|
sha1_library,
|
|
|
|
/// No support for this feature in this protocol version.
|
|
no_protocol_support,
|
|
|
|
/// Reserved close code used
|
|
reserved_close_code,
|
|
|
|
/// Invalid close code used
|
|
invalid_close_code,
|
|
|
|
/// Using a reason requires a close code
|
|
reason_requires_code,
|
|
|
|
/// Error parsing subprotocols
|
|
subprotocol_parse_error,
|
|
|
|
/// Error parsing extensions
|
|
extension_parse_error,
|
|
|
|
/// Extension related operation was ignored because extensions are disabled
|
|
extensions_disabled,
|
|
|
|
/// Short Ke3 read. Hybi00 requires a third key to be read from the 8 bytes
|
|
/// after the handshake. Less than 8 bytes were read.
|
|
short_key3
|
|
};
|
|
|
|
/// Category for processor errors
|
|
class processor_category : public lib::error_category {
|
|
public:
|
|
processor_category() {}
|
|
|
|
char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
|
|
return "websocketpp.processor";
|
|
}
|
|
|
|
std::string message(int value) const {
|
|
switch(value) {
|
|
case error::general:
|
|
return "Generic processor error";
|
|
case error::bad_request:
|
|
return "invalid user input";
|
|
case error::protocol_violation:
|
|
return "Generic protocol violation";
|
|
case error::message_too_big:
|
|
return "A message was too large";
|
|
case error::invalid_payload:
|
|
return "A payload contained invalid data";
|
|
case error::invalid_arguments:
|
|
return "invalid function arguments";
|
|
case error::invalid_opcode:
|
|
return "invalid opcode";
|
|
case error::control_too_big:
|
|
return "Control messages are limited to fewer than 125 characters";
|
|
case error::invalid_rsv_bit:
|
|
return "Invalid use of reserved bits";
|
|
case error::fragmented_control:
|
|
return "Control messages cannot be fragmented";
|
|
case error::invalid_continuation:
|
|
return "Invalid message continuation";
|
|
case error::masking_required:
|
|
return "Clients may not send unmasked frames";
|
|
case error::masking_forbidden:
|
|
return "Servers may not send masked frames";
|
|
case error::non_minimal_encoding:
|
|
return "Payload length was not minimally encoded";
|
|
case error::requires_64bit:
|
|
return "64 bit frames are not supported on 32 bit systems";
|
|
case error::invalid_utf8:
|
|
return "Invalid UTF8 encoding";
|
|
case error::not_implemented:
|
|
return "Operation required not implemented functionality";
|
|
case error::invalid_http_method:
|
|
return "Invalid HTTP method.";
|
|
case error::invalid_http_version:
|
|
return "Invalid HTTP version.";
|
|
case error::invalid_http_status:
|
|
return "Invalid HTTP status.";
|
|
case error::missing_required_header:
|
|
return "A required HTTP header is missing";
|
|
case error::sha1_library:
|
|
return "SHA-1 library error";
|
|
case error::no_protocol_support:
|
|
return "The WebSocket protocol version in use does not support this feature";
|
|
case error::reserved_close_code:
|
|
return "Reserved close code used";
|
|
case error::invalid_close_code:
|
|
return "Invalid close code used";
|
|
case error::reason_requires_code:
|
|
return "Using a close reason requires a valid close code";
|
|
case error::subprotocol_parse_error:
|
|
return "Error parsing subprotocol header";
|
|
case error::extension_parse_error:
|
|
return "Error parsing extension header";
|
|
case error::extensions_disabled:
|
|
return "Extensions are disabled";
|
|
case error::short_key3:
|
|
return "Short Hybi00 Key 3 read";
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
};
|
|
|
|
/// Get a reference to a static copy of the processor error category
|
|
inline lib::error_category const & get_processor_category() {
|
|
static processor_category instance;
|
|
return instance;
|
|
}
|
|
|
|
/// Create an error code with the given value and the processor category
|
|
inline lib::error_code make_error_code(error::processor_errors e) {
|
|
return lib::error_code(static_cast<int>(e), get_processor_category());
|
|
}
|
|
|
|
/// Converts a processor error_code into a websocket close code
|
|
/**
|
|
* Looks up the appropriate WebSocket close code that should be sent after an
|
|
* error of this sort occurred.
|
|
*
|
|
* If the error is not in the processor category close::status::blank is
|
|
* returned.
|
|
*
|
|
* If the error isn't normally associated with reasons to close a connection
|
|
* (such as errors intended to be used internally or delivered to client
|
|
* applications, ex: invalid arguments) then
|
|
* close::status::internal_endpoint_error is returned.
|
|
*/
|
|
inline close::status::value to_ws(lib::error_code ec) {
|
|
if (ec.category() != get_processor_category()) {
|
|
return close::status::blank;
|
|
}
|
|
|
|
switch (ec.value()) {
|
|
case error::protocol_violation:
|
|
case error::control_too_big:
|
|
case error::invalid_opcode:
|
|
case error::invalid_rsv_bit:
|
|
case error::fragmented_control:
|
|
case error::invalid_continuation:
|
|
case error::masking_required:
|
|
case error::masking_forbidden:
|
|
case error::reserved_close_code:
|
|
case error::invalid_close_code:
|
|
return close::status::protocol_error;
|
|
case error::invalid_payload:
|
|
case error::invalid_utf8:
|
|
return close::status::invalid_payload;
|
|
case error::message_too_big:
|
|
return close::status::message_too_big;
|
|
default:
|
|
return close::status::internal_endpoint_error;
|
|
}
|
|
}
|
|
|
|
} // namespace error
|
|
} // namespace processor
|
|
} // namespace websocketpp
|
|
|
|
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
|
|
template<> struct is_error_code_enum<websocketpp::processor::error::processor_errors>
|
|
{
|
|
static bool const value = true;
|
|
};
|
|
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
|
|
|
|
#endif //WEBSOCKETPP_PROCESSOR_BASE_HPP
|