Cookie and Header parsing
This commit is contained in:
parent
c567bb2447
commit
21afe9ca13
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "method.h"
|
#include <rum/http/method.h>
|
||||||
#include "request.h"
|
#include <rum/http/request.h>
|
||||||
#include "response.h"
|
#include <rum/http/response.h>
|
||||||
#include "server.h"
|
#include <rum/http/server.h>
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Rum::HTTP {
|
namespace Rum::HTTP {
|
||||||
|
|
||||||
enum Method { GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE };
|
enum Method { GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE };
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <rum/http/method.h>
|
||||||
|
#include <rum/http/uri.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "method.h"
|
|
||||||
#include "rum/http/uri.h"
|
|
||||||
|
|
||||||
namespace Rum::HTTP {
|
namespace Rum::HTTP {
|
||||||
class Request {
|
class Request {
|
||||||
@ -12,12 +12,16 @@ class Request {
|
|||||||
Request(Method method, const URI& uri) : method(method), uri(uri), body("") {}
|
Request(Method method, const URI& uri) : method(method), uri(uri), body("") {}
|
||||||
|
|
||||||
Method get_method() const { return method; }
|
Method get_method() const { return method; }
|
||||||
const URI& get_uri() const { return uri; }
|
URI& get_uri() { return uri; }
|
||||||
|
|
||||||
const std::map<std::string, std::string>& get_headers() const { return headers; }
|
const std::map<std::string, std::string>& get_headers() const { return headers; }
|
||||||
std::string get_header(std::string name) const { return headers.at(name); }
|
std::string get_header(std::string name) const { return headers.at(name); }
|
||||||
void set_header(std::string name, std::string value) { headers[name] = value; }
|
void set_header(std::string name, std::string value) { headers[name] = value; }
|
||||||
|
|
||||||
|
const std::map<std::string, std::string>& get_cookies() const { return cookies; }
|
||||||
|
std::string get_cookie(std::string name) const { return cookies.at(name); }
|
||||||
|
void set_cookie(std::string name, std::string value) { cookies[name] = value; }
|
||||||
|
|
||||||
std::string get_body() const { return body; }
|
std::string get_body() const { return body; }
|
||||||
void set_body(std::string body) { this->body = body; }
|
void set_body(std::string body) { this->body = body; }
|
||||||
|
|
||||||
@ -29,6 +33,7 @@ class Request {
|
|||||||
Method method;
|
Method method;
|
||||||
URI uri;
|
URI uri;
|
||||||
std::map<std::string, std::string> headers;
|
std::map<std::string, std::string> headers;
|
||||||
|
std::map<std::string, std::string> cookies;
|
||||||
std::string body;
|
std::string body;
|
||||||
};
|
};
|
||||||
} // namespace Rum::HTTP
|
} // namespace Rum::HTTP
|
@ -1,22 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Rum::HTTP {
|
namespace Rum::HTTP {
|
||||||
class Response {
|
class Response {
|
||||||
private:
|
private:
|
||||||
const int client_sock;
|
const int client_sock;
|
||||||
bool sent_header;
|
|
||||||
bool sent_body;
|
|
||||||
bool closed;
|
|
||||||
unsigned int code;
|
unsigned int code;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Response(int client_sock) : client_sock(client_sock), sent_header(false), sent_body(false), closed(false), code(200) {}
|
Response(int client_sock) : client_sock(client_sock), code(200) {}
|
||||||
~Response();
|
~Response();
|
||||||
|
|
||||||
void send_header(const std::string& name, const std::string& value);
|
void set_code(unsigned int code) {
|
||||||
void send_body(const std::string& value);
|
if (code >= 100 && code < 600)
|
||||||
void set_code(unsigned int code) { this->code = code; }
|
this->code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> cookies;
|
||||||
|
std::map<std::string, std::string> headers;
|
||||||
|
std::string body;
|
||||||
};
|
};
|
||||||
} // namespace Rum::HTTP
|
} // namespace Rum::HTTP
|
@ -7,9 +7,9 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../tcp/server.h"
|
#include <rum/tcp/server.h>
|
||||||
#include "request.h"
|
#include <rum/http/request.h>
|
||||||
#include "response.h"
|
#include <rum/http/response.h>
|
||||||
|
|
||||||
#define DEFAULT_WORKER_COUNT 10
|
#define DEFAULT_WORKER_COUNT 10
|
||||||
#define DEFAULT_BUFFER_SIZE 8196
|
#define DEFAULT_BUFFER_SIZE 8196
|
||||||
|
@ -29,6 +29,9 @@ class URI {
|
|||||||
const std::map<std::string, std::string>& get_parameters() const { return parameters; }
|
const std::map<std::string, std::string>& get_parameters() const { return parameters; }
|
||||||
const std::string& get_fragment() const { return fragment; }
|
const std::string& get_fragment() const { return fragment; }
|
||||||
|
|
||||||
|
void set_host(const std::string& host) { this->host = host; }
|
||||||
|
void set_port(const std::string& port) { this->port = port; }
|
||||||
|
|
||||||
operator std::string() const;
|
operator std::string() const;
|
||||||
};
|
};
|
||||||
} // namespace Rum::HTTP
|
} // namespace Rum::HTTP
|
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "error.h"
|
#include <rum/tcp/error.h>
|
||||||
#include "server.h"
|
#include <rum/tcp/server.h>
|
||||||
#include "utility.h"
|
#include <rum/tcp/utility.h>
|
@ -1,8 +1,8 @@
|
|||||||
|
#include <rum/http/method.h>
|
||||||
#include <rum/http/request.h>
|
#include <rum/http/request.h>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "rum/http/method.h"
|
|
||||||
|
|
||||||
namespace Rum::HTTP {
|
namespace Rum::HTTP {
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ Request::operator std::string() const {
|
|||||||
"\tmethod: {}\n"
|
"\tmethod: {}\n"
|
||||||
"\t{}\n"
|
"\t{}\n"
|
||||||
"\theaders: \n{}"
|
"\theaders: \n{}"
|
||||||
"\tbody: \n'{}'"
|
"\tbody: '{}'\n"
|
||||||
"}}",
|
"}}",
|
||||||
std::make_format_args(to_string(method), (std::string)uri, headers_string, body));
|
std::make_format_args(to_string(method), (std::string)uri, headers_string, body));
|
||||||
}
|
}
|
||||||
|
@ -1,72 +1,73 @@
|
|||||||
#include <rum/http/response.h>
|
#include <rum/http/response.h>
|
||||||
#include <rum/tcp/error.h>
|
#include <rum/tcp/error.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <format>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace Rum::HTTP {
|
namespace Rum::HTTP {
|
||||||
std::string to_string(int code) {
|
std::string to_string(int code) {
|
||||||
static const std::map<int, std::string> codes{{100, "Continue"},
|
static const std::map<int, std::string> codes{{100, "Continue"},
|
||||||
{101, "Switching Protocols"},
|
{101, "Switching Protocols"},
|
||||||
{102, "Processing"},
|
{102, "Processing"},
|
||||||
{103, "Early Hints"},
|
{103, "Early Hints"},
|
||||||
{200, "OK"},
|
{200, "OK"},
|
||||||
{201, "Created"},
|
{201, "Created"},
|
||||||
{202, "Accepted"},
|
{202, "Accepted"},
|
||||||
{203, "Non-Authoritative Information"},
|
{203, "Non-Authoritative Information"},
|
||||||
{204, "No Content"},
|
{204, "No Content"},
|
||||||
{205, "Reset Content"},
|
{205, "Reset Content"},
|
||||||
{206, "Partial Content"},
|
{206, "Partial Content"},
|
||||||
{207, "Multi-Status"},
|
{207, "Multi-Status"},
|
||||||
{208, "Already Reported"},
|
{208, "Already Reported"},
|
||||||
{226, "IM Used"},
|
{226, "IM Used"},
|
||||||
{300, "Multiple Choices"},
|
{300, "Multiple Choices"},
|
||||||
{301, "Moved Permanently"},
|
{301, "Moved Permanently"},
|
||||||
{302, "Found"},
|
{302, "Found"},
|
||||||
{303, "See Other"},
|
{303, "See Other"},
|
||||||
{304, "Not Modified"},
|
{304, "Not Modified"},
|
||||||
{307, "Temporary Redirect"},
|
{307, "Temporary Redirect"},
|
||||||
{308, "Permanent Redirect"},
|
{308, "Permanent Redirect"},
|
||||||
{400, "Bad Request"},
|
{400, "Bad Request"},
|
||||||
{401, "Unauthorized"},
|
{401, "Unauthorized"},
|
||||||
{402, "Payment Required"},
|
{402, "Payment Required"},
|
||||||
{403, "Forbidden"},
|
{403, "Forbidden"},
|
||||||
{404, "Not Found"},
|
{404, "Not Found"},
|
||||||
{405, "Method Not Allowed"},
|
{405, "Method Not Allowed"},
|
||||||
{406, "Not Acceptable"},
|
{406, "Not Acceptable"},
|
||||||
{407, "Proxy Authentication Required"},
|
{407, "Proxy Authentication Required"},
|
||||||
{408, "Request Timeout"},
|
{408, "Request Timeout"},
|
||||||
{409, "Conflict"},
|
{409, "Conflict"},
|
||||||
{410, "Gone"},
|
{410, "Gone"},
|
||||||
{411, "Length Required"},
|
{411, "Length Required"},
|
||||||
{412, "Precondition Failed"},
|
{412, "Precondition Failed"},
|
||||||
{413, "Content Too Large"},
|
{413, "Content Too Large"},
|
||||||
{414, "URI Too Long"},
|
{414, "URI Too Long"},
|
||||||
{415, "Unsupported Media Type"},
|
{415, "Unsupported Media Type"},
|
||||||
{416, "Range Not Satisfiable"},
|
{416, "Range Not Satisfiable"},
|
||||||
{417, "Expectation Failed"},
|
{417, "Expectation Failed"},
|
||||||
{418, "I'm a teapot"},
|
{418, "I'm a teapot"},
|
||||||
{421, "Misdirected Request"},
|
{421, "Misdirected Request"},
|
||||||
{422, "Unprocessable Content"},
|
{422, "Unprocessable Content"},
|
||||||
{423, "Locked"},
|
{423, "Locked"},
|
||||||
{424, "Failed Dependency"},
|
{424, "Failed Dependency"},
|
||||||
{425, "Too Early"},
|
{425, "Too Early"},
|
||||||
{426, "Upgrade Required"},
|
{426, "Upgrade Required"},
|
||||||
{428, "Precondition Required"},
|
{428, "Precondition Required"},
|
||||||
{429, "Too Many Requests"},
|
{429, "Too Many Requests"},
|
||||||
{431, "Request Header Fields Too Large"},
|
{431, "Request Header Fields Too Large"},
|
||||||
{451, "Unavailable For Legal Reasons"},
|
{451, "Unavailable For Legal Reasons"},
|
||||||
{500, "Internal Server Error"},
|
{500, "Internal Server Error"},
|
||||||
{501, "Not Implemented"},
|
{501, "Not Implemented"},
|
||||||
{502, "Bad Gateway"},
|
{502, "Bad Gateway"},
|
||||||
{503, "Service Unavailable"},
|
{503, "Service Unavailable"},
|
||||||
{504, "Gateway Timeout"},
|
{504, "Gateway Timeout"},
|
||||||
{505, "HTTP Version Not Supported"},
|
{505, "HTTP Version Not Supported"},
|
||||||
{506, "Variant Also Negotiates"},
|
{506, "Variant Also Negotiates"},
|
||||||
{507, "Insufficient Storage"},
|
{507, "Insufficient Storage"},
|
||||||
{508, "Loop Detected"},
|
{508, "Loop Detected"},
|
||||||
{510, "Not Extended"},
|
{510, "Not Extended"},
|
||||||
{511, "Network Authentication Required"}};
|
{511, "Network Authentication Required"}};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return codes.at(code);
|
return codes.at(code);
|
||||||
@ -75,47 +76,21 @@ std::string to_string(int code) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Response::send_header(const std::string& name, const std::string& value) {
|
|
||||||
if (!sent_header) {
|
|
||||||
std::string resp("HTTP/1.1 " + std::to_string(code) + " " + to_string(code) + "\r\n");
|
|
||||||
if (-1 == send(client_sock, resp.c_str(), resp.size(), 0)) {
|
|
||||||
closed = true;
|
|
||||||
throw TCP::Error(TCP::Error::CLOSED);
|
|
||||||
}
|
|
||||||
sent_header = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string header = name + ": " + value + "\r\n";
|
|
||||||
if (-1 == send(client_sock, header.c_str(), header.size(), 0)) {
|
|
||||||
closed = true;
|
|
||||||
throw TCP::Error(TCP::Error::CLOSED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Response::send_body(const std::string& value) {
|
|
||||||
if (!sent_header) {
|
|
||||||
send_header("Content-Type", "text/html");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sent_body) {
|
|
||||||
if (-1 == send(client_sock, "\r\n", 2, 0)) {
|
|
||||||
closed = true;
|
|
||||||
throw TCP::Error(TCP::Error::CLOSED);
|
|
||||||
}
|
|
||||||
sent_body = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-1 == send(client_sock, value.c_str(), value.size(), 0)) {
|
|
||||||
closed = true;
|
|
||||||
throw TCP::Error(TCP::Error::CLOSED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Response::~Response() {
|
Response::~Response() {
|
||||||
if (!sent_header && !closed) {
|
std::string headers_string;
|
||||||
std::string resp("HTTP/1.1 " + std::to_string(code) + " " + to_string(code));
|
for (auto header : headers) {
|
||||||
send(client_sock, resp.c_str(), resp.size(), 0);
|
headers_string += header.first + ": " + header.second + "\r\n";
|
||||||
|
}
|
||||||
|
for (auto cookie : cookies) {
|
||||||
|
headers_string += "Set-cookie: " + cookie.first + "=" + cookie.second + "\r\n";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
std::string message = std::vformat(
|
||||||
|
"HTTP/1.1 {} {}\r\n"
|
||||||
|
"{}"
|
||||||
|
"\r\n"
|
||||||
|
"{}",
|
||||||
|
std::make_format_args(std::to_string(code), to_string(code), headers_string, body));
|
||||||
|
send(client_sock, message.c_str(), message.size(), 0);
|
||||||
|
}
|
||||||
} // namespace Rum::HTTP
|
} // namespace Rum::HTTP
|
@ -1,6 +1,6 @@
|
|||||||
#include "rum/tcp/server.h"
|
|
||||||
#include <rum/http/server.h>
|
#include <rum/http/server.h>
|
||||||
#include <rum/tcp/error.h>
|
#include <rum/tcp/error.h>
|
||||||
|
#include <rum/tcp/server.h>
|
||||||
#include <rum/tcp/utility.h>
|
#include <rum/tcp/utility.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
@ -101,10 +101,10 @@ void Server::handler(int client_sock, const sockaddr_in& client_address, char* b
|
|||||||
ssize_t recieved = recv(client_sock, buffer, buffer_size, 0);
|
ssize_t recieved = recv(client_sock, buffer, buffer_size, 0);
|
||||||
switch (recieved) {
|
switch (recieved) {
|
||||||
case TCP::Error::CLOSED:
|
case TCP::Error::CLOSED:
|
||||||
std::cout << address << ": connection closed" << std::endl;
|
std::cerr << address << ": connection closed" << std::endl;
|
||||||
return;
|
return;
|
||||||
case TCP::Error::UNKNOWN:
|
case TCP::Error::UNKNOWN:
|
||||||
std::cout << "socket error" << std::endl;
|
std::cerr << "socket error" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +114,12 @@ void Server::handler(int client_sock, const sockaddr_in& client_address, char* b
|
|||||||
std::regex method_regex("(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE) (\\/.*) HTTP.*");
|
std::regex method_regex("(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE) (\\/.*) HTTP.*");
|
||||||
std::smatch match;
|
std::smatch match;
|
||||||
if (std::regex_match(message.cbegin(), message.cbegin() + message.find("\r\n"), match, method_regex)) {
|
if (std::regex_match(message.cbegin(), message.cbegin() + message.find("\r\n"), match, method_regex)) {
|
||||||
// create request object
|
try {
|
||||||
request = Request(string_to_method(match.str(1)), URI("http://0.0.0.0:" + std::to_string(TCP::Server::get_port()) + match.str(2)));
|
request = Request(string_to_method(match.str(1)), URI("http://0.0.0.0:" + std::to_string(TCP::Server::get_port()) + match.str(2)));
|
||||||
|
} catch (std::exception&) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
message = message.substr(message.find("\r\n"));
|
message = message.substr(message.find("\r\n"));
|
||||||
stage = HEADER;
|
stage = HEADER;
|
||||||
} else {
|
} else {
|
||||||
@ -127,7 +131,29 @@ void Server::handler(int client_sock, const sockaddr_in& client_address, char* b
|
|||||||
std::regex header_regex("(.*): (.*)");
|
std::regex header_regex("(.*): (.*)");
|
||||||
for (std::sregex_iterator it = std::sregex_iterator(message.cbegin(), message.cbegin() + message.find("\r\n\r\n"), header_regex);
|
for (std::sregex_iterator it = std::sregex_iterator(message.cbegin(), message.cbegin() + message.find("\r\n\r\n"), header_regex);
|
||||||
it != std::sregex_iterator(); it++) {
|
it != std::sregex_iterator(); it++) {
|
||||||
request.set_header(it->str(1), it->str(2));
|
std::string key(it->str(1));
|
||||||
|
std::string value(it->str(2));
|
||||||
|
|
||||||
|
if (key == "Host") {
|
||||||
|
if (size_t pos = value.find(':'); pos != value.npos) {
|
||||||
|
request.get_uri().set_host(value.substr(0, pos));
|
||||||
|
request.get_uri().set_port(value.substr(pos + 1));
|
||||||
|
} else {
|
||||||
|
request.get_uri().set_host(value);
|
||||||
|
}
|
||||||
|
} else if (key == "Cookie") {
|
||||||
|
std::stringstream cookies_string(value);
|
||||||
|
std::string cookie;
|
||||||
|
while (std::getline(cookies_string, cookie, ';')) {
|
||||||
|
if (size_t pos = cookie.find('='); pos != cookie.npos) {
|
||||||
|
request.set_cookie(cookie.substr(0, pos), cookie.substr(pos + 1));
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
request.set_header(it->str(1), it->str(2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
message = message.substr(message.find("\r\n\r\n"));
|
message = message.substr(message.find("\r\n\r\n"));
|
||||||
|
|
||||||
@ -143,10 +169,9 @@ void Server::handler(int client_sock, const sockaddr_in& client_address, char* b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << request << std::endl;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Response resp(client_sock);
|
Response resp(client_sock);
|
||||||
|
resp.headers["Content-type"] = "text/html";
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
@ -160,7 +185,7 @@ void Server::handler(int client_sock, const sockaddr_in& client_address, char* b
|
|||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
resp.set_code(404);
|
resp.set_code(404);
|
||||||
resp.send_body("<h1>404: Page not found :C</h1>");
|
resp.body = "<h1>404: Page not found :C</h1>";
|
||||||
}
|
}
|
||||||
} catch (std::out_of_range) {
|
} catch (std::out_of_range) {
|
||||||
} catch (TCP::Error) {
|
} catch (TCP::Error) {
|
||||||
|
@ -4,10 +4,6 @@
|
|||||||
#include <regex>
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define MATCH(var, i) \
|
|
||||||
if (match[i].matched) \
|
|
||||||
var = match.str(i);
|
|
||||||
|
|
||||||
namespace Rum::HTTP {
|
namespace Rum::HTTP {
|
||||||
|
|
||||||
URI::operator std::string() const {
|
URI::operator std::string() const {
|
||||||
@ -38,6 +34,10 @@ URI::URI(const std::string& uri) {
|
|||||||
std::cout << uri << std::endl;
|
std::cout << uri << std::endl;
|
||||||
|
|
||||||
if (std::regex_match(uri.cbegin(), uri.cend(), match, uri_regex)) {
|
if (std::regex_match(uri.cbegin(), uri.cend(), match, uri_regex)) {
|
||||||
|
#define MATCH(var, i) \
|
||||||
|
if (match[i].matched) \
|
||||||
|
var = match.str(i);
|
||||||
|
|
||||||
MATCH(scheme, 2)
|
MATCH(scheme, 2)
|
||||||
MATCH(user, 4)
|
MATCH(user, 4)
|
||||||
MATCH(password, 6)
|
MATCH(password, 6)
|
||||||
|
@ -29,14 +29,15 @@ int main(int argc, char** argv) {
|
|||||||
server->end();
|
server->end();
|
||||||
});
|
});
|
||||||
|
|
||||||
server->add_path<Rum::HTTP::GET>("/asd", [](const Rum::HTTP::Request& req, Rum::HTTP::Response& resp) {
|
server->add_path<Rum::HTTP::GET>("/asd(/?|/.*)", [](const Rum::HTTP::Request& req, Rum::HTTP::Response& resp) {
|
||||||
std::cout << "request accepted" << std::endl;
|
std::cout << "request accepted" << std::endl;
|
||||||
resp.send_body("<h1>asd</h1><pre>" + (std::string)req + "</pre>");
|
resp.headers["Server"] = "Rum Barrel";
|
||||||
|
resp.body = "<h1>asd</h1><pre>" + (std::string)req + "</pre>";
|
||||||
});
|
});
|
||||||
|
|
||||||
server->add_path<Rum::HTTP::GET>("/.*", [](const Rum::HTTP::Request& req, Rum::HTTP::Response& resp) {
|
server->add_path<Rum::HTTP::GET>("/.*", [](const Rum::HTTP::Request& req, Rum::HTTP::Response& resp) {
|
||||||
std::cout << "request accepted" << std::endl;
|
std::cout << "request accepted" << std::endl;
|
||||||
resp.send_body("<h1>Hello World</h1><pre>" + (std::string)req + "</pre>");
|
resp.body = "<h1>Hello World</h1><pre>" + (std::string)req + "</pre>";
|
||||||
});
|
});
|
||||||
|
|
||||||
server->listen();
|
server->listen();
|
||||||
|
Loading…
Reference in New Issue
Block a user