Moving enums to enum classes
This commit is contained in:
parent
277a74430c
commit
32767786af
@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
cmake_minimum_required(VERSION 3.9)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
project(frnetlib)
|
||||
set(FRNETLIB_LINK_LIBRARIES "")
|
||||
|
||||
@ -6,7 +7,7 @@ set(FRNETLIB_LINK_LIBRARIES "")
|
||||
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules)
|
||||
|
||||
#User options
|
||||
option(USE_SSL "Enable SSL support" OFF)
|
||||
option(USE_SSL "Enable SSL support" ON)
|
||||
option(BUILD_EXAMPLES "Build frnetlib examples" ON)
|
||||
option(BUILD_TESTS "Build frnetlib tests" ON)
|
||||
option(BUILD_WEBSOCK "Enable WebSocket support" ON)
|
||||
|
||||
@ -32,7 +32,7 @@ int main()
|
||||
//port multiple times. Each thread should have its own fr::SocketSelector, this will
|
||||
//spread connections over multiple workers.
|
||||
auto listener = std::make_shared<fr::TcpListener>();
|
||||
if(listener->listen("8080") != fr::Socket::Success)
|
||||
if(listener->listen("8080") != fr::Socket::Status::Success)
|
||||
{
|
||||
std::cerr << "Failed to bind to port" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
@ -53,7 +53,7 @@ int main()
|
||||
if(ready_socket.first->get_socket_descriptor() == listener->get_socket_descriptor())
|
||||
{
|
||||
auto client = std::make_shared<fr::TcpSocket>(); //Or fr::SSLSocket
|
||||
if(listener->accept(*client) == fr::Socket::Success)
|
||||
if(listener->accept(*client) == fr::Socket::Status::Success)
|
||||
{
|
||||
client->set_blocking(false); //This is important
|
||||
listen_loop_selector.add(client, new SessionState()); //We assign a 'SessionState' object for each connection as opaque data
|
||||
@ -69,23 +69,23 @@ int main()
|
||||
char data[0x1000];
|
||||
size_t received = 0;
|
||||
auto recv_status = client->receive_raw(data, sizeof(data), received);
|
||||
if(recv_status == fr::Socket::Success)
|
||||
if(recv_status == fr::Socket::Status::Success)
|
||||
{
|
||||
//We received data, so parse it using the partial HTTP request associated with this connection
|
||||
auto parse_status = session->partial_request.parse(data, received);
|
||||
if(parse_status == fr::Socket::Success)
|
||||
if(parse_status == fr::Socket::Status::Success)
|
||||
{
|
||||
//The client has sent a full request, queue it for processing
|
||||
process_complete_request(client, std::move(session->partial_request));
|
||||
session->partial_request = fr::HttpRequest();
|
||||
}
|
||||
else if(parse_status != fr::Socket::NotEnoughData)
|
||||
else if(parse_status != fr::Socket::Status::NotEnoughData)
|
||||
{
|
||||
//HTTP error, disconnect the client. Remove from socket selector, and delete opaque data.
|
||||
delete (SessionState*)listen_loop_selector.remove(client);
|
||||
}
|
||||
}
|
||||
else if(recv_status != fr::Socket::WouldBlock)
|
||||
else if(recv_status != fr::Socket::Status::WouldBlock)
|
||||
{
|
||||
//Error, disconnect it. Remove from socket selector, and delete opaque data.
|
||||
delete (SessionState*)listen_loop_selector.remove(client);
|
||||
|
||||
@ -29,7 +29,7 @@ int main()
|
||||
fr::TcpListener listener;
|
||||
|
||||
//Try to connect to the parsed address
|
||||
if((err = socket.connect(parsed_url.get_host(), parsed_url.get_port(), {})) != fr::Socket::Success)
|
||||
if((err = socket.connect(parsed_url.get_host(), parsed_url.get_port(), {})) != fr::Socket::Status::Success)
|
||||
{
|
||||
std::cerr << "Failed to connect to the specified URL: " << fr::Socket::status_to_string(err) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
@ -38,7 +38,7 @@ int main()
|
||||
//Construct a request, requesting the user provided URI
|
||||
fr::HttpRequest request;
|
||||
request.set_uri(parsed_url.get_uri());
|
||||
if((err = socket.send(request)) != fr::Socket::Success)
|
||||
if((err = socket.send(request)) != fr::Socket::Status::Success)
|
||||
{
|
||||
std::cerr << "Failed to send HTTP request: " + fr::Socket::status_to_string(err) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
@ -46,7 +46,7 @@ int main()
|
||||
|
||||
//Now wait for a response
|
||||
fr::HttpResponse response;
|
||||
if(socket.receive(response) != fr::Socket::Success)
|
||||
if(socket.receive(response) != fr::Socket::Status::Success)
|
||||
{
|
||||
std::cerr << "Failed to receive HTTP response" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
|
||||
@ -15,13 +15,13 @@ namespace fr
|
||||
class Http : public Sendable
|
||||
{
|
||||
public:
|
||||
enum RequestVersion
|
||||
enum class RequestVersion
|
||||
{
|
||||
V1 = 1, // HTTP/1.0
|
||||
V1_1 = 2, // HTTP/1.1
|
||||
VersionCount = 3
|
||||
};
|
||||
enum RequestType
|
||||
enum class RequestType
|
||||
{
|
||||
Get = 0,
|
||||
Post = 1,
|
||||
@ -32,7 +32,7 @@ namespace fr
|
||||
Unknown = 6,
|
||||
Partial = 7,
|
||||
};
|
||||
enum RequestStatus
|
||||
enum class RequestStatus
|
||||
{
|
||||
Continue = 100,
|
||||
SwitchingProtocols = 101,
|
||||
@ -274,7 +274,19 @@ namespace fr
|
||||
* @param type The RequestType to convert
|
||||
* @return The printable version of the enum value
|
||||
*/
|
||||
static std::string request_type_to_string(RequestType type);
|
||||
static std::string request_type_to_string(RequestType type)
|
||||
{
|
||||
static_assert((uint32_t)RequestType::RequestTypeCount == 5, "Update request_type_to_string");
|
||||
const static std::string request_type_strings[(uint32_t)RequestType::RequestTypeCount] = {"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"PATCH"};
|
||||
|
||||
if(type >= RequestType::RequestTypeCount)
|
||||
return "UNKNOWN";
|
||||
return request_type_strings[(uint32_t)type];
|
||||
}
|
||||
|
||||
/*!
|
||||
* Converts a string value into a 'RequestType' enum value.
|
||||
@ -282,7 +294,26 @@ namespace fr
|
||||
* @param str The string to convert
|
||||
* @return The converted RequestType. Unknown on failure. Or Partial if str is part of a request type.
|
||||
*/
|
||||
static RequestType string_to_request_type(const std::string &str);
|
||||
static RequestType string_to_request_type(const std::string &str)
|
||||
{
|
||||
//Find the request type
|
||||
static_assert((uint32_t)Http::RequestType::RequestTypeCount == 5, "Update parse_header_type()");
|
||||
|
||||
RequestType type = Http::RequestType::Unknown;
|
||||
for(size_t a = 0; a < (uint32_t)Http::RequestType::RequestTypeCount; ++a)
|
||||
{
|
||||
std::string type_string = request_type_to_string(static_cast<RequestType>(a));
|
||||
int cmp_ret = str.compare(0, type_string.size(), type_string);
|
||||
if(cmp_ret == 0)
|
||||
return static_cast<RequestType>(a);
|
||||
if(str.size() < type_string.size() && cmp_ret < 0)
|
||||
type = Http::RequestType::Partial;
|
||||
if(type != Http::RequestType::Partial && str.size() < type_string.size() && cmp_ret > 0)
|
||||
type = Http::RequestType::Unknown;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
|
||||
@ -710,7 +710,7 @@ namespace fr
|
||||
do
|
||||
{
|
||||
state = socket->send_raw(&buffer[0], buffer.size(), sent);
|
||||
} while(state == fr::Socket::WouldBlock);
|
||||
} while(state == fr::Socket::Status::WouldBlock);
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -737,7 +737,7 @@ namespace fr
|
||||
|
||||
//Check that packet_length doesn't exceed the limit, if any
|
||||
if(socket->get_max_receive_size() && packet_length > socket->get_max_receive_size())
|
||||
return fr::Socket::MaxPacketSizeExceeded;
|
||||
return fr::Socket::Status::MaxPacketSizeExceeded;
|
||||
|
||||
//Now we've got the length, read the rest of the data in
|
||||
if(packet_length + PACKET_HEADER_LENGTH > buffer.size())
|
||||
@ -746,9 +746,9 @@ namespace fr
|
||||
do
|
||||
{
|
||||
status = socket->receive_all(&buffer[PACKET_HEADER_LENGTH], packet_length);
|
||||
} while(status == fr::Socket::WouldBlock);
|
||||
if(status == fr::Socket::Timeout)
|
||||
status = fr::Socket::Disconnected;
|
||||
} while(status == fr::Socket::Status::WouldBlock);
|
||||
if(status == fr::Socket::Status::Timeout)
|
||||
status = fr::Socket::Status::Disconnected;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@ -72,14 +72,14 @@ namespace fr
|
||||
*
|
||||
* @return True if connected, false otherwise
|
||||
*/
|
||||
bool connected() const noexcept override;
|
||||
bool connected() const override;
|
||||
|
||||
/*!
|
||||
* Gets the underlying socket descriptor.
|
||||
*
|
||||
* @return The socket descriptor.
|
||||
*/
|
||||
int32_t get_socket_descriptor() const noexcept override;
|
||||
int32_t get_socket_descriptor() const override;
|
||||
|
||||
private:
|
||||
mbedtls_net_context listen_fd;
|
||||
|
||||
@ -17,7 +17,7 @@ namespace fr
|
||||
class Socket : public SocketDescriptor
|
||||
{
|
||||
public:
|
||||
enum Status
|
||||
enum class Status
|
||||
{
|
||||
Unknown = 0,
|
||||
Success = 1,
|
||||
@ -44,7 +44,7 @@ namespace fr
|
||||
//Remember to update status_to_string if more are added
|
||||
};
|
||||
|
||||
enum IP
|
||||
enum class IP
|
||||
{
|
||||
v4 = 1,
|
||||
v6 = 2,
|
||||
@ -163,7 +163,7 @@ namespace fr
|
||||
* 'WouldBlock' or 'Timeout': No data received. Object still valid though.
|
||||
* Anything else: Object invalid. Call disconnect().
|
||||
*/
|
||||
Status receive_all(void *dest, size_t buffer_size);
|
||||
Socket::Status receive_all(void *dest, size_t buffer_size);
|
||||
|
||||
/*!
|
||||
* Calls the shutdown syscall on the socket.
|
||||
@ -278,9 +278,9 @@ namespace fr
|
||||
*
|
||||
* @return The string address
|
||||
*/
|
||||
inline const std::string &get_remote_address() const
|
||||
const std::string &get_remote_address() const
|
||||
{
|
||||
return remote_address;
|
||||
return fr_socket_remote_address;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -290,7 +290,7 @@ namespace fr
|
||||
*/
|
||||
inline void set_remote_address(const std::string &addr)
|
||||
{
|
||||
remote_address = addr;
|
||||
fr_socket_remote_address = addr;
|
||||
}
|
||||
protected:
|
||||
|
||||
@ -305,7 +305,7 @@ namespace fr
|
||||
*/
|
||||
virtual void reconfigure_socket()=0;
|
||||
|
||||
std::string remote_address;
|
||||
std::string fr_socket_remote_address;
|
||||
int ai_family;
|
||||
uint32_t max_receive_size;
|
||||
uint32_t socket_read_timeout;
|
||||
|
||||
@ -64,14 +64,14 @@ public:
|
||||
*
|
||||
* @return True if connected, false otherwise
|
||||
*/
|
||||
bool connected() const noexcept override;
|
||||
bool connected() const override;
|
||||
|
||||
/*!
|
||||
* Gets the underlying socket descriptor.
|
||||
*
|
||||
* @return The socket descriptor.
|
||||
*/
|
||||
int32_t get_socket_descriptor() const noexcept override;
|
||||
int32_t get_socket_descriptor() const override;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#define FRNETLIB_URLPARSER_H
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
|
||||
//Note, a URL looks like this: scheme:[//host[:port]][/path][?query][#fragment]
|
||||
namespace fr
|
||||
@ -39,7 +40,7 @@ namespace fr
|
||||
*
|
||||
* @param url The URL to parse
|
||||
*/
|
||||
void parse(std::string url);
|
||||
void parse(const std::string &url);
|
||||
|
||||
/*!
|
||||
* Get the URL scheme
|
||||
@ -141,7 +142,12 @@ namespace fr
|
||||
* @param str The string to convert
|
||||
* @return The converted string
|
||||
*/
|
||||
static std::string to_lower(const std::string &str);
|
||||
static std::string to_lower(const std::string &str)
|
||||
{
|
||||
std::string out = str;
|
||||
std::transform(out.begin(), out.end(), out.begin(), ::tolower);
|
||||
return out;
|
||||
}
|
||||
|
||||
//State
|
||||
Scheme scheme;
|
||||
|
||||
@ -14,7 +14,7 @@ namespace fr
|
||||
class WebFrame : public fr::Sendable
|
||||
{
|
||||
public:
|
||||
enum Opcode : uint8_t
|
||||
enum class Opcode : uint8_t
|
||||
{
|
||||
Continuation = 0,
|
||||
Text = 1,
|
||||
@ -29,7 +29,7 @@ namespace fr
|
||||
*
|
||||
* @param type The opcode type. See set_opcode. Text by default.
|
||||
*/
|
||||
explicit WebFrame(Opcode type = Text);
|
||||
explicit WebFrame(Opcode type = Opcode::Text);
|
||||
|
||||
/*!
|
||||
* Get's the receied payload data. (Data received).
|
||||
|
||||
@ -49,7 +49,7 @@ namespace fr
|
||||
{
|
||||
//Establish a connection using the parent class
|
||||
Socket::Status status = SocketType::connect(address, port, timeout);
|
||||
if(status != fr::Socket::Success)
|
||||
if(status != Socket::Status::Success)
|
||||
return status;
|
||||
|
||||
//Send an upgrade request header
|
||||
@ -60,19 +60,19 @@ namespace fr
|
||||
request.header("connection") = "upgrade";
|
||||
request.header("upgrade") = "websocket";
|
||||
status = SocketType::send(request);
|
||||
if(status != fr::Socket::Success)
|
||||
if(status != Socket::Status::Success)
|
||||
return status;
|
||||
|
||||
//Receive the response
|
||||
HttpResponse response;
|
||||
status = SocketType::receive(response);
|
||||
if(status != fr::Socket::Success)
|
||||
if(status != Socket::Status::Success)
|
||||
return status;
|
||||
if(response.get_status() != Http::SwitchingProtocols)
|
||||
if(response.get_status() != Http::RequestStatus::SwitchingProtocols)
|
||||
{
|
||||
disconnect();
|
||||
errno = EPROTO;
|
||||
return Socket::HandshakeFailed;
|
||||
return Socket::Status::HandshakeFailed;
|
||||
}
|
||||
|
||||
//Verify the sec-websocket-accept header
|
||||
@ -81,10 +81,10 @@ namespace fr
|
||||
{
|
||||
disconnect();
|
||||
errno = EPROTO;
|
||||
return Socket::HandshakeFailed;
|
||||
return Socket::Status::HandshakeFailed;
|
||||
}
|
||||
|
||||
return fr::Socket::Success;
|
||||
return Socket::Status::Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -94,7 +94,7 @@ namespace fr
|
||||
void disconnect() override
|
||||
{
|
||||
WebFrame frame;
|
||||
frame.set_opcode(WebFrame::Disconnect);
|
||||
frame.set_opcode(WebFrame::Opcode::Disconnect);
|
||||
if(SocketType::connected())
|
||||
SocketType::send(frame);
|
||||
SocketType::close_socket();
|
||||
@ -117,16 +117,16 @@ namespace fr
|
||||
|
||||
//Initialise connection, receive the handshake
|
||||
HttpRequest request;
|
||||
if(SocketType::receive(request) != fr::Socket::Success)
|
||||
if(SocketType::receive(request) != Socket::Status::Success)
|
||||
throw std::runtime_error("Failed to receive WebSock handshake");
|
||||
|
||||
if(request.header("Upgrade") != "websocket" || request.get_type() != fr::Http::Get)
|
||||
if(request.header("Upgrade") != "websocket" || request.get_type() != Http::RequestType::Get)
|
||||
throw std::runtime_error("Client isn't using the WebSock protocol");
|
||||
|
||||
//Calculate the derived key, then send back our response
|
||||
std::string derived_key = Base64::encode(Sha1::sha1_digest(request.header("sec-websocket-key") + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
|
||||
HttpResponse response;
|
||||
response.set_status(fr::Http::SwitchingProtocols);
|
||||
response.set_status(Http::RequestStatus::SwitchingProtocols);
|
||||
response.header("Upgrade") = "websocket";
|
||||
response.header("Connection") = "Upgrade";
|
||||
response.header("Sec-WebSocket-Accept") = derived_key;
|
||||
|
||||
52
src/Http.cpp
52
src/Http.cpp
@ -13,10 +13,10 @@
|
||||
namespace fr
|
||||
{
|
||||
Http::Http()
|
||||
: request_type(Unknown),
|
||||
: request_type(Http::RequestType::Unknown),
|
||||
uri("/"),
|
||||
status(Ok),
|
||||
version(V1_1)
|
||||
status(Http::RequestStatus::Ok),
|
||||
version(Http::RequestVersion::V1_1)
|
||||
{
|
||||
|
||||
}
|
||||
@ -115,42 +115,6 @@ namespace fr
|
||||
uri = '/' + str;
|
||||
}
|
||||
|
||||
std::string Http::request_type_to_string(RequestType type)
|
||||
{
|
||||
static_assert(RequestType::RequestTypeCount == 5, "Update request_type_to_string");
|
||||
const static std::string request_type_strings[RequestType::RequestTypeCount] = {"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"PATCH"};
|
||||
|
||||
if(type >= RequestType::RequestTypeCount)
|
||||
return "UNKNOWN";
|
||||
return request_type_strings[type];
|
||||
}
|
||||
|
||||
Http::RequestType Http::string_to_request_type(const std::string &str)
|
||||
{
|
||||
//Find the request type
|
||||
static_assert(Http::RequestTypeCount == 5, "Update parse_header_type()");
|
||||
|
||||
RequestType type = Http::Unknown;
|
||||
for(size_t a = 0; a < Http::RequestTypeCount; ++a)
|
||||
{
|
||||
std::string type_string = request_type_to_string(static_cast<RequestType>(a));
|
||||
int cmp_ret = str.compare(0, type_string.size(), type_string);
|
||||
if(cmp_ret == 0)
|
||||
return static_cast<RequestType>(a);
|
||||
if(str.size() < type_string.size() && cmp_ret < 0)
|
||||
type = Http::Partial;
|
||||
if(type != Http::Partial && str.size() < type_string.size() && cmp_ret > 0)
|
||||
type = Http::Unknown;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
void Http::set_type(Http::RequestType type)
|
||||
{
|
||||
request_type = type;
|
||||
@ -1001,7 +965,7 @@ namespace fr
|
||||
do
|
||||
{
|
||||
state = socket->send_raw(&data[0], data.size(), sent);
|
||||
} while(state == fr::Socket::WouldBlock);
|
||||
} while(state == fr::Socket::Status::WouldBlock);
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -1016,18 +980,18 @@ namespace fr
|
||||
//Receive the request
|
||||
auto status = socket->receive_raw(recv_buffer, RECV_CHUNK_SIZE, received);
|
||||
total_received += received;
|
||||
if(status != Socket::Success)
|
||||
if(status != Socket::Status::Success)
|
||||
{
|
||||
if(total_received == 0)
|
||||
return status;
|
||||
if(status == Socket::WouldBlock)
|
||||
if(status == Socket::Status::WouldBlock)
|
||||
continue;
|
||||
return Socket::Disconnected;
|
||||
return Socket::Status::Disconnected;
|
||||
}
|
||||
|
||||
//Parse it
|
||||
state = parse(recv_buffer, received);
|
||||
} while(state == fr::Socket::NotEnoughData);
|
||||
} while(state == fr::Socket::Status::NotEnoughData);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -22,8 +22,8 @@ namespace fr
|
||||
if(!header_ended)
|
||||
{
|
||||
//Verify that it's a valid HTTP header so far
|
||||
if(!body.empty() && Http::string_to_request_type(body) == fr::Http::Unknown)
|
||||
return fr::Socket::ParseError;
|
||||
if(!body.empty() && Http::string_to_request_type(body) == Http::RequestType::Unknown)
|
||||
return fr::Socket::Status::ParseError;
|
||||
|
||||
//Check to see if this request data contains the end of the header
|
||||
uint16_t header_end_size = 4;
|
||||
@ -38,16 +38,16 @@ namespace fr
|
||||
//Ensure that the header doesn't exceed max length
|
||||
if((!header_ended && body.size() > MAX_HTTP_HEADER_SIZE) || (header_ended && header_end > MAX_HTTP_HEADER_SIZE))
|
||||
{
|
||||
return fr::Socket::HttpHeaderTooBig;
|
||||
return fr::Socket::Status::HttpHeaderTooBig;
|
||||
}
|
||||
|
||||
//If the header end has not been found, ask for more data.
|
||||
if(!header_ended)
|
||||
return fr::Socket::NotEnoughData;
|
||||
return fr::Socket::Status::NotEnoughData;
|
||||
|
||||
//Else parse it
|
||||
if(!parse_header(header_end))
|
||||
return fr::Socket::ParseError;
|
||||
return fr::Socket::Status::ParseError;
|
||||
|
||||
//Leave things after the header intact
|
||||
body.erase(0, header_end + header_end_size);
|
||||
@ -56,7 +56,7 @@ namespace fr
|
||||
//Ensure that body doesn't exceed maximum length
|
||||
if(body.size() > MAX_HTTP_BODY_SIZE)
|
||||
{
|
||||
return fr::Socket::HttpBodyTooBig;
|
||||
return fr::Socket::Status::HttpBodyTooBig;
|
||||
}
|
||||
|
||||
//If we've got the whole request, parse the POST if it exists
|
||||
@ -64,10 +64,10 @@ namespace fr
|
||||
{
|
||||
if(request_type == RequestType::Post)
|
||||
parse_post_body();
|
||||
return fr::Socket::Success;
|
||||
return fr::Socket::Status::Success;
|
||||
}
|
||||
|
||||
return fr::Socket::NotEnoughData;
|
||||
return fr::Socket::Status::NotEnoughData;
|
||||
}
|
||||
|
||||
bool HttpRequest::parse_header(int64_t header_end_pos)
|
||||
@ -82,7 +82,7 @@ namespace fr
|
||||
|
||||
//Parse request type & uri
|
||||
request_type = parse_header_type(header_lines[line]);
|
||||
if(request_type > Http::RequestTypeCount)
|
||||
if(request_type > Http::RequestType::RequestTypeCount)
|
||||
return false;
|
||||
parse_header_uri(header_lines[line]);
|
||||
line++;
|
||||
@ -107,7 +107,7 @@ namespace fr
|
||||
std::string HttpRequest::construct(const std::string &host) const
|
||||
{
|
||||
//Add HTTP header
|
||||
std::string request = request_type_to_string(request_type == Http::Unknown ? Http::Get : request_type) + " " + uri;
|
||||
std::string request = request_type_to_string(request_type == Http::RequestType::Unknown ? Http::RequestType::Get : request_type) + " " + uri;
|
||||
if(!get_data.empty())
|
||||
{
|
||||
request += "?";
|
||||
@ -119,7 +119,7 @@ namespace fr
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(RequestVersion::VersionCount == 3, "Update me");
|
||||
static_assert((uint32_t)RequestVersion::VersionCount == 3, "Update me");
|
||||
request += (version == RequestVersion::V1) ? " HTTP/1.0\r\n" : " HTTP/1.1\r\n";
|
||||
|
||||
//Add the headers to the request
|
||||
@ -192,7 +192,7 @@ namespace fr
|
||||
{
|
||||
return string_to_request_type(str.substr(0, type_end));
|
||||
}
|
||||
return Http::Unknown;
|
||||
return Http::RequestType::Unknown;
|
||||
}
|
||||
|
||||
void HttpRequest::parse_header_uri(const std::string &str)
|
||||
@ -223,7 +223,7 @@ namespace fr
|
||||
}
|
||||
|
||||
//Parse HTTP version. HTTP/1.0 or HTTP/1.1
|
||||
static_assert(RequestVersion::VersionCount == 3, "Update me");
|
||||
static_assert((uint32_t)RequestVersion::VersionCount == 3, "Update me");
|
||||
version = str.compare(uri_end + 1, 8, "HTTP/1.0") == 0 ? RequestVersion::V1 : RequestVersion::V1_1;
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@ namespace fr
|
||||
{
|
||||
//Verify that it's a valid HTTP response if there's enough data
|
||||
if(body.size() >= 4 && body.compare(0, 4, "HTTP") != 0)
|
||||
return fr::Socket::ParseError;
|
||||
return fr::Socket::Status::ParseError;
|
||||
|
||||
//Check to see if this request data contains the end of the header
|
||||
uint16_t header_end_size = 4;
|
||||
@ -31,16 +31,16 @@ namespace fr
|
||||
//Ensure that the header doesn't exceed max length
|
||||
if((!header_ended && body.size() > MAX_HTTP_HEADER_SIZE) || (header_ended && header_end > MAX_HTTP_HEADER_SIZE))
|
||||
{
|
||||
return fr::Socket::HttpHeaderTooBig;
|
||||
return fr::Socket::Status::HttpHeaderTooBig;
|
||||
}
|
||||
|
||||
//If the header end has not been found, ask for more data.
|
||||
if(!header_ended)
|
||||
return fr::Socket::NotEnoughData;
|
||||
return fr::Socket::Status::NotEnoughData;
|
||||
|
||||
//Else parse it
|
||||
if(!parse_header(header_end))
|
||||
return fr::Socket::ParseError;
|
||||
return fr::Socket::Status::ParseError;
|
||||
|
||||
//Leave things after the header intact
|
||||
body.erase(0, header_end + header_end_size);
|
||||
@ -48,14 +48,14 @@ namespace fr
|
||||
|
||||
//Ensure that body doesn't exceed maximum length
|
||||
if(body.size() > MAX_HTTP_BODY_SIZE)
|
||||
return fr::Socket::HttpBodyTooBig;
|
||||
return fr::Socket::Status::HttpBodyTooBig;
|
||||
|
||||
//Cut off any data if it exceeds content length, todo: potentially an issue, could cut the next request off
|
||||
if(body.size() > content_length)
|
||||
body.resize(content_length);
|
||||
else if(body.size() < content_length)
|
||||
return fr::Socket::NotEnoughData;
|
||||
return fr::Socket::Success;
|
||||
return fr::Socket::Status::NotEnoughData;
|
||||
return fr::Socket::Status::Success;
|
||||
|
||||
}
|
||||
|
||||
@ -63,8 +63,8 @@ namespace fr
|
||||
{
|
||||
//Add HTTP header
|
||||
|
||||
static_assert(RequestVersion::VersionCount == 3, "Update me");
|
||||
std::string response = ((version == RequestVersion::V1) ? "HTTP/1.0 " : "HTTP/1.1 ") + std::to_string(status) + " \r\n";
|
||||
static_assert((uint32_t)RequestVersion::VersionCount == 3, "Update me");
|
||||
std::string response = ((version == RequestVersion::V1) ? "HTTP/1.0 " : "HTTP/1.1 ") + std::to_string((uint32_t)status) + " \r\n";
|
||||
|
||||
//Add the headers to the response
|
||||
for(const auto &header : header_data)
|
||||
@ -107,7 +107,7 @@ namespace fr
|
||||
status = (RequestStatus)std::stoi(header_lines[0].substr(status_begin, end_pos - status_begin));
|
||||
|
||||
//Get HTTP version
|
||||
static_assert(RequestVersion::VersionCount == 3, "Update me");
|
||||
static_assert((uint32_t)RequestVersion::VersionCount == 3, "Update me");
|
||||
version = header_lines[0].compare(0, status_begin, "HTTP/1.0") == 0 ? RequestVersion::V1 : RequestVersion::V1_1;
|
||||
line++;
|
||||
|
||||
|
||||
@ -74,14 +74,14 @@ namespace fr
|
||||
mbedtls_net_init(&listen_fd);
|
||||
fr::TcpListener tcp_listen;
|
||||
tcp_listen.set_inet_version(ai_family);
|
||||
if(tcp_listen.listen(port) != fr::Socket::Success)
|
||||
if(tcp_listen.listen(port) != fr::Socket::Status::Success)
|
||||
{
|
||||
return Socket::BindFailed;
|
||||
return Socket::Status::BindFailed;
|
||||
}
|
||||
|
||||
listen_fd.fd = tcp_listen.get_socket_descriptor();
|
||||
tcp_listen.set_socket_descriptor(-1); //The socket wont close if it's -1 when we destruct it
|
||||
return Socket::Success;
|
||||
return Socket::Status::Success;
|
||||
}
|
||||
|
||||
Socket::Status SSLListener::accept(Socket &client_)
|
||||
@ -100,7 +100,7 @@ namespace fr
|
||||
if((error = mbedtls_ssl_setup(ssl.get(), &conf)) != 0)
|
||||
{
|
||||
free_contexts();
|
||||
return Socket::Error;
|
||||
return Socket::Status::Error;
|
||||
}
|
||||
|
||||
//Accept a connection
|
||||
@ -109,7 +109,7 @@ namespace fr
|
||||
if((error = mbedtls_net_accept(&listen_fd, client_fd.get(), client_ip, sizeof(client_ip), &ip_len)) != 0)
|
||||
{
|
||||
free_contexts();
|
||||
return Socket::AcceptError;
|
||||
return Socket::Status::AcceptError;
|
||||
}
|
||||
|
||||
|
||||
@ -144,7 +144,7 @@ namespace fr
|
||||
client.set_ssl_context(std::move(ssl));
|
||||
client.set_descriptor(client_fd.release());
|
||||
client.set_remote_address(client_printable_addr);
|
||||
return Socket::Success;
|
||||
return Socket::Status::Success;
|
||||
}
|
||||
|
||||
void SSLListener::shutdown()
|
||||
@ -152,7 +152,7 @@ namespace fr
|
||||
::shutdown(listen_fd.fd, 0);
|
||||
}
|
||||
|
||||
int32_t SSLListener::get_socket_descriptor() const noexcept
|
||||
int32_t SSLListener::get_socket_descriptor() const
|
||||
{
|
||||
return listen_fd.fd;
|
||||
}
|
||||
@ -171,7 +171,7 @@ namespace fr
|
||||
}
|
||||
}
|
||||
|
||||
bool SSLListener::connected() const noexcept
|
||||
bool SSLListener::connected() const
|
||||
{
|
||||
return listen_fd.fd > -1;
|
||||
}
|
||||
|
||||
@ -168,10 +168,10 @@ namespace fr
|
||||
{
|
||||
fr::TcpSocket socket;
|
||||
auto ret = socket.connect(address, port, timeout);
|
||||
if(ret != fr::Socket::Success)
|
||||
if(ret != fr::Socket::Status::Success)
|
||||
return ret;
|
||||
ssl_socket_descriptor->fd = socket.get_socket_descriptor();
|
||||
remote_address = socket.get_remote_address();
|
||||
set_remote_address(socket.get_remote_address());
|
||||
socket.set_descriptor(nullptr);
|
||||
}
|
||||
|
||||
@ -249,11 +249,11 @@ namespace fr
|
||||
if(ret != 0)
|
||||
{
|
||||
errno = ret;
|
||||
return fr::Socket::SSLError;
|
||||
return fr::Socket::Status::SSLError;
|
||||
}
|
||||
|
||||
is_blocking = should_block;
|
||||
return fr::Socket::Success;
|
||||
return fr::Socket::Status::Success;
|
||||
}
|
||||
|
||||
void SSLSocket::reconfigure_socket()
|
||||
|
||||
@ -27,7 +27,7 @@ namespace fr
|
||||
Socket::Status Socket::send(const Sendable &obj)
|
||||
{
|
||||
if(!connected())
|
||||
return Socket::Disconnected;
|
||||
return Socket::Status::Disconnected;
|
||||
|
||||
return obj.send(this);
|
||||
}
|
||||
@ -45,13 +45,13 @@ namespace fr
|
||||
size_t received = 0;
|
||||
Status status = receive_raw((char*)dest + (buffer_size - bytes_remaining), (size_t)bytes_remaining, received);
|
||||
bytes_remaining -= received;
|
||||
if(status != Socket::Success)
|
||||
if(status != Socket::Status::Success)
|
||||
{
|
||||
if((ssize_t)buffer_size == bytes_remaining)
|
||||
return status;
|
||||
if(status == Socket::WouldBlock)
|
||||
if(status == Socket::Status::WouldBlock)
|
||||
continue;
|
||||
return Socket::Disconnected;
|
||||
return Socket::Status::Disconnected;
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,49 +99,49 @@ namespace fr
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case Unknown:
|
||||
case Socket::Status::Unknown:
|
||||
return "Unknown";
|
||||
case Success:
|
||||
case Socket::Status::Success:
|
||||
return "Success";
|
||||
case ListenFailed:
|
||||
case Socket::Status::ListenFailed:
|
||||
return std::string("Listen Failed (").append(ERR_STR).append(")");
|
||||
case BindFailed:
|
||||
case Socket::Status::BindFailed:
|
||||
return std::string("Bind Failed (").append(ERR_STR).append(")");
|
||||
case Disconnected:
|
||||
case Socket::Status::Disconnected:
|
||||
return "The Socket Is Not Connected";
|
||||
case Error:
|
||||
case Socket::Status::Error:
|
||||
return "Error";
|
||||
case WouldBlock:
|
||||
case Socket::Status::WouldBlock:
|
||||
return "Would Block";
|
||||
case ConnectionFailed:
|
||||
case Socket::Status::ConnectionFailed:
|
||||
return "Connection Failed";
|
||||
case HandshakeFailed:
|
||||
case Socket::Status::HandshakeFailed:
|
||||
return "Handshake Failed";
|
||||
case VerificationFailed:
|
||||
case Socket::Status::VerificationFailed:
|
||||
return "Verification Failed";
|
||||
case MaxPacketSizeExceeded:
|
||||
case Socket::Status::MaxPacketSizeExceeded:
|
||||
return "Max Packet Size Exceeded";
|
||||
case NotEnoughData:
|
||||
case Socket::Status::NotEnoughData:
|
||||
return "Not Enough Data";
|
||||
case ParseError:
|
||||
case Socket::Status::ParseError:
|
||||
return "Parse Error";
|
||||
case HttpHeaderTooBig:
|
||||
case Socket::Status::HttpHeaderTooBig:
|
||||
return "HTTP Header Too Big";
|
||||
case HttpBodyTooBig:
|
||||
case Socket::Status::HttpBodyTooBig:
|
||||
return "HTTP Body Too Big";
|
||||
case AddressLookupFailure:
|
||||
case Socket::Status::AddressLookupFailure:
|
||||
#ifdef _WIN32
|
||||
return std::string("Address Lookup Failure (").append(wsa_err_to_str(WSAGetLastError())).append(")");
|
||||
#else
|
||||
return std::string("Address Lookup Failure (").append(gai_strerror(errno)).append(")");
|
||||
#endif
|
||||
case SendError:
|
||||
case Socket::Status::SendError:
|
||||
return std::string("Send Error (").append(ERR_STR).append(")");
|
||||
case ReceiveError:
|
||||
case Socket::Status::ReceiveError:
|
||||
return std::string("Receive Error (").append(ERR_STR).append(")");
|
||||
case AcceptError:
|
||||
case Socket::Status::AcceptError:
|
||||
return std::string("Accept Error (").append(ERR_STR).append(")");
|
||||
case SSLError:
|
||||
case Socket::Status::SSLError:
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
char buff[256] = {0};
|
||||
@ -151,9 +151,9 @@ namespace fr
|
||||
return "Generic SSL Error";
|
||||
#endif
|
||||
}
|
||||
case NoRouteToHost:
|
||||
case Socket::Status::NoRouteToHost:
|
||||
return "No Route To Host";
|
||||
case Timeout:
|
||||
case Socket::Status::Timeout:
|
||||
return "Timeout";
|
||||
default:
|
||||
return "Unknown";
|
||||
|
||||
@ -91,9 +91,9 @@ namespace fr
|
||||
//Listen to socket
|
||||
if(::listen(socket_descriptor, LISTEN_QUEUE_SIZE) == SOCKET_ERROR)
|
||||
{
|
||||
return Socket::ListenFailed;
|
||||
return Socket::Status::ListenFailed;
|
||||
}
|
||||
return Socket::Success;
|
||||
return Socket::Status::Success;
|
||||
}
|
||||
|
||||
Socket::Status TcpListener::accept(Socket &client_)
|
||||
@ -110,7 +110,7 @@ namespace fr
|
||||
socklen_t client_addr_len = sizeof client_addr;
|
||||
client_descriptor = ::accept(socket_descriptor, (sockaddr*)&client_addr, &client_addr_len);
|
||||
if(client_descriptor == SOCKET_ERROR)
|
||||
return Socket::AcceptError;
|
||||
return Socket::Status::AcceptError;
|
||||
|
||||
//Get printable address. If we failed then set it as just 'unknown'
|
||||
int err = getnameinfo((sockaddr*)&client_addr, client_addr_len, client_printable_addr, sizeof(client_printable_addr), nullptr, 0, NI_NUMERICHOST);
|
||||
@ -123,7 +123,7 @@ namespace fr
|
||||
client.set_descriptor(&client_descriptor);
|
||||
client.set_remote_address(client_printable_addr);
|
||||
|
||||
return Socket::Success;
|
||||
return Socket::Status::Success;
|
||||
}
|
||||
|
||||
void TcpListener::shutdown()
|
||||
@ -131,7 +131,7 @@ namespace fr
|
||||
::shutdown(socket_descriptor, 0);
|
||||
}
|
||||
|
||||
int32_t TcpListener::get_socket_descriptor() const noexcept
|
||||
int32_t TcpListener::get_socket_descriptor() const
|
||||
{
|
||||
return socket_descriptor;
|
||||
}
|
||||
@ -150,7 +150,7 @@ namespace fr
|
||||
}
|
||||
}
|
||||
|
||||
bool TcpListener::connected() const noexcept
|
||||
bool TcpListener::connected() const
|
||||
{
|
||||
return socket_descriptor > -1;
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@ namespace fr
|
||||
{
|
||||
|
||||
TcpSocket::TcpSocket() noexcept
|
||||
: socket_descriptor(-1),
|
||||
is_blocking(true)
|
||||
: socket_descriptor(-1),
|
||||
is_blocking(true)
|
||||
{
|
||||
|
||||
}
|
||||
@ -192,7 +192,7 @@ namespace fr
|
||||
return Socket::Status::Error;
|
||||
|
||||
//Update state now we've got a valid socket descriptor
|
||||
remote_address = address + ":" + port;
|
||||
set_remote_address(address + ":" + port);
|
||||
reconfigure_socket();
|
||||
|
||||
return Socket::Status::Success;
|
||||
@ -203,7 +203,7 @@ namespace fr
|
||||
if(!set_unix_socket_blocking(socket_descriptor, is_blocking, should_block))
|
||||
return Status::Error;
|
||||
is_blocking = should_block;
|
||||
return Socket::Success;
|
||||
return fr::Socket::Status::Success;
|
||||
}
|
||||
|
||||
int32_t TcpSocket::get_socket_descriptor() const noexcept
|
||||
|
||||
@ -26,7 +26,7 @@ namespace fr
|
||||
}
|
||||
|
||||
|
||||
void URL::parse(std::string url)
|
||||
void URL::parse(const std::string &url)
|
||||
{
|
||||
scheme = Scheme::Unknown;
|
||||
size_t parse_offset = 0;
|
||||
@ -133,13 +133,6 @@ namespace fr
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
std::string URL::to_lower(const std::string &str)
|
||||
{
|
||||
std::string out = str;
|
||||
std::transform(out.begin(), out.end(), out.begin(), ::tolower);
|
||||
return out;
|
||||
}
|
||||
|
||||
const std::string &URL::scheme_to_string(URL::Scheme scheme)
|
||||
{
|
||||
auto iter = std::find_if(scheme_string_map.begin(), scheme_string_map.end(), [&](const auto &i)
|
||||
|
||||
@ -20,7 +20,7 @@ namespace fr
|
||||
{
|
||||
auto *socket = dynamic_cast<WebSocketBase*>(socket_);
|
||||
if(!socket)
|
||||
return Socket::Error;
|
||||
return Socket::Status::Error;
|
||||
|
||||
uint16_t first_2bytes = 0;
|
||||
std::string buffer;
|
||||
@ -29,7 +29,7 @@ namespace fr
|
||||
first_2bytes |= final << 15;
|
||||
|
||||
//Set opcode bit
|
||||
first_2bytes |= opcode << 8;
|
||||
first_2bytes |= (uint8_t)opcode << 8;
|
||||
|
||||
//Set mask bit (dependent on is_client flag, only client -> server messages are masked)
|
||||
first_2bytes |= socket->is_client() << 7;
|
||||
@ -82,7 +82,7 @@ namespace fr
|
||||
do
|
||||
{
|
||||
state = socket_->send_raw(buffer.c_str(), buffer.size(), sent);
|
||||
} while(state == fr::Socket::WouldBlock);
|
||||
} while(state == fr::Socket::Status::WouldBlock);
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -90,13 +90,13 @@ namespace fr
|
||||
{
|
||||
auto *socket_ = dynamic_cast<WebSocketBase*>(socket);
|
||||
if(!socket_)
|
||||
return Socket::Error;
|
||||
return Socket::Status::Error;
|
||||
payload.clear();
|
||||
Socket::Status status;
|
||||
|
||||
uint16_t first_2bytes;
|
||||
status = socket->receive_all(&first_2bytes, sizeof(first_2bytes));
|
||||
if(status != fr::Socket::Success)
|
||||
if(status != fr::Socket::Status::Success)
|
||||
return status;
|
||||
first_2bytes = ntohs(first_2bytes);
|
||||
|
||||
@ -110,7 +110,7 @@ namespace fr
|
||||
auto mask = static_cast<bool>((first_2bytes >> 7) & 0x1);
|
||||
if(mask == socket_->is_client())
|
||||
{
|
||||
return fr::Socket::Error;
|
||||
return fr::Socket::Status::Error;
|
||||
}
|
||||
|
||||
|
||||
@ -122,11 +122,11 @@ namespace fr
|
||||
do
|
||||
{
|
||||
status = socket->receive_all(&length, sizeof(length));
|
||||
} while(status == fr::Socket::WouldBlock);
|
||||
if(status == fr::Socket::Timeout)
|
||||
status = fr::Socket::Disconnected;
|
||||
} while(status == fr::Socket::Status::WouldBlock);
|
||||
if(status == fr::Socket::Status::Timeout)
|
||||
status = fr::Socket::Status::Disconnected;
|
||||
payload_length = ntohs(length);
|
||||
if(status != fr::Socket::Success)
|
||||
if(status != fr::Socket::Status::Success)
|
||||
return status;
|
||||
}
|
||||
else if(payload_length == 127) //Length is longer than 16 bit, so read 64bit length
|
||||
@ -134,18 +134,18 @@ namespace fr
|
||||
do
|
||||
{
|
||||
status = socket->receive_all(&payload_length, sizeof(payload_length));
|
||||
} while(status == fr::Socket::WouldBlock);
|
||||
if(status == fr::Socket::Timeout)
|
||||
status = fr::Socket::Disconnected;
|
||||
} while(status == fr::Socket::Status::WouldBlock);
|
||||
if(status == fr::Socket::Status::Timeout)
|
||||
status = fr::Socket::Status::Disconnected;
|
||||
payload_length = fr_ntohll(payload_length);
|
||||
if(status != fr::Socket::Success)
|
||||
if(status != fr::Socket::Status::Success)
|
||||
return status;
|
||||
}
|
||||
|
||||
//Verify that payload length isn't too large
|
||||
if(socket->get_max_receive_size() && payload_length > socket->get_max_receive_size())
|
||||
{
|
||||
return Socket::MaxPacketSizeExceeded;
|
||||
return Socket::Status::MaxPacketSizeExceeded;
|
||||
}
|
||||
|
||||
//Read masking key if the mask bit is set
|
||||
@ -159,10 +159,10 @@ namespace fr
|
||||
do
|
||||
{
|
||||
status = socket->receive_all(&mask_union.mask_key, 4);
|
||||
} while(status == fr::Socket::WouldBlock);
|
||||
if(status == fr::Socket::Timeout)
|
||||
status = fr::Socket::Disconnected;
|
||||
if(status != fr::Socket::Success)
|
||||
} while(status == fr::Socket::Status::WouldBlock);
|
||||
if(status == fr::Socket::Status::Timeout)
|
||||
status = fr::Socket::Status::Disconnected;
|
||||
if(status != fr::Socket::Status::Success)
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -171,10 +171,10 @@ namespace fr
|
||||
do
|
||||
{
|
||||
status = socket->receive_all(&payload[0], payload_length);
|
||||
} while(status == fr::Socket::WouldBlock);
|
||||
if(status == fr::Socket::Timeout)
|
||||
status = fr::Socket::Disconnected;
|
||||
if(status != fr::Socket::Success)
|
||||
} while(status == fr::Socket::Status::WouldBlock);
|
||||
if(status == fr::Socket::Status::Timeout)
|
||||
status = fr::Socket::Status::Disconnected;
|
||||
if(status != fr::Socket::Status::Success)
|
||||
return status;
|
||||
|
||||
//Decode the payload if the mask bit is set
|
||||
@ -186,7 +186,7 @@ namespace fr
|
||||
}
|
||||
|
||||
}
|
||||
return fr::Socket::Success;
|
||||
return fr::Socket::Status::Success;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -14,10 +14,10 @@ TEST(HttpRequestTest, get_request_parse)
|
||||
|
||||
//Parse it
|
||||
fr::HttpRequest request;
|
||||
ASSERT_EQ(request.parse(raw_request.c_str(), raw_request.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.parse(raw_request.c_str(), raw_request.size()), fr::Socket::Status::Success);
|
||||
|
||||
//Check that the request type is intact
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Get);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Get);
|
||||
|
||||
//Test that URI is intact
|
||||
ASSERT_EQ(request.get_uri(), "/index.html");
|
||||
@ -57,10 +57,10 @@ TEST(HttpRequestTest, post_request_parse)
|
||||
|
||||
//Parse it
|
||||
fr::HttpRequest request;
|
||||
ASSERT_EQ(request.parse(raw_request.c_str(), raw_request.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.parse(raw_request.c_str(), raw_request.size()), fr::Socket::Status::Success);
|
||||
|
||||
//Check that the request type is intact
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Post);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Post);
|
||||
|
||||
//Test that URI is intact
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
@ -89,48 +89,48 @@ TEST(HttpRequestTest, request_type_parse)
|
||||
const std::string invalid_request2 = "PU / HTTP/1.1\r\n\r\n";
|
||||
|
||||
fr::HttpRequest request;
|
||||
ASSERT_EQ(request.parse(get_request.c_str(), get_request.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Get);
|
||||
ASSERT_EQ(request.parse(get_request.c_str(), get_request.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Get);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
request = {};
|
||||
|
||||
ASSERT_EQ(request.parse(post_request.c_str(), post_request.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Post);
|
||||
ASSERT_EQ(request.parse(post_request.c_str(), post_request.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Post);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
request = {};
|
||||
|
||||
ASSERT_EQ(request.parse(get_request_v2.c_str(), get_request_v2.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Get);
|
||||
ASSERT_EQ(request.parse(get_request_v2.c_str(), get_request_v2.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Get);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1);
|
||||
request = {};
|
||||
|
||||
ASSERT_EQ(request.parse(post_request_v2.c_str(), post_request_v2.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Post);
|
||||
ASSERT_EQ(request.parse(post_request_v2.c_str(), post_request_v2.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Post);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1);
|
||||
request = {};
|
||||
|
||||
ASSERT_EQ(request.parse(put_request.c_str(), put_request.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Put);
|
||||
ASSERT_EQ(request.parse(put_request.c_str(), put_request.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Put);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
request = {};
|
||||
|
||||
ASSERT_EQ(request.parse(delete_request.c_str(), delete_request.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Delete);
|
||||
ASSERT_EQ(request.parse(delete_request.c_str(), delete_request.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Delete);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
request = {};
|
||||
|
||||
ASSERT_EQ(request.parse(patch_request.c_str(), patch_request.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Patch);
|
||||
ASSERT_EQ(request.parse(patch_request.c_str(), patch_request.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Patch);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
request = {};
|
||||
|
||||
ASSERT_EQ(request.parse(invalid_request.c_str(), invalid_request.size()), fr::Socket::ParseError);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Unknown);
|
||||
ASSERT_EQ(request.parse(invalid_request.c_str(), invalid_request.size()), fr::Socket::Status::ParseError);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Unknown);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
request = {};
|
||||
|
||||
ASSERT_EQ(request.parse(invalid_request2.c_str(), invalid_request2.size()), fr::Socket::ParseError);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Unknown);
|
||||
ASSERT_EQ(request.parse(invalid_request2.c_str(), invalid_request2.size()), fr::Socket::Status::ParseError);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Unknown);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
request = {};
|
||||
}
|
||||
@ -147,7 +147,7 @@ TEST(HttpRequestTest, get_request_construction)
|
||||
request.get("my_get") = "var1";
|
||||
request.get("my_other_get") = "var2";
|
||||
request.set_uri("heyo/bobby");
|
||||
request.set_type(fr::Http::Get);
|
||||
request.set_type(fr::Http::RequestType::Get);
|
||||
std::string constructed_request = request.construct("frednicolson.co.uk");
|
||||
|
||||
//Parse it and check that everything's correct
|
||||
@ -158,7 +158,7 @@ TEST(HttpRequestTest, get_request_construction)
|
||||
ASSERT_EQ(request.get("my_get"), "var1");
|
||||
ASSERT_EQ(request.get("my_other_get"), "var2");
|
||||
ASSERT_EQ(request.get_uri(), "/heyo/bobby");
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Get);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Get);
|
||||
ASSERT_EQ(request.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
|
||||
//Quick v1 test
|
||||
@ -179,7 +179,7 @@ TEST(HttpRequestTest, post_request_construction)
|
||||
request.get("var") = "20";
|
||||
request.post("my_post") = "post_data";
|
||||
request.post("some_post") = "more_post";
|
||||
request.set_type(fr::Http::Post);
|
||||
request.set_type(fr::Http::RequestType::Post);
|
||||
const std::string constructed_request = request.construct("frednicolson.co.uk");
|
||||
|
||||
//Parse it
|
||||
@ -191,7 +191,7 @@ TEST(HttpRequestTest, post_request_construction)
|
||||
ASSERT_EQ(request.get("var"), "20");
|
||||
ASSERT_EQ(request.post("my_post"), "post_data");
|
||||
ASSERT_EQ(request.post("some_post"), "more_post");
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Post);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Post);
|
||||
}
|
||||
|
||||
TEST(HttpRequestTest, partial_parse)
|
||||
@ -211,13 +211,13 @@ TEST(HttpRequestTest, partial_parse)
|
||||
|
||||
//Parse part 1
|
||||
fr::HttpRequest request;
|
||||
ASSERT_EQ(request.parse(raw_request1.c_str(), raw_request1.size()), fr::Socket::NotEnoughData);
|
||||
ASSERT_EQ(request.parse(raw_request1.c_str(), raw_request1.size()), fr::Socket::Status::NotEnoughData);
|
||||
|
||||
//Parse part 2
|
||||
ASSERT_EQ(request.parse(raw_request2.c_str(), raw_request2.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.parse(raw_request2.c_str(), raw_request2.size()), fr::Socket::Status::Success);
|
||||
|
||||
//Verify it
|
||||
ASSERT_EQ(request.get_type(), fr::Http::Get);
|
||||
ASSERT_EQ(request.get_type(), fr::Http::RequestType::Get);
|
||||
ASSERT_EQ(request.header("content-type"), "application/x-www-form-urlencoded");
|
||||
ASSERT_EQ(request.header("Cache-Control"), "no-cache");
|
||||
}
|
||||
@ -230,7 +230,7 @@ TEST(HttpRequestTest, awkward_parse)
|
||||
"Test=bob\n"
|
||||
"\n";
|
||||
fr::HttpRequest request;
|
||||
ASSERT_EQ(request.parse(request_data.c_str(), request_data.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.parse(request_data.c_str(), request_data.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_uri(), "/my/url");
|
||||
ASSERT_EQ(request.post("Test"), "bob");
|
||||
}
|
||||
@ -242,7 +242,7 @@ TEST(HttpRequestTest, awkward_parse2)
|
||||
"Test=bob";
|
||||
|
||||
fr::HttpRequest request;
|
||||
ASSERT_EQ(request.parse(request_data.c_str(), request_data.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(request.parse(request_data.c_str(), request_data.size()), fr::Socket::Status::Success);
|
||||
ASSERT_EQ(request.get_uri(), "/my/url");
|
||||
ASSERT_EQ(request.get("Bob"), "10");
|
||||
ASSERT_EQ(request.post("Test"), "bob");
|
||||
|
||||
@ -18,7 +18,7 @@ TEST(HttpResponseTest, response_parse_v1)
|
||||
|
||||
//Parse response
|
||||
fr::HttpResponse test;
|
||||
ASSERT_EQ(test.parse(raw_response.c_str(), raw_response.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(test.parse(raw_response.c_str(), raw_response.size()), fr::Socket::Status::Success);
|
||||
|
||||
//Verify it
|
||||
ASSERT_EQ(test.get_version(), fr::Http::RequestVersion::V1);
|
||||
@ -54,11 +54,11 @@ TEST(HttpResponseTest, response_parse_v2)
|
||||
|
||||
//Parse response
|
||||
fr::HttpResponse test;
|
||||
ASSERT_EQ(test.parse(raw_response.c_str(), raw_response.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(test.parse(raw_response.c_str(), raw_response.size()), fr::Socket::Status::Success);
|
||||
|
||||
//Verify it
|
||||
ASSERT_EQ(test.get_version(), fr::Http::RequestVersion::V1_1);
|
||||
ASSERT_EQ(test.get_status(), fr::Http::MovedPermanently);
|
||||
ASSERT_EQ(test.get_status(), fr::Http::RequestStatus::MovedPermanently);
|
||||
ASSERT_EQ(test.header("Content-length"), "177");
|
||||
ASSERT_EQ(test.get_body(), response_body);
|
||||
}
|
||||
@ -97,12 +97,12 @@ TEST(HttpResponseTest, response_partial_parse)
|
||||
|
||||
//Parse response
|
||||
fr::HttpResponse test;
|
||||
ASSERT_EQ(test.parse(raw_response1.c_str(), raw_response1.size()), fr::Socket::NotEnoughData);
|
||||
ASSERT_EQ(test.parse(raw_response2.c_str(), raw_response2.size()), fr::Socket::NotEnoughData);
|
||||
ASSERT_EQ(test.parse(raw_response3.c_str(), raw_response3.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(test.parse(raw_response1.c_str(), raw_response1.size()), fr::Socket::Status::NotEnoughData);
|
||||
ASSERT_EQ(test.parse(raw_response2.c_str(), raw_response2.size()), fr::Socket::Status::NotEnoughData);
|
||||
ASSERT_EQ(test.parse(raw_response3.c_str(), raw_response3.size()), fr::Socket::Status::Success);
|
||||
|
||||
//Verify it
|
||||
ASSERT_EQ(test.get_status(), fr::Http::MovedPermanently);
|
||||
ASSERT_EQ(test.get_status(), fr::Http::RequestStatus::MovedPermanently);
|
||||
ASSERT_EQ(test.header("Content-length"), "177");
|
||||
ASSERT_EQ(test.get_body(), response_body);
|
||||
}
|
||||
@ -113,7 +113,7 @@ TEST(HttpResponseTest, header_length_test)
|
||||
std::string buff(MAX_HTTP_HEADER_SIZE + 1, '\0');
|
||||
fr::HttpResponse response;
|
||||
buff.insert(0, "HTTP");
|
||||
ASSERT_EQ(response.parse(buff.c_str(), buff.size()), fr::Socket::HttpHeaderTooBig);
|
||||
ASSERT_EQ(response.parse(buff.c_str(), buff.size()), fr::Socket::Status::HttpHeaderTooBig);
|
||||
response = {};
|
||||
|
||||
//Now try short header but long data, this should work
|
||||
@ -122,7 +122,7 @@ TEST(HttpResponseTest, header_length_test)
|
||||
"Content-Length: " + std::to_string(MAX_HTTP_BODY_SIZE - 1) + "\n"
|
||||
"Connection: keep-alive\n"
|
||||
"\n" + std::string(MAX_HTTP_BODY_SIZE - 1, '\0');
|
||||
ASSERT_EQ(response.parse(buff.c_str(), buff.size()), fr::Socket::Success);
|
||||
ASSERT_EQ(response.parse(buff.c_str(), buff.size()), fr::Socket::Status::Success);
|
||||
}
|
||||
|
||||
TEST(HttpResponseTest, body_length_test)
|
||||
@ -135,14 +135,14 @@ TEST(HttpResponseTest, body_length_test)
|
||||
"\n";
|
||||
buff += std::string(MAX_HTTP_BODY_SIZE + 1, '\0');
|
||||
fr::HttpResponse response;
|
||||
ASSERT_EQ(response.parse(buff.c_str(), buff.size()), fr::Socket::HttpBodyTooBig);
|
||||
ASSERT_EQ(response.parse(buff.c_str(), buff.size()), fr::Socket::Status::HttpBodyTooBig);
|
||||
}
|
||||
|
||||
TEST(HttpResponseTest, HttpResponseConstruction)
|
||||
{
|
||||
{
|
||||
fr::HttpResponse response;
|
||||
response.set_status(fr::Http::ImATeapot);
|
||||
response.set_status(fr::Http::RequestStatus::ImATeapot);
|
||||
response.header("bob") = "trob";
|
||||
response.set_body("lob");
|
||||
auto constructed = response.construct("frednicolson.co.uk");
|
||||
|
||||
@ -7,31 +7,31 @@
|
||||
|
||||
TEST(HttpTest, test_request_type_to_string)
|
||||
{
|
||||
for(size_t a = 0; a < fr::Http::RequestTypeCount; ++a)
|
||||
for(size_t a = 0; a < (uint32_t)fr::Http::RequestType::RequestTypeCount; ++a)
|
||||
{
|
||||
ASSERT_EQ(fr::Http::string_to_request_type(fr::Http::request_type_to_string((fr::Http::RequestType)a)), a);
|
||||
ASSERT_EQ((size_t)fr::Http::string_to_request_type(fr::Http::request_type_to_string((fr::Http::RequestType)a)), a);
|
||||
}
|
||||
|
||||
ASSERT_EQ(fr::Http::request_type_to_string(fr::Http::Partial), "UNKNOWN");
|
||||
ASSERT_EQ(fr::Http::request_type_to_string(fr::Http::RequestTypeCount), "UNKNOWN");
|
||||
ASSERT_EQ(fr::Http::request_type_to_string(fr::Http::Unknown), "UNKNOWN");
|
||||
ASSERT_EQ(fr::Http::request_type_to_string(fr::Http::RequestType::Partial), "UNKNOWN");
|
||||
ASSERT_EQ(fr::Http::request_type_to_string(fr::Http::RequestType::RequestTypeCount), "UNKNOWN");
|
||||
ASSERT_EQ(fr::Http::request_type_to_string(fr::Http::RequestType::Unknown), "UNKNOWN");
|
||||
}
|
||||
|
||||
TEST(HttpTest, test_string_to_request_type)
|
||||
{
|
||||
std::vector<std::pair<fr::Http::RequestType, std::string>> strings = {
|
||||
{fr::Http::Get, "GET"},
|
||||
{fr::Http::Put, "PUT"},
|
||||
{fr::Http::Delete, "DELETE"},
|
||||
{fr::Http::Patch, "PATCH"},
|
||||
{fr::Http::Patch, "PATCHid-=wa"},
|
||||
{fr::Http::Partial, "PA"},
|
||||
{fr::Http::Partial, "PU"},
|
||||
{fr::Http::Partial, "DELET"},
|
||||
{fr::Http::Unknown, "DELETa"},
|
||||
{fr::Http::Unknown, "U"},
|
||||
{fr::Http::Unknown, "dwaouidhwi"},
|
||||
{fr::Http::Unknown, "get"},
|
||||
{fr::Http::RequestType::Get, "GET"},
|
||||
{fr::Http::RequestType::Put, "PUT"},
|
||||
{fr::Http::RequestType::Delete, "DELETE"},
|
||||
{fr::Http::RequestType::Patch, "PATCH"},
|
||||
{fr::Http::RequestType::Patch, "PATCHid-=wa"},
|
||||
{fr::Http::RequestType::Partial, "PA"},
|
||||
{fr::Http::RequestType::Partial, "PU"},
|
||||
{fr::Http::RequestType::Partial, "DELET"},
|
||||
{fr::Http::RequestType::Unknown, "DELETa"},
|
||||
{fr::Http::RequestType::Unknown, "U"},
|
||||
{fr::Http::RequestType::Unknown, "dwaouidhwi"},
|
||||
{fr::Http::RequestType::Unknown, "get"},
|
||||
};
|
||||
|
||||
for(auto &str : strings)
|
||||
|
||||
@ -11,7 +11,7 @@ TEST(TcpListenerTest, listner_listen)
|
||||
fr::TcpListener listener;
|
||||
ASSERT_EQ(listener.get_socket_descriptor(), -1);
|
||||
fr::Socket::Status ret = listener.listen("9090");
|
||||
ASSERT_EQ(ret, fr::Socket::Success);
|
||||
ASSERT_EQ(ret, fr::Socket::Status::Success);
|
||||
listener.close_socket();
|
||||
ASSERT_EQ(listener.get_socket_descriptor(), -1);
|
||||
}
|
||||
@ -21,7 +21,7 @@ TEST(TcpListenerTest, listener_accept)
|
||||
{
|
||||
fr::TcpListener listener;
|
||||
listener.set_inet_version(fr::Socket::IP::v4);
|
||||
if(listener.listen("9095") != fr::Socket::Success)
|
||||
if(listener.listen("9095") != fr::Socket::Status::Success)
|
||||
FAIL();
|
||||
|
||||
auto client_thread = []()
|
||||
@ -29,13 +29,13 @@ TEST(TcpListenerTest, listener_accept)
|
||||
fr::TcpSocket socket;
|
||||
socket.set_inet_version(fr::Socket::IP::v4);
|
||||
auto ret = socket.connect("127.0.0.1", "9095", std::chrono::seconds(5));
|
||||
ASSERT_EQ(ret, fr::Socket::Success);
|
||||
ASSERT_EQ(ret, fr::Socket::Status::Success);
|
||||
};
|
||||
|
||||
std::thread t1(client_thread);
|
||||
fr::TcpSocket socket;
|
||||
auto ret = listener.accept(socket);
|
||||
ASSERT_EQ(ret, fr::Socket::Success);
|
||||
ASSERT_EQ(ret, fr::Socket::Status::Success);
|
||||
t1.join();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user