Added .clang-format file and applied style to source files
This commit is contained in:
parent
3ee9f8dc52
commit
e50d2fc63a
13 changed files with 2552 additions and 2538 deletions
9
.clang-format
Normal file
9
.clang-format
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
IndentWidth: 2
|
||||
AccessModifierOffset: -2
|
||||
UseTab: Never
|
||||
ColumnLimit: 0
|
||||
MaxEmptyLinesToKeep: 2
|
||||
SpaceBeforeParens: Never
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping: {BeforeElse: true, BeforeCatch: true}
|
||||
NamespaceIndentation: All
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
#define CLIENT_HTTP_HPP
|
||||
|
||||
#include "utility.hpp"
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <mutex>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_STANDALONE_ASIO
|
||||
#include <asio.hpp>
|
||||
|
|
@ -14,7 +14,7 @@ namespace SimpleWeb {
|
|||
using system_error = std::system_error;
|
||||
namespace make_error_code = std;
|
||||
using string_view = const std::string &; // TODO c++17: use std::string_view
|
||||
}
|
||||
} // namespace SimpleWeb
|
||||
#else
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
|
@ -25,7 +25,7 @@ namespace SimpleWeb {
|
|||
using system_error = boost::system::system_error;
|
||||
namespace make_error_code = boost::system::errc;
|
||||
using string_view = boost::string_ref;
|
||||
}
|
||||
} // namespace SimpleWeb
|
||||
#endif
|
||||
|
||||
namespace SimpleWeb {
|
||||
|
|
@ -37,6 +37,7 @@ namespace SimpleWeb {
|
|||
public:
|
||||
class Content : public std::istream {
|
||||
friend class ClientBase<socket_type>;
|
||||
|
||||
public:
|
||||
size_t size() {
|
||||
return streambuf.size();
|
||||
|
|
@ -47,6 +48,7 @@ namespace SimpleWeb {
|
|||
ss << rdbuf();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
asio::streambuf &streambuf;
|
||||
Content(asio::streambuf &streambuf) : std::istream(&streambuf), streambuf(streambuf) {}
|
||||
|
|
@ -55,6 +57,7 @@ namespace SimpleWeb {
|
|||
class Response {
|
||||
friend class ClientBase<socket_type>;
|
||||
friend class Client<socket_type>;
|
||||
|
||||
public:
|
||||
std::string http_version, status_code;
|
||||
|
||||
|
|
@ -70,8 +73,10 @@ namespace SimpleWeb {
|
|||
|
||||
class Config {
|
||||
friend class ClientBase<socket_type>;
|
||||
|
||||
private:
|
||||
Config() {}
|
||||
|
||||
public:
|
||||
/// Set timeout on requests in seconds. Default value: 0 (no timeout).
|
||||
size_t timeout = 0;
|
||||
|
|
@ -84,8 +89,8 @@ namespace SimpleWeb {
|
|||
protected:
|
||||
class Connection {
|
||||
public:
|
||||
Connection(const std::string &host, unsigned short port, const Config &config, std::unique_ptr<socket_type> &&socket) :
|
||||
host(host), port(port), config(config), socket(std::move(socket)) {
|
||||
Connection(const std::string &host, unsigned short port, const Config &config, std::unique_ptr<socket_type> &&socket)
|
||||
: host(host), port(port), config(config), socket(std::move(socket)) {
|
||||
if(config.proxy_server.empty())
|
||||
query = std::unique_ptr<asio::ip::tcp::resolver::query>(new asio::ip::tcp::resolver::query(host, std::to_string(port)));
|
||||
else {
|
||||
|
|
@ -107,8 +112,8 @@ namespace SimpleWeb {
|
|||
|
||||
class Session {
|
||||
public:
|
||||
Session(const std::shared_ptr<asio::io_service> &io_service, const std::shared_ptr<Connection> &connection, std::unique_ptr<asio::streambuf> &&request_buffer) :
|
||||
io_service(io_service), connection(connection), request_buffer(std::move(request_buffer)), response(new Response()) {}
|
||||
Session(const std::shared_ptr<asio::io_service> &io_service, const std::shared_ptr<Connection> &connection, std::unique_ptr<asio::streambuf> &&request_buffer)
|
||||
: io_service(io_service), connection(connection), request_buffer(std::move(request_buffer)), response(new Response()) {}
|
||||
std::shared_ptr<asio::io_service> io_service;
|
||||
std::shared_ptr<Connection> connection;
|
||||
std::unique_ptr<asio::streambuf> request_buffer;
|
||||
|
|
@ -128,7 +133,8 @@ namespace SimpleWeb {
|
|||
|
||||
/// Convenience function to perform synchronous request. The io_service is run within this function.
|
||||
/// If reusing the io_service for other tasks, please use the asynchronous request functions instead.
|
||||
std::shared_ptr<Response> request(const std::string& method, const std::string& path=std::string("/"), string_view content="", const CaseInsensitiveMultimap& header=CaseInsensitiveMultimap()) {
|
||||
std::shared_ptr<Response> request(const std::string &method, const std::string &path = std::string("/"),
|
||||
string_view content = "", const CaseInsensitiveMultimap &header = CaseInsensitiveMultimap()) {
|
||||
std::shared_ptr<Response> response;
|
||||
request(method, path, content, header, [&response](std::shared_ptr<Response> response_, const error_code &ec) {
|
||||
response = response_;
|
||||
|
|
@ -144,7 +150,8 @@ namespace SimpleWeb {
|
|||
|
||||
/// Convenience function to perform synchronous request. The io_service is run within this function.
|
||||
/// If reusing the io_service for other tasks, please use the asynchronous request functions instead.
|
||||
std::shared_ptr<Response> request(const std::string& method, const std::string& path, std::istream& content, const CaseInsensitiveMultimap& header=CaseInsensitiveMultimap()) {
|
||||
std::shared_ptr<Response> request(const std::string &method, const std::string &path, std::istream &content,
|
||||
const CaseInsensitiveMultimap &header = CaseInsensitiveMultimap()) {
|
||||
std::shared_ptr<Response> response;
|
||||
request(method, path, content, header, [&response](std::shared_ptr<Response> response_, const error_code &ec) {
|
||||
response = response_;
|
||||
|
|
@ -194,7 +201,8 @@ namespace SimpleWeb {
|
|||
std::ostream write_stream(session->request_buffer.get());
|
||||
if(content.size() > 0)
|
||||
write_stream << "Content-Length: " << content.size() << "\r\n";
|
||||
write_stream << "\r\n" << content;
|
||||
write_stream << "\r\n"
|
||||
<< content;
|
||||
|
||||
Client<socket_type>::connect(session);
|
||||
}
|
||||
|
|
@ -275,7 +283,8 @@ namespace SimpleWeb {
|
|||
std::shared_ptr<std::vector<std::shared_ptr<Connection>>> connections;
|
||||
std::shared_ptr<std::mutex> connections_mutex;
|
||||
|
||||
ClientBase(const std::string& host_port, unsigned short default_port) : io_service(new asio::io_service()), connections(new std::vector<std::shared_ptr<Connection>>()), connections_mutex(new std::mutex()) {
|
||||
ClientBase(const std::string &host_port, unsigned short default_port)
|
||||
: io_service(new asio::io_service()), connections(new std::vector<std::shared_ptr<Connection>>()), connections_mutex(new std::mutex()) {
|
||||
auto parsed_host_port = parse_host_port(host_port, default_port);
|
||||
host = parsed_host_port.first;
|
||||
port = parsed_host_port.second;
|
||||
|
|
@ -388,8 +397,7 @@ namespace SimpleWeb {
|
|||
|
||||
static void read(const std::shared_ptr<Session> &session) {
|
||||
auto timer = get_timeout_timer(session);
|
||||
asio::async_read_until(*session->connection->socket, session->response->content_buffer, "\r\n\r\n",
|
||||
[session, timer](const error_code& ec, size_t bytes_transferred) {
|
||||
asio::async_read_until(*session->connection->socket, session->response->content_buffer, "\r\n\r\n", [session, timer](const error_code &ec, size_t bytes_transferred) {
|
||||
if(timer)
|
||||
timer->cancel();
|
||||
if(!ec) {
|
||||
|
|
@ -404,8 +412,7 @@ namespace SimpleWeb {
|
|||
auto content_length = stoull(header_it->second);
|
||||
if(content_length > num_additional_bytes) {
|
||||
auto timer = get_timeout_timer(session);
|
||||
asio::async_read(*session->connection->socket, session->response->content_buffer, asio::transfer_exactly(content_length-num_additional_bytes),
|
||||
[session, timer](const error_code& ec, size_t /*bytes_transferred*/) {
|
||||
asio::async_read(*session->connection->socket, session->response->content_buffer, asio::transfer_exactly(content_length - num_additional_bytes), [session, timer](const error_code &ec, size_t /*bytes_transferred*/) {
|
||||
if(timer)
|
||||
timer->cancel();
|
||||
if(!ec)
|
||||
|
|
@ -496,8 +503,7 @@ namespace SimpleWeb {
|
|||
|
||||
if((2 + length) > num_additional_bytes) {
|
||||
auto timer = get_timeout_timer(session);
|
||||
asio::async_read(*session->connection->socket, session->response->content_buffer, asio::transfer_exactly(2+length-num_additional_bytes),
|
||||
[session, post_process, timer](const error_code& ec, size_t /*bytes_transferred*/) {
|
||||
asio::async_read(*session->connection->socket, session->response->content_buffer, asio::transfer_exactly(2 + length - num_additional_bytes), [session, post_process, timer](const error_code &ec, size_t /*bytes_transferred*/) {
|
||||
if(timer)
|
||||
timer->cancel();
|
||||
if(!ec)
|
||||
|
|
@ -575,6 +581,6 @@ namespace SimpleWeb {
|
|||
write(session);
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace SimpleWeb
|
||||
|
||||
#endif /* CLIENT_HTTP_HPP */
|
||||
|
|
|
|||
|
|
@ -17,10 +17,9 @@ namespace SimpleWeb {
|
|||
public:
|
||||
friend ClientBase<HTTPS>;
|
||||
|
||||
Client(const std::string& server_port_path, bool verify_certificate=true,
|
||||
const std::string& cert_file=std::string(), const std::string& private_key_file=std::string(),
|
||||
const std::string& verify_file=std::string()) :
|
||||
ClientBase<HTTPS>::ClientBase(server_port_path, 443), context(asio::ssl::context::tlsv12) {
|
||||
Client(const std::string &server_port_path, bool verify_certificate = true, const std::string &cert_file = std::string(),
|
||||
const std::string &private_key_file = std::string(), const std::string &verify_file = std::string())
|
||||
: ClientBase<HTTPS>::ClientBase(server_port_path, 443), context(asio::ssl::context::tlsv12) {
|
||||
if(cert_file.size() > 0 && private_key_file.size() > 0) {
|
||||
context.use_certificate_chain_file(cert_file);
|
||||
context.use_private_key_file(private_key_file, asio::ssl::context::pem);
|
||||
|
|
@ -64,7 +63,8 @@ namespace SimpleWeb {
|
|||
auto write_buffer = std::make_shared<asio::streambuf>();
|
||||
std::ostream write_stream(write_buffer.get());
|
||||
auto host_port = session->connection->host + ':' + std::to_string(session->connection->port);
|
||||
write_stream << "CONNECT "+host_port+" HTTP/1.1\r\n" << "Host: " << host_port << "\r\n\r\n";
|
||||
write_stream << "CONNECT " + host_port + " HTTP/1.1\r\n"
|
||||
<< "Host: " << host_port << "\r\n\r\n";
|
||||
auto timer = get_timeout_timer(session, session->connection->config.timeout_connect);
|
||||
asio::async_write(session->connection->socket->next_layer(), *write_buffer, [session, write_buffer, timer](const error_code &ec, size_t /*bytes_transferred*/) {
|
||||
if(timer)
|
||||
|
|
@ -129,6 +129,6 @@ namespace SimpleWeb {
|
|||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace SimpleWeb
|
||||
|
||||
#endif /* CLIENT_HTTPS_HPP */
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
#ifndef SIMPLE_WEB_CRYPTO_HPP
|
||||
#define SIMPLE_WEB_CRYPTO_HPP
|
||||
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//Moving these to a seperate namespace for minimal global namespace cluttering does not work with clang++
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
namespace SimpleWeb {
|
||||
//TODO 2017: remove workaround for MSVS 2012
|
||||
|
|
@ -24,6 +24,7 @@ namespace SimpleWeb {
|
|||
|
||||
class Crypto {
|
||||
const static size_t buffer_size = 131072;
|
||||
|
||||
public:
|
||||
class Base64 {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
#include "server_http.hpp"
|
||||
#include "client_http.hpp"
|
||||
#include "server_http.hpp"
|
||||
|
||||
//Added for the json-example
|
||||
#define BOOST_SPIRIT_THREADSAFE
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
//Added for the default_resource example
|
||||
#include <fstream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include "crypto.hpp"
|
||||
#endif
|
||||
|
|
@ -23,8 +23,7 @@ typedef SimpleWeb::Server<SimpleWeb::HTTP> HttpServer;
|
|||
typedef SimpleWeb::Client<SimpleWeb::HTTP> HttpClient;
|
||||
|
||||
//Added for the default_resource example
|
||||
void default_resource_send(const HttpServer &server, const shared_ptr<HttpServer::Response> &response,
|
||||
const shared_ptr<ifstream> &ifs);
|
||||
void default_resource_send(const HttpServer &server, const shared_ptr<HttpServer::Response> &response, const shared_ptr<ifstream> &ifs);
|
||||
|
||||
int main() {
|
||||
//HTTP-server at port 8080 using 1 thread
|
||||
|
|
@ -43,7 +42,8 @@ int main() {
|
|||
//ss << request->content.rdbuf();
|
||||
//auto content=ss.str();
|
||||
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n"
|
||||
<< content;
|
||||
|
||||
|
||||
// Alternatively, use one of the convenience functions, for instance:
|
||||
|
|
@ -71,7 +71,8 @@ int main() {
|
|||
<< name;
|
||||
}
|
||||
catch(const exception &e) {
|
||||
*response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n" << e.what();
|
||||
*response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n"
|
||||
<< e.what();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -100,7 +101,8 @@ int main() {
|
|||
//find length of content_stream (length received using content_stream.tellp())
|
||||
stream.seekp(0, ios::end);
|
||||
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << stream.tellp() << "\r\n\r\n" << stream.rdbuf();
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << stream.tellp() << "\r\n\r\n"
|
||||
<< stream.rdbuf();
|
||||
|
||||
|
||||
// Alternatively, using a convenience function:
|
||||
|
|
@ -116,7 +118,8 @@ int main() {
|
|||
//For instance a request GET /match/123 will receive: 123
|
||||
server.resource["^/match/([0-9]+)$"]["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
|
||||
string number = request->path_match[1];
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n"
|
||||
<< number;
|
||||
|
||||
|
||||
// Alternatively, using a convenience function:
|
||||
|
|
@ -223,12 +226,9 @@ int main() {
|
|||
client.io_service->run();
|
||||
|
||||
server_thread.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void default_resource_send(const HttpServer &server, const shared_ptr<HttpServer::Response> &response,
|
||||
const shared_ptr<ifstream> &ifs) {
|
||||
void default_resource_send(const HttpServer &server, const shared_ptr<HttpServer::Response> &response, const shared_ptr<ifstream> &ifs) {
|
||||
//read and send 128 KB at a time
|
||||
static vector<char> buffer(131072); // Safe when server is running on one thread
|
||||
streamsize read_length;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
#include "server_https.hpp"
|
||||
#include "client_https.hpp"
|
||||
#include "server_https.hpp"
|
||||
|
||||
//Added for the json-example
|
||||
#define BOOST_SPIRIT_THREADSAFE
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
//Added for the default_resource example
|
||||
#include <fstream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "crypto.hpp"
|
||||
#include <algorithm>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
//Added for the json-example:
|
||||
|
|
@ -21,8 +21,7 @@ typedef SimpleWeb::Server<SimpleWeb::HTTPS> HttpsServer;
|
|||
typedef SimpleWeb::Client<SimpleWeb::HTTPS> HttpsClient;
|
||||
|
||||
//Added for the default_resource example
|
||||
void default_resource_send(const HttpsServer &server, const shared_ptr<HttpsServer::Response> &response,
|
||||
const shared_ptr<ifstream> &ifs);
|
||||
void default_resource_send(const HttpsServer &server, const shared_ptr<HttpsServer::Response> &response, const shared_ptr<ifstream> &ifs);
|
||||
|
||||
int main() {
|
||||
//HTTPS-server at port 8080 using 1 thread
|
||||
|
|
@ -41,7 +40,8 @@ int main() {
|
|||
//ss << request->content.rdbuf();
|
||||
//auto content=ss.str();
|
||||
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n"
|
||||
<< content;
|
||||
|
||||
|
||||
// Alternatively, use one of the convenience functions, for instance:
|
||||
|
|
@ -69,7 +69,8 @@ int main() {
|
|||
<< name;
|
||||
}
|
||||
catch(const exception &e) {
|
||||
*response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n" << e.what();
|
||||
*response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n"
|
||||
<< e.what();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -98,7 +99,8 @@ int main() {
|
|||
//find length of content_stream (length received using content_stream.tellp())
|
||||
stream.seekp(0, ios::end);
|
||||
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << stream.tellp() << "\r\n\r\n" << stream.rdbuf();
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << stream.tellp() << "\r\n\r\n"
|
||||
<< stream.rdbuf();
|
||||
|
||||
|
||||
// Alternatively, using a convenience function:
|
||||
|
|
@ -114,7 +116,8 @@ int main() {
|
|||
//For instance a request GET /match/123 will receive: 123
|
||||
server.resource["^/match/([0-9]+)$"]["GET"] = [](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
|
||||
string number = request->path_match[1];
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n"
|
||||
<< number;
|
||||
|
||||
|
||||
// Alternatively, using a convenience function:
|
||||
|
|
@ -222,12 +225,9 @@ int main() {
|
|||
client.io_service->run();
|
||||
|
||||
server_thread.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void default_resource_send(const HttpsServer &server, const shared_ptr<HttpsServer::Response> &response,
|
||||
const shared_ptr<ifstream> &ifs) {
|
||||
void default_resource_send(const HttpsServer &server, const shared_ptr<HttpsServer::Response> &response, const shared_ptr<ifstream> &ifs) {
|
||||
//read and send 128 KB at a time
|
||||
static vector<char> buffer(131072); // Safe when server is running on one thread
|
||||
streamsize read_length;
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
#define SERVER_HTTP_HPP
|
||||
|
||||
#include "utility.hpp"
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
#ifdef USE_STANDALONE_ASIO
|
||||
#include <asio.hpp>
|
||||
|
|
@ -14,7 +14,7 @@ namespace SimpleWeb {
|
|||
using error_code = std::error_code;
|
||||
using errc = std::errc;
|
||||
namespace make_error_code = std;
|
||||
}
|
||||
} // namespace SimpleWeb
|
||||
#else
|
||||
#include <boost/asio.hpp>
|
||||
namespace SimpleWeb {
|
||||
|
|
@ -22,7 +22,7 @@ namespace SimpleWeb {
|
|||
using error_code = boost::system::error_code;
|
||||
namespace errc = boost::system::errc;
|
||||
namespace make_error_code = boost::system::errc;
|
||||
}
|
||||
} // namespace SimpleWeb
|
||||
#endif
|
||||
|
||||
// Late 2017 TODO: remove the following checks and always use std::regex
|
||||
|
|
@ -73,6 +73,7 @@ namespace SimpleWeb {
|
|||
else
|
||||
*this << "\r\n";
|
||||
}
|
||||
|
||||
public:
|
||||
size_t size() {
|
||||
return streambuf.size();
|
||||
|
|
@ -132,6 +133,7 @@ namespace SimpleWeb {
|
|||
|
||||
class Content : public std::istream {
|
||||
friend class ServerBase<socket_type>;
|
||||
|
||||
public:
|
||||
size_t size() {
|
||||
return streambuf.size();
|
||||
|
|
@ -142,6 +144,7 @@ namespace SimpleWeb {
|
|||
ss << rdbuf();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
asio::streambuf &streambuf;
|
||||
Content(asio::streambuf &streambuf) : std::istream(&streambuf), streambuf(streambuf) {}
|
||||
|
|
@ -150,6 +153,7 @@ namespace SimpleWeb {
|
|||
class Request {
|
||||
friend class ServerBase<socket_type>;
|
||||
friend class Server<socket_type>;
|
||||
|
||||
public:
|
||||
std::string method, path, http_version;
|
||||
|
||||
|
|
@ -177,7 +181,8 @@ namespace SimpleWeb {
|
|||
remote_endpoint_address = socket.lowest_layer().remote_endpoint().address().to_string();
|
||||
remote_endpoint_port = socket.lowest_layer().remote_endpoint().port();
|
||||
}
|
||||
catch(...) {}
|
||||
catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
asio::streambuf streambuf;
|
||||
|
|
@ -187,6 +192,7 @@ namespace SimpleWeb {
|
|||
friend class ServerBase<socket_type>;
|
||||
|
||||
Config(unsigned short port) : port(port) {}
|
||||
|
||||
public:
|
||||
/// Port number to use. Defaults to 80 for HTTP and 443 for HTTPS.
|
||||
unsigned short port;
|
||||
|
|
@ -208,6 +214,7 @@ namespace SimpleWeb {
|
|||
private:
|
||||
class regex_orderable : public regex::regex {
|
||||
std::string str;
|
||||
|
||||
public:
|
||||
regex_orderable(const char *regex_cstr) : regex::regex(regex_cstr), str(regex_cstr) {}
|
||||
regex_orderable(const std::string ®ex_str) : regex::regex(regex_str), str(regex_str) {}
|
||||
|
|
@ -215,13 +222,12 @@ namespace SimpleWeb {
|
|||
return str < rhs.str;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/// Warning: do not add or remove resources after start() is called
|
||||
std::map<regex_orderable, std::map<std::string,
|
||||
std::function<void(std::shared_ptr<typename ServerBase<socket_type>::Response>, std::shared_ptr<typename ServerBase<socket_type>::Request>)> > > resource;
|
||||
std::map<regex_orderable, std::map<std::string, std::function<void(std::shared_ptr<typename ServerBase<socket_type>::Response>, std::shared_ptr<typename ServerBase<socket_type>::Request>)>>> resource;
|
||||
|
||||
std::map<std::string,
|
||||
std::function<void(std::shared_ptr<typename ServerBase<socket_type>::Response>, std::shared_ptr<typename ServerBase<socket_type>::Request>)> > default_resource;
|
||||
std::map<std::string, std::function<void(std::shared_ptr<typename ServerBase<socket_type>::Response>, std::shared_ptr<typename ServerBase<socket_type>::Request>)>> default_resource;
|
||||
|
||||
std::function<void(std::shared_ptr<typename ServerBase<socket_type>::Request>, const error_code &)> on_error;
|
||||
|
||||
|
|
@ -284,6 +290,7 @@ namespace SimpleWeb {
|
|||
/// If you have your own asio::io_service, store its pointer here before running start().
|
||||
/// You might also want to set config.thread_pool_size to 0.
|
||||
std::shared_ptr<asio::io_service> io_service;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<asio::ip::tcp::acceptor> acceptor;
|
||||
std::vector<std::thread> threads;
|
||||
|
|
@ -316,8 +323,7 @@ namespace SimpleWeb {
|
|||
//Set timeout on the following asio::async-read or write function
|
||||
auto timer = this->get_timeout_timer(socket, config.timeout_request);
|
||||
|
||||
asio::async_read_until(*socket, request->streambuf, "\r\n\r\n",
|
||||
[this, socket, request, timer](const error_code& ec, size_t bytes_transferred) {
|
||||
asio::async_read_until(*socket, request->streambuf, "\r\n\r\n", [this, socket, request, timer](const error_code &ec, size_t bytes_transferred) {
|
||||
if(timer)
|
||||
timer->cancel();
|
||||
if(!ec) {
|
||||
|
|
@ -345,10 +351,7 @@ namespace SimpleWeb {
|
|||
if(content_length > num_additional_bytes) {
|
||||
//Set timeout on the following asio::async-read or write function
|
||||
auto timer = this->get_timeout_timer(socket, config.timeout_content);
|
||||
asio::async_read(*socket, request->streambuf,
|
||||
asio::transfer_exactly(content_length-num_additional_bytes),
|
||||
[this, socket, request, timer]
|
||||
(const error_code& ec, size_t /*bytes_transferred*/) {
|
||||
asio::async_read(*socket, request->streambuf, asio::transfer_exactly(content_length - num_additional_bytes), [this, socket, request, timer](const error_code &ec, size_t /*bytes_transferred*/) {
|
||||
if(timer)
|
||||
timer->cancel();
|
||||
if(!ec)
|
||||
|
|
@ -437,8 +440,7 @@ namespace SimpleWeb {
|
|||
}
|
||||
|
||||
void write_response(const std::shared_ptr<socket_type> &socket, const std::shared_ptr<Request> &request,
|
||||
std::function<void(std::shared_ptr<typename ServerBase<socket_type>::Response>,
|
||||
std::shared_ptr<typename ServerBase<socket_type>::Request>)>& resource_function) {
|
||||
std::function<void(std::shared_ptr<typename ServerBase<socket_type>::Response>, std::shared_ptr<typename ServerBase<socket_type>::Request>)> &resource_function) {
|
||||
//Set timeout on the following asio::async-read or write function
|
||||
auto timer = this->get_timeout_timer(socket, config.timeout_content);
|
||||
|
||||
|
|
@ -455,7 +457,8 @@ namespace SimpleWeb {
|
|||
for(auto it = range.first; it != range.second; it++) {
|
||||
if(case_insensitive_equal(it->second, "close")) {
|
||||
return;
|
||||
} else if (case_insensitive_equal(it->second, "keep-alive")) {
|
||||
}
|
||||
else if(case_insensitive_equal(it->second, "keep-alive")) {
|
||||
this->read_request_and_content(response->socket);
|
||||
return;
|
||||
}
|
||||
|
|
@ -487,8 +490,7 @@ namespace SimpleWeb {
|
|||
template <>
|
||||
class Server<HTTP> : public ServerBase<HTTP> {
|
||||
public:
|
||||
DEPRECATED Server(unsigned short port, size_t thread_pool_size=1, long timeout_request=5, long timeout_content=300) :
|
||||
Server() {
|
||||
DEPRECATED Server(unsigned short port, size_t thread_pool_size = 1, long timeout_request = 5, long timeout_content = 300) : Server() {
|
||||
config.port = port;
|
||||
config.thread_pool_size = thread_pool_size;
|
||||
config.timeout_request = timeout_request;
|
||||
|
|
@ -519,5 +521,6 @@ namespace SimpleWeb {
|
|||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace SimpleWeb
|
||||
|
||||
#endif /* SERVER_HTTP_HPP */
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
#include <boost/asio/ssl.hpp>
|
||||
#endif
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <algorithm>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
namespace SimpleWeb {
|
||||
typedef asio::ssl::stream<asio::ip::tcp::socket> HTTPS;
|
||||
|
|
@ -19,26 +19,25 @@ namespace SimpleWeb {
|
|||
class Server<HTTPS> : public ServerBase<HTTPS> {
|
||||
std::string session_id_context;
|
||||
bool set_session_id_context = false;
|
||||
|
||||
public:
|
||||
DEPRECATED Server(unsigned short port, size_t thread_pool_size, const std::string &cert_file, const std::string &private_key_file,
|
||||
long timeout_request=5, long timeout_content=300,
|
||||
const std::string& verify_file=std::string()) :
|
||||
Server(cert_file, private_key_file, verify_file) {
|
||||
long timeout_request = 5, long timeout_content = 300, const std::string &verify_file = std::string())
|
||||
: Server(cert_file, private_key_file, verify_file) {
|
||||
config.port = port;
|
||||
config.thread_pool_size = thread_pool_size;
|
||||
config.timeout_request = timeout_request;
|
||||
config.timeout_content = timeout_content;
|
||||
}
|
||||
|
||||
Server(const std::string& cert_file, const std::string& private_key_file, const std::string& verify_file=std::string()):
|
||||
ServerBase<HTTPS>::ServerBase(443), context(asio::ssl::context::tlsv12) {
|
||||
Server(const std::string &cert_file, const std::string &private_key_file, const std::string &verify_file = std::string())
|
||||
: ServerBase<HTTPS>::ServerBase(443), context(asio::ssl::context::tlsv12) {
|
||||
context.use_certificate_chain_file(cert_file);
|
||||
context.use_private_key_file(private_key_file, asio::ssl::context::pem);
|
||||
|
||||
if(verify_file.size() > 0) {
|
||||
context.load_verify_file(verify_file);
|
||||
context.set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert |
|
||||
asio::ssl::verify_client_once);
|
||||
context.set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert | asio::ssl::verify_client_once);
|
||||
set_session_id_context = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -74,8 +73,7 @@ namespace SimpleWeb {
|
|||
|
||||
//Set timeout on the following asio::ssl::stream::async_handshake
|
||||
auto timer = get_timeout_timer(socket, config.timeout_request);
|
||||
socket->async_handshake(asio::ssl::stream_base::server, [this, socket, timer]
|
||||
(const error_code& ec) {
|
||||
socket->async_handshake(asio::ssl::stream_base::server, [this, socket, timer](const error_code &ec) {
|
||||
if(timer)
|
||||
timer->cancel();
|
||||
if(!ec)
|
||||
|
|
@ -89,8 +87,6 @@ namespace SimpleWeb {
|
|||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace SimpleWeb
|
||||
|
||||
#endif /* SERVER_HTTPS_HPP */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
#include "crypto.hpp"
|
||||
|
||||
|
|
@ -13,28 +13,23 @@ const vector<pair<string, string> > base64_string_tests = {
|
|||
{"foo", "Zm9v"},
|
||||
{"foob", "Zm9vYg=="},
|
||||
{"fooba", "Zm9vYmE="},
|
||||
{"foobar", "Zm9vYmFy"}
|
||||
};
|
||||
{"foobar", "Zm9vYmFy"}};
|
||||
|
||||
const vector<pair<string, string>> md5_string_tests = {
|
||||
{"", "d41d8cd98f00b204e9800998ecf8427e"},
|
||||
{"The quick brown fox jumps over the lazy dog", "9e107d9d372bb6826bd81d3542a419d6"}
|
||||
};
|
||||
{"The quick brown fox jumps over the lazy dog", "9e107d9d372bb6826bd81d3542a419d6"}};
|
||||
|
||||
const vector<pair<string, string>> sha1_string_tests = {
|
||||
{"", "da39a3ee5e6b4b0d3255bfef95601890afd80709"},
|
||||
{"The quick brown fox jumps over the lazy dog", "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"}
|
||||
};
|
||||
{"The quick brown fox jumps over the lazy dog", "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"}};
|
||||
|
||||
const vector<pair<string, string>> sha256_string_tests = {
|
||||
{"", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
|
||||
{"The quick brown fox jumps over the lazy dog", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"}
|
||||
};
|
||||
{"The quick brown fox jumps over the lazy dog", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"}};
|
||||
|
||||
const vector<pair<string, string>> sha512_string_tests = {
|
||||
{"", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"},
|
||||
{"The quick brown fox jumps over the lazy dog", "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6"}
|
||||
};
|
||||
{"The quick brown fox jumps over the lazy dog", "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6"}};
|
||||
|
||||
int main() {
|
||||
for(auto &string_test : base64_string_tests) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "server_http.hpp"
|
||||
#include "client_http.hpp"
|
||||
#include "server_http.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
|
@ -15,7 +15,8 @@ int main() {
|
|||
server.resource["^/string$"]["POST"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
|
||||
auto content = request->content.string();
|
||||
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n"
|
||||
<< content;
|
||||
};
|
||||
|
||||
server.resource["^/string2$"]["POST"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
|
||||
|
|
@ -39,18 +40,21 @@ int main() {
|
|||
|
||||
content_stream.seekp(0, ios::end);
|
||||
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content_stream.tellp() << "\r\n\r\n" << content_stream.rdbuf();
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content_stream.tellp() << "\r\n\r\n"
|
||||
<< content_stream.rdbuf();
|
||||
};
|
||||
|
||||
server.resource["^/match/([0-9]+)$"]["GET"] = [&server](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
|
||||
string number = request->path_match[1];
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n"
|
||||
<< number;
|
||||
};
|
||||
|
||||
server.resource["^/header$"]["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
|
||||
auto content = request->header.find("test1")->second + request->header.find("test2")->second;
|
||||
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
|
||||
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n"
|
||||
<< content;
|
||||
};
|
||||
|
||||
thread server_thread([&server]() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "server_http.hpp"
|
||||
#include "client_http.hpp"
|
||||
#include <iostream>
|
||||
#include "server_http.hpp"
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace SimpleWeb;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue