Skip to content

Commit

Permalink
#25 - Secure socket test uses application/network/http/HTTPProtocol
Browse files Browse the repository at this point in the history
  • Loading branch information
PerMalmberg committed May 18, 2019
1 parent 597787f commit 4f2cc3f
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 470 deletions.
109 changes: 64 additions & 45 deletions lib/smooth/application/network/http/HTTPPacket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,81 @@
#include <string>
#include <unordered_map>
#include <algorithm>
#include <smooth/application/network/http/http_utils.h>

namespace smooth
namespace smooth::application::network::http
{
namespace application
HTTPPacket::HTTPPacket(ResponseCode code, const std::string& version,
const std::unordered_map<std::string, std::string>& new_headers,
const std::vector<uint8_t>& response_content)
{
namespace network
append("HTTP/");
append(version);
append(" ");
append(std::to_string(static_cast<int>(code)));
append(" ");
append(response_code_to_text.at(code));
append("\r\n");

for (const auto& header : new_headers)
{
namespace http
{
HTTPPacket::HTTPPacket(ResponseCode code, const std::string& version,
const std::unordered_map<std::string, std::string>& new_headers,
std::vector<uint8_t>& response_content)
{
append("HTTP/");
append(version);
append(" ");
append(std::to_string(static_cast<int>(code)));
append(" ");
append(response_code_to_text.at(code));
append("\r\n");
const auto& key = header.first;
const auto& value = header.second;

add_header(key, value);
}

for (const auto& header : new_headers)
{
const auto& key = header.first;
const auto& value = header.second;
// Add required ending CRLF
append("\r\n");

add_header(key, value);
}
if (!response_content.empty())
{
std::copy(response_content.begin(), response_content.end(), std::back_inserter(content));
}
}

// Add required ending CRLF
append("\r\n");
HTTPPacket::HTTPPacket(HTTPMethod method, const std::string& url,
const std::unordered_map<std::string, std::string>& new_headers,
const std::vector<uint8_t>& response_content)
{
append(utils::http_method_to_string(method));
append(" ");
append(url);
append(" HTTP/1.1");
append("\r\n");

if (!response_content.empty())
{
std::copy(response_content.begin(), response_content.end(), std::back_inserter(content));
}
}
for (const auto& header : new_headers)
{
const auto& key = header.first;
const auto& value = header.second;

void HTTPPacket::append(const std::string& s)
{
std::copy(s.begin(), s.end(), std::back_inserter(content));
}
add_header(key, value);
}

void HTTPPacket::add_header(const std::string& key, const std::string& value)
{
append(key);
append(": ");
append(value);
append("\r\n");
}
// Add required ending CRLF
append("\r\n");

HTTPPacket::HTTPPacket(std::vector<uint8_t>& response_content)
{
content = std::move(response_content);
}
}
if (!response_content.empty())
{
std::copy(response_content.begin(), response_content.end(), std::back_inserter(content));
}
}

void HTTPPacket::append(const std::string& s)
{
std::copy(s.begin(), s.end(), std::back_inserter(content));
}

void HTTPPacket::add_header(const std::string& key, const std::string& value)
{
append(key);
append(": ");
append(value);
append("\r\n");
}

HTTPPacket::HTTPPacket(std::vector<uint8_t>& response_content)
{
content = std::move(response_content);
}
}
25 changes: 25 additions & 0 deletions lib/smooth/application/network/http/http_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,29 @@ namespace smooth::application::network::http::utils

return ret;
}

std::string http_method_to_string(const HTTPMethod m)
{
if(m == HTTPMethod::DELETE)
{
return "DELETE";
}
else if(m == HTTPMethod::GET)
{
return "GET";
}
else if(m == HTTPMethod::HEAD)
{
return "HEAD";
}
else if(m == HTTPMethod::PUT)
{
return "PUT";
}
else if(m == HTTPMethod::POST)
{
return "POST";
}
return "";
}
}
17 changes: 16 additions & 1 deletion lib/smooth/include/smooth/application/network/http/HTTPPacket.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ namespace smooth

