mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-12-20 06:57:19 +01:00
Initial preparations for CURL and Discord integration.
This commit is contained in:
308
module/Vendor/WebSocketPP/websocketpp/http/constants.hpp
vendored
Normal file
308
module/Vendor/WebSocketPP/websocketpp/http/constants.hpp
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* 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 HTTP_CONSTANTS_HPP
|
||||
#define HTTP_CONSTANTS_HPP
|
||||
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace websocketpp {
|
||||
/// HTTP handling support
|
||||
namespace http {
|
||||
/// The type of an HTTP attribute list
|
||||
/**
|
||||
* The attribute list is an unordered key/value map. Encoded attribute
|
||||
* values are delimited by semicolons.
|
||||
*/
|
||||
typedef std::map<std::string,std::string> attribute_list;
|
||||
|
||||
/// The type of an HTTP parameter list
|
||||
/**
|
||||
* The parameter list is an ordered pairing of a parameter and its
|
||||
* associated attribute list. Encoded parameter values are delimited by
|
||||
* commas.
|
||||
*/
|
||||
typedef std::vector< std::pair<std::string,attribute_list> > parameter_list;
|
||||
|
||||
/// Literal value of the HTTP header delimiter
|
||||
static char const header_delimiter[] = "\r\n";
|
||||
|
||||
/// Literal value of the HTTP header separator
|
||||
static char const header_separator[] = ":";
|
||||
|
||||
/// Literal value of an empty header
|
||||
static std::string const empty_header;
|
||||
|
||||
/// Maximum size in bytes before rejecting an HTTP header as too big.
|
||||
size_t const max_header_size = 16000;
|
||||
|
||||
/// Default Maximum size in bytes for HTTP message bodies.
|
||||
size_t const max_body_size = 32000000;
|
||||
|
||||
/// Number of bytes to use for temporary istream read buffers
|
||||
size_t const istream_buffer = 512;
|
||||
|
||||
/// invalid HTTP token characters
|
||||
/**
|
||||
* 0x00 - 0x32, 0x7f-0xff
|
||||
* ( ) < > @ , ; : \ " / [ ] ? = { }
|
||||
*/
|
||||
static char const header_token[] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f
|
||||
0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f
|
||||
1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f
|
||||
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f
|
||||
1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f
|
||||
1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff
|
||||
};
|
||||
|
||||
/// Is the character a token
|
||||
inline bool is_token_char(unsigned char c) {
|
||||
return (header_token[c] == 1);
|
||||
}
|
||||
|
||||
/// Is the character a non-token
|
||||
inline bool is_not_token_char(unsigned char c) {
|
||||
return !header_token[c];
|
||||
}
|
||||
|
||||
/// Is the character whitespace
|
||||
/**
|
||||
* whitespace is space (32) or horizontal tab (9)
|
||||
*/
|
||||
inline bool is_whitespace_char(unsigned char c) {
|
||||
return (c == 9 || c == 32);
|
||||
}
|
||||
|
||||
/// Is the character non-whitespace
|
||||
inline bool is_not_whitespace_char(unsigned char c) {
|
||||
return (c != 9 && c != 32);
|
||||
}
|
||||
|
||||
/// HTTP Status codes
|
||||
namespace status_code {
|
||||
enum value {
|
||||
uninitialized = 0,
|
||||
|
||||
continue_code = 100,
|
||||
switching_protocols = 101,
|
||||
|
||||
ok = 200,
|
||||
created = 201,
|
||||
accepted = 202,
|
||||
non_authoritative_information = 203,
|
||||
no_content = 204,
|
||||
reset_content = 205,
|
||||
partial_content = 206,
|
||||
|
||||
multiple_choices = 300,
|
||||
moved_permanently = 301,
|
||||
found = 302,
|
||||
see_other = 303,
|
||||
not_modified = 304,
|
||||
use_proxy = 305,
|
||||
temporary_redirect = 307,
|
||||
|
||||
bad_request = 400,
|
||||
unauthorized = 401,
|
||||
payment_required = 402,
|
||||
forbidden = 403,
|
||||
not_found = 404,
|
||||
method_not_allowed = 405,
|
||||
not_acceptable = 406,
|
||||
proxy_authentication_required = 407,
|
||||
request_timeout = 408,
|
||||
conflict = 409,
|
||||
gone = 410,
|
||||
length_required = 411,
|
||||
precondition_failed = 412,
|
||||
request_entity_too_large = 413,
|
||||
request_uri_too_long = 414,
|
||||
unsupported_media_type = 415,
|
||||
request_range_not_satisfiable = 416,
|
||||
expectation_failed = 417,
|
||||
im_a_teapot = 418,
|
||||
upgrade_required = 426,
|
||||
precondition_required = 428,
|
||||
too_many_requests = 429,
|
||||
request_header_fields_too_large = 431,
|
||||
|
||||
internal_server_error = 500,
|
||||
not_implemented = 501,
|
||||
bad_gateway = 502,
|
||||
service_unavailable = 503,
|
||||
gateway_timeout = 504,
|
||||
http_version_not_supported = 505,
|
||||
not_extended = 510,
|
||||
network_authentication_required = 511
|
||||
};
|
||||
|
||||
// TODO: should this be inline?
|
||||
inline std::string get_string(value c) {
|
||||
switch (c) {
|
||||
case uninitialized:
|
||||
return "Uninitialized";
|
||||
case continue_code:
|
||||
return "Continue";
|
||||
case switching_protocols:
|
||||
return "Switching Protocols";
|
||||
case ok:
|
||||
return "OK";
|
||||
case created:
|
||||
return "Created";
|
||||
case accepted:
|
||||
return "Accepted";
|
||||
case non_authoritative_information:
|
||||
return "Non Authoritative Information";
|
||||
case no_content:
|
||||
return "No Content";
|
||||
case reset_content:
|
||||
return "Reset Content";
|
||||
case partial_content:
|
||||
return "Partial Content";
|
||||
case multiple_choices:
|
||||
return "Multiple Choices";
|
||||
case moved_permanently:
|
||||
return "Moved Permanently";
|
||||
case found:
|
||||
return "Found";
|
||||
case see_other:
|
||||
return "See Other";
|
||||
case not_modified:
|
||||
return "Not Modified";
|
||||
case use_proxy:
|
||||
return "Use Proxy";
|
||||
case temporary_redirect:
|
||||
return "Temporary Redirect";
|
||||
case bad_request:
|
||||
return "Bad Request";
|
||||
case unauthorized:
|
||||
return "Unauthorized";
|
||||
case payment_required:
|
||||
return "Payment Required";
|
||||
case forbidden:
|
||||
return "Forbidden";
|
||||
case not_found:
|
||||
return "Not Found";
|
||||
case method_not_allowed:
|
||||
return "Method Not Allowed";
|
||||
case not_acceptable:
|
||||
return "Not Acceptable";
|
||||
case proxy_authentication_required:
|
||||
return "Proxy Authentication Required";
|
||||
case request_timeout:
|
||||
return "Request Timeout";
|
||||
case conflict:
|
||||
return "Conflict";
|
||||
case gone:
|
||||
return "Gone";
|
||||
case length_required:
|
||||
return "Length Required";
|
||||
case precondition_failed:
|
||||
return "Precondition Failed";
|
||||
case request_entity_too_large:
|
||||
return "Request Entity Too Large";
|
||||
case request_uri_too_long:
|
||||
return "Request-URI Too Long";
|
||||
case unsupported_media_type:
|
||||
return "Unsupported Media Type";
|
||||
case request_range_not_satisfiable:
|
||||
return "Requested Range Not Satisfiable";
|
||||
case expectation_failed:
|
||||
return "Expectation Failed";
|
||||
case im_a_teapot:
|
||||
return "I'm a teapot";
|
||||
case upgrade_required:
|
||||
return "Upgrade Required";
|
||||
case precondition_required:
|
||||
return "Precondition Required";
|
||||
case too_many_requests:
|
||||
return "Too Many Requests";
|
||||
case request_header_fields_too_large:
|
||||
return "Request Header Fields Too Large";
|
||||
case internal_server_error:
|
||||
return "Internal Server Error";
|
||||
case not_implemented:
|
||||
return "Not Implemented";
|
||||
case bad_gateway:
|
||||
return "Bad Gateway";
|
||||
case service_unavailable:
|
||||
return "Service Unavailable";
|
||||
case gateway_timeout:
|
||||
return "Gateway Timeout";
|
||||
case http_version_not_supported:
|
||||
return "HTTP Version Not Supported";
|
||||
case not_extended:
|
||||
return "Not Extended";
|
||||
case network_authentication_required:
|
||||
return "Network Authentication Required";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class exception : public std::exception {
|
||||
public:
|
||||
exception(const std::string& log_msg,
|
||||
status_code::value error_code,
|
||||
const std::string& error_msg = std::string(),
|
||||
const std::string& body = std::string())
|
||||
: m_msg(log_msg)
|
||||
, m_error_msg(error_msg)
|
||||
, m_body(body)
|
||||
, m_error_code(error_code) {}
|
||||
|
||||
~exception() throw() {}
|
||||
|
||||
virtual const char* what() const throw() {
|
||||
return m_msg.c_str();
|
||||
}
|
||||
|
||||
std::string m_msg;
|
||||
std::string m_error_msg;
|
||||
std::string m_body;
|
||||
status_code::value m_error_code;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HTTP_CONSTANTS_HPP
|
||||
200
module/Vendor/WebSocketPP/websocketpp/http/impl/parser.hpp
vendored
Normal file
200
module/Vendor/WebSocketPP/websocketpp/http/impl/parser.hpp
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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 HTTP_PARSER_IMPL_HPP
|
||||
#define HTTP_PARSER_IMPL_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
inline void parser::set_version(std::string const & version) {
|
||||
m_version = version;
|
||||
}
|
||||
|
||||
inline std::string const & parser::get_header(std::string const & key) const {
|
||||
header_list::const_iterator h = m_headers.find(key);
|
||||
|
||||
if (h == m_headers.end()) {
|
||||
return empty_header;
|
||||
} else {
|
||||
return h->second;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool parser::get_header_as_plist(std::string const & key,
|
||||
parameter_list & out) const
|
||||
{
|
||||
header_list::const_iterator it = m_headers.find(key);
|
||||
|
||||
if (it == m_headers.end() || it->second.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->parse_parameter_list(it->second,out);
|
||||
}
|
||||
|
||||
inline void parser::append_header(std::string const & key, std::string const &
|
||||
val)
|
||||
{
|
||||
if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) {
|
||||
throw exception("Invalid header name",status_code::bad_request);
|
||||
}
|
||||
|
||||
if (this->get_header(key).empty()) {
|
||||
m_headers[key] = val;
|
||||
} else {
|
||||
m_headers[key] += ", " + val;
|
||||
}
|
||||
}
|
||||
|
||||
inline void parser::replace_header(std::string const & key, std::string const &
|
||||
val)
|
||||
{
|
||||
m_headers[key] = val;
|
||||
}
|
||||
|
||||
inline void parser::remove_header(std::string const & key) {
|
||||
m_headers.erase(key);
|
||||
}
|
||||
|
||||
inline void parser::set_body(std::string const & value) {
|
||||
if (value.size() == 0) {
|
||||
remove_header("Content-Length");
|
||||
m_body.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: should this method respect the max size? If so how should errors
|
||||
// be indicated?
|
||||
|
||||
std::stringstream len;
|
||||
len << value.size();
|
||||
replace_header("Content-Length", len.str());
|
||||
m_body = value;
|
||||
}
|
||||
|
||||
inline bool parser::parse_parameter_list(std::string const & in,
|
||||
parameter_list & out) const
|
||||
{
|
||||
if (in.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string::const_iterator it;
|
||||
it = extract_parameters(in.begin(),in.end(),out);
|
||||
return (it == in.begin());
|
||||
}
|
||||
|
||||
inline bool parser::prepare_body() {
|
||||
if (!get_header("Content-Length").empty()) {
|
||||
std::string const & cl_header = get_header("Content-Length");
|
||||
char * end;
|
||||
|
||||
// TODO: not 100% sure what the compatibility of this method is. Also,
|
||||
// I believe this will only work up to 32bit sizes. Is there a need for
|
||||
// > 4GiB HTTP payloads?
|
||||
m_body_bytes_needed = std::strtoul(cl_header.c_str(),&end,10);
|
||||
|
||||
if (m_body_bytes_needed > m_body_bytes_max) {
|
||||
throw exception("HTTP message body too large",
|
||||
status_code::request_entity_too_large);
|
||||
}
|
||||
|
||||
m_body_encoding = body_encoding::plain;
|
||||
return true;
|
||||
} else if (get_header("Transfer-Encoding") == "chunked") {
|
||||
// TODO
|
||||
//m_body_encoding = body_encoding::chunked;
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline size_t parser::process_body(char const * buf, size_t len) {
|
||||
if (m_body_encoding == body_encoding::plain) {
|
||||
size_t processed = (std::min)(m_body_bytes_needed,len);
|
||||
m_body.append(buf,processed);
|
||||
m_body_bytes_needed -= processed;
|
||||
return processed;
|
||||
} else if (m_body_encoding == body_encoding::chunked) {
|
||||
// TODO:
|
||||
throw exception("Unexpected body encoding",
|
||||
status_code::internal_server_error);
|
||||
} else {
|
||||
throw exception("Unexpected body encoding",
|
||||
status_code::internal_server_error);
|
||||
}
|
||||
}
|
||||
|
||||
inline void parser::process_header(std::string::iterator begin,
|
||||
std::string::iterator end)
|
||||
{
|
||||
std::string::iterator cursor = std::search(
|
||||
begin,
|
||||
end,
|
||||
header_separator,
|
||||
header_separator + sizeof(header_separator) - 1
|
||||
);
|
||||
|
||||
if (cursor == end) {
|
||||
throw exception("Invalid header line",status_code::bad_request);
|
||||
}
|
||||
|
||||
append_header(strip_lws(std::string(begin,cursor)),
|
||||
strip_lws(std::string(cursor+sizeof(header_separator)-1,end)));
|
||||
}
|
||||
|
||||
inline header_list const & parser::get_headers() const {
|
||||
return m_headers;
|
||||
}
|
||||
|
||||
inline std::string parser::raw_headers() const {
|
||||
std::stringstream raw;
|
||||
|
||||
header_list::const_iterator it;
|
||||
for (it = m_headers.begin(); it != m_headers.end(); it++) {
|
||||
raw << it->first << ": " << it->second << "\r\n";
|
||||
}
|
||||
|
||||
return raw.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace parser
|
||||
} // namespace http
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // HTTP_PARSER_IMPL_HPP
|
||||
191
module/Vendor/WebSocketPP/websocketpp/http/impl/request.hpp
vendored
Normal file
191
module/Vendor/WebSocketPP/websocketpp/http/impl/request.hpp
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* 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 HTTP_PARSER_REQUEST_IMPL_HPP
|
||||
#define HTTP_PARSER_REQUEST_IMPL_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
inline size_t request::consume(char const * buf, size_t len) {
|
||||
size_t bytes_processed;
|
||||
|
||||
if (m_ready) {return 0;}
|
||||
|
||||
if (m_body_bytes_needed > 0) {
|
||||
bytes_processed = process_body(buf,len);
|
||||
if (body_ready()) {
|
||||
m_ready = true;
|
||||
}
|
||||
return bytes_processed;
|
||||
}
|
||||
|
||||
// copy new header bytes into buffer
|
||||
m_buf->append(buf,len);
|
||||
|
||||
// Search for delimiter in buf. If found read until then. If not read all
|
||||
std::string::iterator begin = m_buf->begin();
|
||||
std::string::iterator end;
|
||||
|
||||
for (;;) {
|
||||
// search for line delimiter
|
||||
end = std::search(
|
||||
begin,
|
||||
m_buf->end(),
|
||||
header_delimiter,
|
||||
header_delimiter+sizeof(header_delimiter)-1
|
||||
);
|
||||
|
||||
m_header_bytes += (end-begin+sizeof(header_delimiter));
|
||||
|
||||
if (m_header_bytes > max_header_size) {
|
||||
// exceeded max header size
|
||||
throw exception("Maximum header size exceeded.",
|
||||
status_code::request_header_fields_too_large);
|
||||
}
|
||||
|
||||
if (end == m_buf->end()) {
|
||||
// we are out of bytes. Discard the processed bytes and copy the
|
||||
// remaining unprecessed bytes to the beginning of the buffer
|
||||
std::copy(begin,end,m_buf->begin());
|
||||
m_buf->resize(static_cast<std::string::size_type>(end-begin));
|
||||
m_header_bytes -= m_buf->size();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//the range [begin,end) now represents a line to be processed.
|
||||
if (end-begin == 0) {
|
||||
// we got a blank line
|
||||
if (m_method.empty() || get_header("Host").empty()) {
|
||||
throw exception("Incomplete Request",status_code::bad_request);
|
||||
}
|
||||
|
||||
bytes_processed = (
|
||||
len - static_cast<std::string::size_type>(m_buf->end()-end)
|
||||
+ sizeof(header_delimiter) - 1
|
||||
);
|
||||
|
||||
// frees memory used temporarily during request parsing
|
||||
m_buf.reset();
|
||||
|
||||
// if this was not an upgrade request and has a content length
|
||||
// continue capturing content-length bytes and expose them as a
|
||||
// request body.
|
||||
|
||||
if (prepare_body()) {
|
||||
bytes_processed += process_body(buf+bytes_processed,len-bytes_processed);
|
||||
if (body_ready()) {
|
||||
m_ready = true;
|
||||
}
|
||||
return bytes_processed;
|
||||
} else {
|
||||
m_ready = true;
|
||||
|
||||
// return number of bytes processed (starting bytes - bytes left)
|
||||
return bytes_processed;
|
||||
}
|
||||
} else {
|
||||
if (m_method.empty()) {
|
||||
this->process(begin,end);
|
||||
} else {
|
||||
this->process_header(begin,end);
|
||||
}
|
||||
}
|
||||
|
||||
begin = end+(sizeof(header_delimiter)-1);
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string request::raw() const {
|
||||
// TODO: validation. Make sure all required fields have been set?
|
||||
std::stringstream ret;
|
||||
|
||||
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
|
||||
ret << raw_headers() << "\r\n" << m_body;
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
inline std::string request::raw_head() const {
|
||||
// TODO: validation. Make sure all required fields have been set?
|
||||
std::stringstream ret;
|
||||
|
||||
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
|
||||
ret << raw_headers() << "\r\n";
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
inline void request::set_method(std::string const & method) {
|
||||
if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) {
|
||||
throw exception("Invalid method token.",status_code::bad_request);
|
||||
}
|
||||
|
||||
m_method = method;
|
||||
}
|
||||
|
||||
inline void request::set_uri(std::string const & uri) {
|
||||
// TODO: validation?
|
||||
m_uri = uri;
|
||||
}
|
||||
|
||||
inline void request::process(std::string::iterator begin, std::string::iterator
|
||||
end)
|
||||
{
|
||||
std::string::iterator cursor_start = begin;
|
||||
std::string::iterator cursor_end = std::find(begin,end,' ');
|
||||
|
||||
if (cursor_end == end) {
|
||||
throw exception("Invalid request line1",status_code::bad_request);
|
||||
}
|
||||
|
||||
set_method(std::string(cursor_start,cursor_end));
|
||||
|
||||
cursor_start = cursor_end+1;
|
||||
cursor_end = std::find(cursor_start,end,' ');
|
||||
|
||||
if (cursor_end == end) {
|
||||
throw exception("Invalid request line2",status_code::bad_request);
|
||||
}
|
||||
|
||||
set_uri(std::string(cursor_start,cursor_end));
|
||||
set_version(std::string(cursor_end+1,end));
|
||||
}
|
||||
|
||||
} // namespace parser
|
||||
} // namespace http
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // HTTP_PARSER_REQUEST_IMPL_HPP
|
||||
266
module/Vendor/WebSocketPP/websocketpp/http/impl/response.hpp
vendored
Normal file
266
module/Vendor/WebSocketPP/websocketpp/http/impl/response.hpp
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* 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 HTTP_PARSER_RESPONSE_IMPL_HPP
|
||||
#define HTTP_PARSER_RESPONSE_IMPL_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
inline size_t response::consume(char const * buf, size_t len) {
|
||||
if (m_state == DONE) {return 0;}
|
||||
|
||||
if (m_state == BODY) {
|
||||
return this->process_body(buf,len);
|
||||
}
|
||||
|
||||
// copy new header bytes into buffer
|
||||
m_buf->append(buf,len);
|
||||
|
||||
// Search for delimiter in buf. If found read until then. If not read all
|
||||
std::string::iterator begin = m_buf->begin();
|
||||
std::string::iterator end = begin;
|
||||
|
||||
|
||||
for (;;) {
|
||||
// search for delimiter
|
||||
end = std::search(
|
||||
begin,
|
||||
m_buf->end(),
|
||||
header_delimiter,
|
||||
header_delimiter + sizeof(header_delimiter) - 1
|
||||
);
|
||||
|
||||
m_header_bytes += (end-begin+sizeof(header_delimiter));
|
||||
|
||||
if (m_header_bytes > max_header_size) {
|
||||
// exceeded max header size
|
||||
throw exception("Maximum header size exceeded.",
|
||||
status_code::request_header_fields_too_large);
|
||||
}
|
||||
|
||||
if (end == m_buf->end()) {
|
||||
// we are out of bytes. Discard the processed bytes and copy the
|
||||
// remaining unprecessed bytes to the beginning of the buffer
|
||||
std::copy(begin,end,m_buf->begin());
|
||||
m_buf->resize(static_cast<std::string::size_type>(end-begin));
|
||||
|
||||
m_read += len;
|
||||
m_header_bytes -= m_buf->size();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//the range [begin,end) now represents a line to be processed.
|
||||
|
||||
if (end-begin == 0) {
|
||||
// we got a blank line
|
||||
if (m_state == RESPONSE_LINE) {
|
||||
throw exception("Incomplete Request",status_code::bad_request);
|
||||
}
|
||||
|
||||
// TODO: grab content-length
|
||||
std::string length = get_header("Content-Length");
|
||||
|
||||
if (length.empty()) {
|
||||
// no content length found, read indefinitely
|
||||
m_read = 0;
|
||||
} else {
|
||||
std::istringstream ss(length);
|
||||
|
||||
if ((ss >> m_read).fail()) {
|
||||
throw exception("Unable to parse Content-Length header",
|
||||
status_code::bad_request);
|
||||
}
|
||||
}
|
||||
|
||||
m_state = BODY;
|
||||
|
||||
// calc header bytes processed (starting bytes - bytes left)
|
||||
size_t read = (
|
||||
len - static_cast<std::string::size_type>(m_buf->end() - end)
|
||||
+ sizeof(header_delimiter) - 1
|
||||
);
|
||||
|
||||
// if there were bytes left process them as body bytes
|
||||
if (read < len) {
|
||||
read += this->process_body(buf+read,(len-read));
|
||||
}
|
||||
|
||||
// frees memory used temporarily during header parsing
|
||||
m_buf.reset();
|
||||
|
||||
return read;
|
||||
} else {
|
||||
if (m_state == RESPONSE_LINE) {
|
||||
this->process(begin,end);
|
||||
m_state = HEADERS;
|
||||
} else {
|
||||
this->process_header(begin,end);
|
||||
}
|
||||
}
|
||||
|
||||
begin = end+(sizeof(header_delimiter) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
inline size_t response::consume(std::istream & s) {
|
||||
char buf[istream_buffer];
|
||||
size_t bytes_read;
|
||||
size_t bytes_processed;
|
||||
size_t total = 0;
|
||||
|
||||
while (s.good()) {
|
||||
s.getline(buf,istream_buffer);
|
||||
bytes_read = static_cast<size_t>(s.gcount());
|
||||
|
||||
if (s.fail() || s.eof()) {
|
||||
bytes_processed = this->consume(buf,bytes_read);
|
||||
total += bytes_processed;
|
||||
|
||||
if (bytes_processed != bytes_read) {
|
||||
// problem
|
||||
break;
|
||||
}
|
||||
} else if (s.bad()) {
|
||||
// problem
|
||||
break;
|
||||
} else {
|
||||
// the delimiting newline was found. Replace the trailing null with
|
||||
// the newline that was discarded, since our raw consume function
|
||||
// expects the newline to be be there.
|
||||
buf[bytes_read-1] = '\n';
|
||||
bytes_processed = this->consume(buf,bytes_read);
|
||||
total += bytes_processed;
|
||||
|
||||
if (bytes_processed != bytes_read) {
|
||||
// problem
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
inline std::string response::raw() const {
|
||||
// TODO: validation. Make sure all required fields have been set?
|
||||
|
||||
std::stringstream ret;
|
||||
|
||||
ret << get_version() << " " << m_status_code << " " << m_status_msg;
|
||||
ret << "\r\n" << raw_headers() << "\r\n";
|
||||
|
||||
ret << m_body;
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
inline void response::set_status(status_code::value code) {
|
||||
// TODO: validation?
|
||||
m_status_code = code;
|
||||
m_status_msg = get_string(code);
|
||||
}
|
||||
|
||||
inline void response::set_status(status_code::value code, std::string const &
|
||||
msg)
|
||||
{
|
||||
// TODO: validation?
|
||||
m_status_code = code;
|
||||
m_status_msg = msg;
|
||||
}
|
||||
|
||||
inline void response::process(std::string::iterator begin,
|
||||
std::string::iterator end)
|
||||
{
|
||||
std::string::iterator cursor_start = begin;
|
||||
std::string::iterator cursor_end = std::find(begin,end,' ');
|
||||
|
||||
if (cursor_end == end) {
|
||||
throw exception("Invalid response line",status_code::bad_request);
|
||||
}
|
||||
|
||||
set_version(std::string(cursor_start,cursor_end));
|
||||
|
||||
cursor_start = cursor_end+1;
|
||||
cursor_end = std::find(cursor_start,end,' ');
|
||||
|
||||
if (cursor_end == end) {
|
||||
throw exception("Invalid request line",status_code::bad_request);
|
||||
}
|
||||
|
||||
int code;
|
||||
|
||||
std::istringstream ss(std::string(cursor_start,cursor_end));
|
||||
|
||||
if ((ss >> code).fail()) {
|
||||
throw exception("Unable to parse response code",status_code::bad_request);
|
||||
}
|
||||
|
||||
set_status(status_code::value(code),std::string(cursor_end+1,end));
|
||||
}
|
||||
|
||||
inline size_t response::process_body(char const * buf, size_t len) {
|
||||
// If no content length was set then we read forever and never set m_ready
|
||||
if (m_read == 0) {
|
||||
//m_body.append(buf,len);
|
||||
//return len;
|
||||
m_state = DONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Otherwise m_read is the number of bytes left.
|
||||
size_t to_read;
|
||||
|
||||
if (len >= m_read) {
|
||||
// if we have more bytes than we need read, read only the amount needed
|
||||
// then set done state
|
||||
to_read = m_read;
|
||||
m_state = DONE;
|
||||
} else {
|
||||
// we need more bytes than are available, read them all
|
||||
to_read = len;
|
||||
}
|
||||
|
||||
m_body.append(buf,to_read);
|
||||
m_read -= to_read;
|
||||
return to_read;
|
||||
}
|
||||
|
||||
} // namespace parser
|
||||
} // namespace http
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // HTTP_PARSER_RESPONSE_IMPL_HPP
|
||||
629
module/Vendor/WebSocketPP/websocketpp/http/parser.hpp
vendored
Normal file
629
module/Vendor/WebSocketPP/websocketpp/http/parser.hpp
vendored
Normal file
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
* 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 HTTP_PARSER_HPP
|
||||
#define HTTP_PARSER_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <websocketpp/utilities.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
namespace state {
|
||||
enum value {
|
||||
method,
|
||||
resource,
|
||||
version,
|
||||
headers
|
||||
};
|
||||
}
|
||||
|
||||
namespace body_encoding {
|
||||
enum value {
|
||||
unknown,
|
||||
plain,
|
||||
chunked
|
||||
};
|
||||
}
|
||||
|
||||
typedef std::map<std::string, std::string, utility::ci_less > header_list;
|
||||
|
||||
/// Read and return the next token in the stream
|
||||
/**
|
||||
* Read until a non-token character is found and then return the token and
|
||||
* iterator to the next character to read
|
||||
*
|
||||
* @param begin An iterator to the beginning of the sequence
|
||||
* @param end An iterator to the end of the sequence
|
||||
* @return A pair containing the token and an iterator to the next character in
|
||||
* the stream
|
||||
*/
|
||||
template <typename InputIterator>
|
||||
std::pair<std::string,InputIterator> extract_token(InputIterator begin,
|
||||
InputIterator end)
|
||||
{
|
||||
InputIterator it = std::find_if(begin,end,&is_not_token_char);
|
||||
return std::make_pair(std::string(begin,it),it);
|
||||
}
|
||||
|
||||
/// Read and return the next quoted string in the stream
|
||||
/**
|
||||
* Read a double quoted string starting at `begin`. The quotes themselves are
|
||||
* stripped. The quoted value is returned along with an iterator to the next
|
||||
* character to read
|
||||
*
|
||||
* @param begin An iterator to the beginning of the sequence
|
||||
* @param end An iterator to the end of the sequence
|
||||
* @return A pair containing the string read and an iterator to the next
|
||||
* character in the stream
|
||||
*/
|
||||
template <typename InputIterator>
|
||||
std::pair<std::string,InputIterator> extract_quoted_string(InputIterator begin,
|
||||
InputIterator end)
|
||||
{
|
||||
std::string s;
|
||||
|
||||
if (end == begin) {
|
||||
return std::make_pair(s,begin);
|
||||
}
|
||||
|
||||
if (*begin != '"') {
|
||||
return std::make_pair(s,begin);
|
||||
}
|
||||
|
||||
InputIterator cursor = begin+1;
|
||||
InputIterator marker = cursor;
|
||||
|
||||
cursor = std::find(cursor,end,'"');
|
||||
|
||||
while (cursor != end) {
|
||||
// either this is the end or a quoted string
|
||||
if (*(cursor-1) == '\\') {
|
||||
s.append(marker,cursor-1);
|
||||
s.append(1,'"');
|
||||
++cursor;
|
||||
marker = cursor;
|
||||
} else {
|
||||
s.append(marker,cursor);
|
||||
++cursor;
|
||||
return std::make_pair(s,cursor);
|
||||
}
|
||||
|
||||
cursor = std::find(cursor,end,'"');
|
||||
}
|
||||
|
||||
return std::make_pair("",begin);
|
||||
}
|
||||
|
||||
/// Read and discard one unit of linear whitespace
|
||||
/**
|
||||
* Read one unit of linear white space and return the iterator to the character
|
||||
* afterwards. If `begin` is returned, no whitespace was extracted.
|
||||
*
|
||||
* @param begin An iterator to the beginning of the sequence
|
||||
* @param end An iterator to the end of the sequence
|
||||
* @return An iterator to the character after the linear whitespace read
|
||||
*/
|
||||
template <typename InputIterator>
|
||||
InputIterator extract_lws(InputIterator begin, InputIterator end) {
|
||||
InputIterator it = begin;
|
||||
|
||||
// strip leading CRLF
|
||||
if (end-begin > 2 && *begin == '\r' && *(begin+1) == '\n' &&
|
||||
is_whitespace_char(static_cast<unsigned char>(*(begin+2))))
|
||||
{
|
||||
it+=3;
|
||||
}
|
||||
|
||||
it = std::find_if(it,end,&is_not_whitespace_char);
|
||||
return it;
|
||||
}
|
||||
|
||||
/// Read and discard linear whitespace
|
||||
/**
|
||||
* Read linear white space until a non-lws character is read and return an
|
||||
* iterator to that character. If `begin` is returned, no whitespace was
|
||||
* extracted.
|
||||
*
|
||||
* @param begin An iterator to the beginning of the sequence
|
||||
* @param end An iterator to the end of the sequence
|
||||
* @return An iterator to the character after the linear whitespace read
|
||||
*/
|
||||
template <typename InputIterator>
|
||||
InputIterator extract_all_lws(InputIterator begin, InputIterator end) {
|
||||
InputIterator old_it;
|
||||
InputIterator new_it = begin;
|
||||
|
||||
do {
|
||||
// Pull value from previous iteration
|
||||
old_it = new_it;
|
||||
|
||||
// look ahead another pass
|
||||
new_it = extract_lws(old_it,end);
|
||||
} while (new_it != end && old_it != new_it);
|
||||
|
||||
return new_it;
|
||||
}
|
||||
|
||||
/// Extract HTTP attributes
|
||||
/**
|
||||
* An http attributes list is a semicolon delimited list of key value pairs in
|
||||
* the format: *( ";" attribute "=" value ) where attribute is a token and value
|
||||
* is a token or quoted string.
|
||||
*
|
||||
* Attributes extracted are appended to the supplied attributes list
|
||||
* `attributes`.
|
||||
*
|
||||
* @param [in] begin An iterator to the beginning of the sequence
|
||||
* @param [in] end An iterator to the end of the sequence
|
||||
* @param [out] attributes A reference to the attributes list to append
|
||||
* attribute/value pairs extracted to
|
||||
* @return An iterator to the character after the last atribute read
|
||||
*/
|
||||
template <typename InputIterator>
|
||||
InputIterator extract_attributes(InputIterator begin, InputIterator end,
|
||||
attribute_list & attributes)
|
||||
{
|
||||
InputIterator cursor;
|
||||
bool first = true;
|
||||
|
||||
if (begin == end) {
|
||||
return begin;
|
||||
}
|
||||
|
||||
cursor = begin;
|
||||
std::pair<std::string,InputIterator> ret;
|
||||
|
||||
while (cursor != end) {
|
||||
std::string name;
|
||||
|
||||
cursor = http::parser::extract_all_lws(cursor,end);
|
||||
if (cursor == end) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
// ignore this check for the very first pass
|
||||
first = false;
|
||||
} else {
|
||||
if (*cursor == ';') {
|
||||
// advance past the ';'
|
||||
++cursor;
|
||||
} else {
|
||||
// non-semicolon in this position indicates end end of the
|
||||
// attribute list, break and return.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cursor = http::parser::extract_all_lws(cursor,end);
|
||||
ret = http::parser::extract_token(cursor,end);
|
||||
|
||||
if (ret.first.empty()) {
|
||||
// error: expected a token
|
||||
return begin;
|
||||
} else {
|
||||
name = ret.first;
|
||||
cursor = ret.second;
|
||||
}
|
||||
|
||||
cursor = http::parser::extract_all_lws(cursor,end);
|
||||
if (cursor == end || *cursor != '=') {
|
||||
// if there is an equals sign, read the attribute value. Otherwise
|
||||
// record a blank value and continue
|
||||
attributes[name].clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
// advance past the '='
|
||||
++cursor;
|
||||
|
||||
cursor = http::parser::extract_all_lws(cursor,end);
|
||||
if (cursor == end) {
|
||||
// error: expected a token or quoted string
|
||||
return begin;
|
||||
}
|
||||
|
||||
ret = http::parser::extract_quoted_string(cursor,end);
|
||||
if (ret.second != cursor) {
|
||||
attributes[name] = ret.first;
|
||||
cursor = ret.second;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = http::parser::extract_token(cursor,end);
|
||||
if (ret.first.empty()) {
|
||||
// error : expected token or quoted string
|
||||
return begin;
|
||||
} else {
|
||||
attributes[name] = ret.first;
|
||||
cursor = ret.second;
|
||||
}
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/// Extract HTTP parameters
|
||||
/**
|
||||
* An http parameters list is a comma delimited list of tokens followed by
|
||||
* optional semicolon delimited attributes lists.
|
||||
*
|
||||
* Parameters extracted are appended to the supplied parameters list
|
||||
* `parameters`.
|
||||
*
|
||||
* @param [in] begin An iterator to the beginning of the sequence
|
||||
* @param [in] end An iterator to the end of the sequence
|
||||
* @param [out] parameters A reference to the parameters list to append
|
||||
* paramter values extracted to
|
||||
* @return An iterator to the character after the last parameter read
|
||||
*/
|
||||
template <typename InputIterator>
|
||||
InputIterator extract_parameters(InputIterator begin, InputIterator end,
|
||||
parameter_list ¶meters)
|
||||
{
|
||||
InputIterator cursor;
|
||||
|
||||
if (begin == end) {
|
||||
// error: expected non-zero length range
|
||||
return begin;
|
||||
}
|
||||
|
||||
cursor = begin;
|
||||
std::pair<std::string,InputIterator> ret;
|
||||
|
||||
/**
|
||||
* LWS
|
||||
* token
|
||||
* LWS
|
||||
* *(";" method-param)
|
||||
* LWS
|
||||
* ,=loop again
|
||||
*/
|
||||
while (cursor != end) {
|
||||
std::string parameter_name;
|
||||
attribute_list attributes;
|
||||
|
||||
// extract any stray whitespace
|
||||
cursor = http::parser::extract_all_lws(cursor,end);
|
||||
if (cursor == end) {break;}
|
||||
|
||||
ret = http::parser::extract_token(cursor,end);
|
||||
|
||||
if (ret.first.empty()) {
|
||||
// error: expected a token
|
||||
return begin;
|
||||
} else {
|
||||
parameter_name = ret.first;
|
||||
cursor = ret.second;
|
||||
}
|
||||
|
||||
// Safe break point, insert parameter with blank attributes and exit
|
||||
cursor = http::parser::extract_all_lws(cursor,end);
|
||||
if (cursor == end) {
|
||||
//parameters[parameter_name] = attributes;
|
||||
parameters.push_back(std::make_pair(parameter_name,attributes));
|
||||
break;
|
||||
}
|
||||
|
||||
// If there is an attribute list, read it in
|
||||
if (*cursor == ';') {
|
||||
InputIterator acursor;
|
||||
|
||||
++cursor;
|
||||
acursor = http::parser::extract_attributes(cursor,end,attributes);
|
||||
|
||||
if (acursor == cursor) {
|
||||
// attribute extraction ended in syntax error
|
||||
return begin;
|
||||
}
|
||||
|
||||
cursor = acursor;
|
||||
}
|
||||
|
||||
// insert parameter into output list
|
||||
//parameters[parameter_name] = attributes;
|
||||
parameters.push_back(std::make_pair(parameter_name,attributes));
|
||||
|
||||
cursor = http::parser::extract_all_lws(cursor,end);
|
||||
if (cursor == end) {break;}
|
||||
|
||||
// if next char is ',' then read another parameter, else stop
|
||||
if (*cursor != ',') {
|
||||
break;
|
||||
}
|
||||
|
||||
// advance past comma
|
||||
++cursor;
|
||||
|
||||
if (cursor == end) {
|
||||
// expected more bytes after a comma
|
||||
return begin;
|
||||
}
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
inline std::string strip_lws(std::string const & input) {
|
||||
std::string::const_iterator begin = extract_all_lws(input.begin(),input.end());
|
||||
if (begin == input.end()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string::const_reverse_iterator rbegin = extract_all_lws(input.rbegin(),input.rend());
|
||||
if (rbegin == input.rend()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return std::string(begin,rbegin.base());
|
||||
}
|
||||
|
||||
/// Base HTTP parser
|
||||
/**
|
||||
* Includes methods and data elements common to all types of HTTP messages such
|
||||
* as headers, versions, bodies, etc.
|
||||
*/
|
||||
class parser {
|
||||
public:
|
||||
parser()
|
||||
: m_header_bytes(0)
|
||||
, m_body_bytes_needed(0)
|
||||
, m_body_bytes_max(max_body_size)
|
||||
, m_body_encoding(body_encoding::unknown) {}
|
||||
|
||||
/// Get the HTTP version string
|
||||
/**
|
||||
* @return The version string for this parser
|
||||
*/
|
||||
std::string const & get_version() const {
|
||||
return m_version;
|
||||
}
|
||||
|
||||
/// Set HTTP parser Version
|
||||
/**
|
||||
* Input should be in format: HTTP/x.y where x and y are positive integers.
|
||||
* @todo Does this method need any validation?
|
||||
*
|
||||
* @param [in] version The value to set the HTTP version to.
|
||||
*/
|
||||
void set_version(std::string const & version);
|
||||
|
||||
/// Get the value of an HTTP header
|
||||
/**
|
||||
* @todo Make this method case insensitive.
|
||||
*
|
||||
* @param [in] key The name/key of the header to get.
|
||||
* @return The value associated with the given HTTP header key.
|
||||
*/
|
||||
std::string const & get_header(std::string const & key) const;
|
||||
|
||||
/// Extract an HTTP parameter list from a parser header.
|
||||
/**
|
||||
* If the header requested doesn't exist or exists and is empty the
|
||||
* parameter list is valid (but empty).
|
||||
*
|
||||
* @param [in] key The name/key of the HTTP header to use as input.
|
||||
* @param [out] out The parameter list to store extracted parameters in.
|
||||
* @return Whether or not the input was a valid parameter list.
|
||||
*/
|
||||
bool get_header_as_plist(std::string const & key, parameter_list & out)
|
||||
const;
|
||||
|
||||
/// Return a list of all HTTP headers
|
||||
/**
|
||||
* Return a list of all HTTP headers
|
||||
*
|
||||
* @since 0.8.0
|
||||
*
|
||||
* @return A list of all HTTP headers
|
||||
*/
|
||||
header_list const & get_headers() const;
|
||||
|
||||
/// Append a value to an existing HTTP header
|
||||
/**
|
||||
* This method will set the value of the HTTP header `key` with the
|
||||
* indicated value. If a header with the name `key` already exists, `val`
|
||||
* will be appended to the existing value.
|
||||
*
|
||||
* @todo Make this method case insensitive.
|
||||
* @todo Should there be any restrictions on which keys are allowed?
|
||||
* @todo Exception free varient
|
||||
*
|
||||
* @see replace_header
|
||||
*
|
||||
* @param [in] key The name/key of the header to append to.
|
||||
* @param [in] val The value to append.
|
||||
*/
|
||||
void append_header(std::string const & key, std::string const & val);
|
||||
|
||||
/// Set a value for an HTTP header, replacing an existing value
|
||||
/**
|
||||
* This method will set the value of the HTTP header `key` with the
|
||||
* indicated value. If a header with the name `key` already exists, `val`
|
||||
* will replace the existing value.
|
||||
*
|
||||
* @todo Make this method case insensitive.
|
||||
* @todo Should there be any restrictions on which keys are allowed?
|
||||
* @todo Exception free varient
|
||||
*
|
||||
* @see append_header
|
||||
*
|
||||
* @param [in] key The name/key of the header to append to.
|
||||
* @param [in] val The value to append.
|
||||
*/
|
||||
void replace_header(std::string const & key, std::string const & val);
|
||||
|
||||
/// Remove a header from the parser
|
||||
/**
|
||||
* Removes the header entirely from the parser. This is different than
|
||||
* setting the value of the header to blank.
|
||||
*
|
||||
* @todo Make this method case insensitive.
|
||||
*
|
||||
* @param [in] key The name/key of the header to remove.
|
||||
*/
|
||||
void remove_header(std::string const & key);
|
||||
|
||||
/// Get HTTP body
|
||||
/**
|
||||
* Gets the body of the HTTP object
|
||||
*
|
||||
* @return The body of the HTTP message.
|
||||
*/
|
||||
std::string const & get_body() const {
|
||||
return m_body;
|
||||
}
|
||||
|
||||
/// Set body content
|
||||
/**
|
||||
* Set the body content of the HTTP response to the parameter string. Note
|
||||
* set_body will also set the Content-Length HTTP header to the appropriate
|
||||
* value. If you want the Content-Length header to be something else, do so
|
||||
* via replace_header("Content-Length") after calling set_body()
|
||||
*
|
||||
* @param value String data to include as the body content.
|
||||
*/
|
||||
void set_body(std::string const & value);
|
||||
|
||||
/// Get body size limit
|
||||
/**
|
||||
* Retrieves the maximum number of bytes to parse & buffer before canceling
|
||||
* a request.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @return The maximum length of a message body.
|
||||
*/
|
||||
size_t get_max_body_size() const {
|
||||
return m_body_bytes_max;
|
||||
}
|
||||
|
||||
/// Set body size limit
|
||||
/**
|
||||
* Set the maximum number of bytes to parse and buffer before canceling a
|
||||
* request.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @param value The size to set the max body length to.
|
||||
*/
|
||||
void set_max_body_size(size_t value) {
|
||||
m_body_bytes_max = value;
|
||||
}
|
||||
|
||||
/// Extract an HTTP parameter list from a string.
|
||||
/**
|
||||
* @param [in] in The input string.
|
||||
* @param [out] out The parameter list to store extracted parameters in.
|
||||
* @return Whether or not the input was a valid parameter list.
|
||||
*/
|
||||
bool parse_parameter_list(std::string const & in, parameter_list & out)
|
||||
const;
|
||||
protected:
|
||||
/// Process a header line
|
||||
/**
|
||||
* @todo Update this method to be exception free.
|
||||
*
|
||||
* @param [in] begin An iterator to the beginning of the sequence.
|
||||
* @param [in] end An iterator to the end of the sequence.
|
||||
*/
|
||||
void process_header(std::string::iterator begin, std::string::iterator end);
|
||||
|
||||
/// Prepare the parser to begin parsing body data
|
||||
/**
|
||||
* Inspects headers to determine if the message has a body that needs to be
|
||||
* read. If so, sets up the necessary state, otherwise returns false. If
|
||||
* this method returns true and loading the message body is desired call
|
||||
* `process_body` until it returns zero bytes or an error.
|
||||
*
|
||||
* Must not be called until after all headers have been processed.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @return True if more bytes are needed to load the body, false otherwise.
|
||||
*/
|
||||
bool prepare_body();
|
||||
|
||||
/// Process body data
|
||||
/**
|
||||
* Parses body data.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @param [in] begin An iterator to the beginning of the sequence.
|
||||
* @param [in] end An iterator to the end of the sequence.
|
||||
* @return The number of bytes processed
|
||||
*/
|
||||
size_t process_body(char const * buf, size_t len);
|
||||
|
||||
/// Check if the parser is done parsing the body
|
||||
/**
|
||||
* Behavior before a call to `prepare_body` is undefined.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @return True if the message body has been completed loaded.
|
||||
*/
|
||||
bool body_ready() const {
|
||||
return (m_body_bytes_needed == 0);
|
||||
}
|
||||
|
||||
/// Generate and return the HTTP headers as a string
|
||||
/**
|
||||
* Each headers will be followed by the \r\n sequence including the last one.
|
||||
* A second \r\n sequence (blank header) is not appended by this method
|
||||
*
|
||||
* @return The HTTP headers as a string.
|
||||
*/
|
||||
std::string raw_headers() const;
|
||||
|
||||
std::string m_version;
|
||||
header_list m_headers;
|
||||
|
||||
size_t m_header_bytes;
|
||||
|
||||
std::string m_body;
|
||||
size_t m_body_bytes_needed;
|
||||
size_t m_body_bytes_max;
|
||||
body_encoding::value m_body_encoding;
|
||||
};
|
||||
|
||||
} // namespace parser
|
||||
} // namespace http
|
||||
} // namespace websocketpp
|
||||
|
||||
#include <websocketpp/http/impl/parser.hpp>
|
||||
|
||||
#endif // HTTP_PARSER_HPP
|
||||
124
module/Vendor/WebSocketPP/websocketpp/http/request.hpp
vendored
Normal file
124
module/Vendor/WebSocketPP/websocketpp/http/request.hpp
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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 HTTP_PARSER_REQUEST_HPP
|
||||
#define HTTP_PARSER_REQUEST_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
/// Stores, parses, and manipulates HTTP requests
|
||||
/**
|
||||
* http::request provides the following functionality for working with HTTP
|
||||
* requests.
|
||||
*
|
||||
* - Initialize request via manually setting each element
|
||||
* - Initialize request via reading raw bytes and parsing
|
||||
* - Once initialized, access individual parsed elements
|
||||
* - Once initialized, read entire request as raw bytes
|
||||
*/
|
||||
class request : public parser {
|
||||
public:
|
||||
typedef request type;
|
||||
typedef lib::shared_ptr<type> ptr;
|
||||
|
||||
request()
|
||||
: m_buf(lib::make_shared<std::string>())
|
||||
, m_ready(false) {}
|
||||
|
||||
/// Process bytes in the input buffer
|
||||
/**
|
||||
* Process up to len bytes from input buffer buf. Returns the number of
|
||||
* bytes processed. Bytes left unprocessed means bytes left over after the
|
||||
* final header delimiters.
|
||||
*
|
||||
* Consume is a streaming processor. It may be called multiple times on one
|
||||
* request and the full headers need not be available before processing can
|
||||
* begin. If the end of the request was reached during this call to consume
|
||||
* the ready flag will be set. Further calls to consume once ready will be
|
||||
* ignored.
|
||||
*
|
||||
* Consume will throw an http::exception in the case of an error. Typical
|
||||
* error reasons include malformed requests, incomplete requests, and max
|
||||
* header size being reached.
|
||||
*
|
||||
* @param buf Pointer to byte buffer
|
||||
* @param len Size of byte buffer
|
||||
* @return Number of bytes processed.
|
||||
*/
|
||||
size_t consume(char const * buf, size_t len);
|
||||
|
||||
/// Returns whether or not the request is ready for reading.
|
||||
bool ready() const {
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
/// Returns the full raw request (including the body)
|
||||
std::string raw() const;
|
||||
|
||||
/// Returns the raw request headers only (similar to an HTTP HEAD request)
|
||||
std::string raw_head() const;
|
||||
|
||||
/// Set the HTTP method. Must be a valid HTTP token
|
||||
void set_method(std::string const & method);
|
||||
|
||||
/// Return the request method
|
||||
std::string const & get_method() const {
|
||||
return m_method;
|
||||
}
|
||||
|
||||
/// Set the HTTP uri. Must be a valid HTTP uri
|
||||
void set_uri(std::string const & uri);
|
||||
|
||||
/// Return the requested URI
|
||||
std::string const & get_uri() const {
|
||||
return m_uri;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Helper function for message::consume. Process request line
|
||||
void process(std::string::iterator begin, std::string::iterator end);
|
||||
|
||||
lib::shared_ptr<std::string> m_buf;
|
||||
std::string m_method;
|
||||
std::string m_uri;
|
||||
bool m_ready;
|
||||
};
|
||||
|
||||
} // namespace parser
|
||||
} // namespace http
|
||||
} // namespace websocketpp
|
||||
|
||||
#include <websocketpp/http/impl/request.hpp>
|
||||
|
||||
#endif // HTTP_PARSER_REQUEST_HPP
|
||||
188
module/Vendor/WebSocketPP/websocketpp/http/response.hpp
vendored
Normal file
188
module/Vendor/WebSocketPP/websocketpp/http/response.hpp
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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 HTTP_PARSER_RESPONSE_HPP
|
||||
#define HTTP_PARSER_RESPONSE_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
/// Stores, parses, and manipulates HTTP responses
|
||||
/**
|
||||
* http::response provides the following functionality for working with HTTP
|
||||
* responses.
|
||||
*
|
||||
* - Initialize response via manually setting each element
|
||||
* - Initialize response via reading raw bytes and parsing
|
||||
* - Once initialized, access individual parsed elements
|
||||
* - Once initialized, read entire response as raw bytes
|
||||
*
|
||||
* http::response checks for header completeness separately from the full
|
||||
* response. Once the header is complete, the Content-Length header is read to
|
||||
* determine when to stop reading body bytes. If no Content-Length is present
|
||||
* ready() will never return true. It is the responsibility of the caller to
|
||||
* consume to determine when the response is complete (ie when the connection
|
||||
* terminates, or some other metric).
|
||||
*/
|
||||
class response : public parser {
|
||||
public:
|
||||
typedef response type;
|
||||
typedef lib::shared_ptr<type> ptr;
|
||||
|
||||
response()
|
||||
: m_read(0)
|
||||
, m_buf(lib::make_shared<std::string>())
|
||||
, m_status_code(status_code::uninitialized)
|
||||
, m_state(RESPONSE_LINE) {}
|
||||
|
||||
/// Process bytes in the input buffer
|
||||
/**
|
||||
* Process up to len bytes from input buffer buf. Returns the number of
|
||||
* bytes processed. Bytes left unprocessed means bytes left over after the
|
||||
* final header delimiters.
|
||||
*
|
||||
* Consume is a streaming processor. It may be called multiple times on one
|
||||
* response and the full headers need not be available before processing can
|
||||
* begin. If the end of the response was reached during this call to consume
|
||||
* the ready flag will be set. Further calls to consume once ready will be
|
||||
* ignored.
|
||||
*
|
||||
* Consume will throw an http::exception in the case of an error. Typical
|
||||
* error reasons include malformed responses, incomplete responses, and max
|
||||
* header size being reached.
|
||||
*
|
||||
* @param buf Pointer to byte buffer
|
||||
* @param len Size of byte buffer
|
||||
* @return Number of bytes processed.
|
||||
*/
|
||||
size_t consume(char const * buf, size_t len);
|
||||
|
||||
/// Process bytes in the input buffer (istream version)
|
||||
/**
|
||||
* Process bytes from istream s. Returns the number of bytes processed.
|
||||
* Bytes left unprocessed means bytes left over after the final header
|
||||
* delimiters.
|
||||
*
|
||||
* Consume is a streaming processor. It may be called multiple times on one
|
||||
* response and the full headers need not be available before processing can
|
||||
* begin. If the end of the response was reached during this call to consume
|
||||
* the ready flag will be set. Further calls to consume once ready will be
|
||||
* ignored.
|
||||
*
|
||||
* Consume will throw an http::exception in the case of an error. Typical
|
||||
* error reasons include malformed responses, incomplete responses, and max
|
||||
* header size being reached.
|
||||
*
|
||||
* @param buf Pointer to byte buffer
|
||||
* @param len Size of byte buffer
|
||||
* @return Number of bytes processed.
|
||||
*/
|
||||
size_t consume(std::istream & s);
|
||||
|
||||
/// Returns true if the response is ready.
|
||||
/**
|
||||
* @note will never return true if the content length header is not present
|
||||
*/
|
||||
bool ready() const {
|
||||
return m_state == DONE;
|
||||
}
|
||||
|
||||
/// Returns true if the response headers are fully parsed.
|
||||
bool headers_ready() const {
|
||||
return (m_state == BODY || m_state == DONE);
|
||||
}
|
||||
|
||||
/// Returns the full raw response
|
||||
std::string raw() const;
|
||||
|
||||
/// Set response status code and message
|
||||
/**
|
||||
* Sets the response status code to `code` and looks up the corresponding
|
||||
* message for standard codes. Non-standard codes will be entered as Unknown
|
||||
* use set_status(status_code::value,std::string) overload to set both
|
||||
* values explicitly.
|
||||
*
|
||||
* @param code Code to set
|
||||
* @param msg Message to set
|
||||
*/
|
||||
void set_status(status_code::value code);
|
||||
|
||||
/// Set response status code and message
|
||||
/**
|
||||
* Sets the response status code and message to independent custom values.
|
||||
* use set_status(status_code::value) to set the code and have the standard
|
||||
* message be automatically set.
|
||||
*
|
||||
* @param code Code to set
|
||||
* @param msg Message to set
|
||||
*/
|
||||
void set_status(status_code::value code, std::string const & msg);
|
||||
|
||||
/// Return the response status code
|
||||
status_code::value get_status_code() const {
|
||||
return m_status_code;
|
||||
}
|
||||
|
||||
/// Return the response status message
|
||||
const std::string& get_status_msg() const {
|
||||
return m_status_msg;
|
||||
}
|
||||
private:
|
||||
/// Helper function for consume. Process response line
|
||||
void process(std::string::iterator begin, std::string::iterator end);
|
||||
|
||||
/// Helper function for processing body bytes
|
||||
size_t process_body(char const * buf, size_t len);
|
||||
|
||||
enum state {
|
||||
RESPONSE_LINE = 0,
|
||||
HEADERS = 1,
|
||||
BODY = 2,
|
||||
DONE = 3
|
||||
};
|
||||
|
||||
std::string m_status_msg;
|
||||
size_t m_read;
|
||||
lib::shared_ptr<std::string> m_buf;
|
||||
status_code::value m_status_code;
|
||||
state m_state;
|
||||
|
||||
};
|
||||
|
||||
} // namespace parser
|
||||
} // namespace http
|
||||
} // namespace websocketpp
|
||||
|
||||
#include <websocketpp/http/impl/response.hpp>
|
||||
|
||||
#endif // HTTP_PARSER_RESPONSE_HPP
|
||||
Reference in New Issue
Block a user