HTTPPacket(ResponseCode code, const std::string& version,
const std::unordered_map<std::string, std::string>& new_headers,
std::vector<uint8_t>& response_content);
const std::vector<uint8_t>& response_content);

HTTPPacket(HTTPMethod method, const std::string& url,
const std::unordered_map<std::string, std::string>& new_headers,
const std::vector<uint8_t>& response_content);

explicit HTTPPacket(std::vector<uint8_t>& response_content);

Expand Down Expand Up @@ -80,6 +84,16 @@ namespace smooth
request_version = version;
}

void set_response_data(ResponseCode code)
{
resp_code = code;
}

ResponseCode response_code() const
{
return resp_code;
}

const std::string& get_request_url() const
{
return request_url;
Expand Down Expand Up @@ -147,6 +161,7 @@ namespace smooth
std::string request_url{};
std::string request_version{};
std::vector<uint8_t> content{};
ResponseCode resp_code{};
bool continuation = false;
bool continued = false;
};
Expand Down
26 changes: 21 additions & 5 deletions lib/smooth/include/smooth/application/network/http/HTTPProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ using namespace smooth::core::logging;

namespace smooth::application::network::http
{
template<int MaxHeaderSize, int ContentChuckSize>
template<int MaxHeaderSize, int ContentChunkSize>
class HTTPProtocol
: public smooth::core::network::IPacketAssembly<HTTPProtocol<MaxHeaderSize, ContentChuckSize>, HTTPPacket>
: public smooth::core::network::IPacketAssembly<HTTPProtocol<MaxHeaderSize, ContentChunkSize>, HTTPPacket>
{
static_assert(MaxHeaderSize > 0,
"MaxHeaderSize must be larger than 0, and a reasonable value.");
static_assert(ContentChuckSize > 0,
"ContentChuckSize must be larger than 0, and a reasonable value.");
static_assert(ContentChunkSize > 0,
"ContentChunkSize must be larger than 0, and a reasonable value.");

public:
using packet_type = HTTPPacket;
Expand Down Expand Up @@ -52,6 +52,7 @@ namespace smooth::application::network::http
int header_bytes_received{0};
int total_content_bytes_received = 0;
int content_bytes_received_in_current_package{0};
const std::regex response_line{R"!(HTTP\/(\d.\d)\ (\d+)\ (.+))!"}; // HTTP/1.1 200 OK
const std::regex request_line{R"!((.+)\ (.+)\ HTTP\/(\d\.\d))!"}; // "GET / HTTP/1.1"
const char* CONTENT_LENGTH = "content-length";
const char* tag = "HTTPProtocol";
Expand Down Expand Up @@ -81,7 +82,7 @@ namespace smooth::application::network::http
}
else
{
// Don't make packets larger than ContentChuckSize
// Don't make packets larger than ContentChunkSize
res = std::min(incoming_content_length, ContentChuckSize - content_bytes_received_in_current_package);
packet.set_size(res);
}
Expand Down Expand Up @@ -200,6 +201,21 @@ namespace smooth::application::network::http
last_request_version = m[3].str();
packet.set_request_data(last_method, last_url, last_request_version);
}
else if(std::regex_match(s, m, response_line))
{
// Store response data for later use
try
{
auto response_code = std::stoi(m[2].str());
packet.set_response_data(static_cast<ResponseCode>(response_code));
}
catch(...)
{
error = true;
Log::error("HTTPProtocol",
Format("Invalid response code: {1}", Str(m[2].str())));
}
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <string>
#include <chrono>
#include <smooth/core/filesystem/Path.h>
#include "HTTPMethod.h"

namespace smooth::application::network::http::utils
{
Expand All @@ -13,4 +14,6 @@ namespace smooth::application::network::http::utils
std::string get_content_type(const smooth::core::filesystem::Path& path);

time_t timegm(tm& tm);

std::string http_method_to_string(HTTPMethod m);
}
45 changes: 0 additions & 45 deletions test/secure_socket_test/HTTPPacket.cpp

This file was deleted.

Loading

0 comments on commit 4f2cc3f

Please sign in to comment.