mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 14:29:10 -07:00
Added Context struct.
This commit is contained in:
parent
3464386f17
commit
277d7c0854
2 changed files with 66 additions and 33 deletions
|
@ -14,17 +14,17 @@ int main(void)
|
||||||
|
|
||||||
Server svr;
|
Server svr;
|
||||||
|
|
||||||
svr.post("/", [](const Request& /*req*/, Response& res) {
|
svr.get("/", [](Context& cxt) {
|
||||||
res.body_ = "<html><head></head><body><ul></ul></body></html>";
|
cxt.response.body = "<html><head></head><body><ul></ul></body></html>";
|
||||||
});
|
});
|
||||||
|
|
||||||
svr.post("/item", [](const Request& req, Response& res) {
|
svr.post("/item", [](Context& cxt) {
|
||||||
res.body_ = req.pattern_;
|
cxt.response.body = cxt.request.pattern;
|
||||||
});
|
});
|
||||||
|
|
||||||
svr.get("/item/:name", [](const Request& req, Response& res) {
|
svr.get("/item/:name", [](Context& cxt) {
|
||||||
try {
|
try {
|
||||||
res.body_ = req.params_.at("name");
|
cxt.response.body = cxt.request.params.at("name");
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// Error...
|
// Error...
|
||||||
}
|
}
|
||||||
|
|
87
httpsvrkit.h
87
httpsvrkit.h
|
@ -37,27 +37,32 @@ typedef int socket_t;
|
||||||
namespace httpsvrkit
|
namespace httpsvrkit
|
||||||
{
|
{
|
||||||
|
|
||||||
// HTTP request
|
typedef std::map<std::string, std::string> Map;
|
||||||
class Request {
|
typedef std::multimap<std::string, std::string> MultiMap;
|
||||||
public:
|
|
||||||
std::map<std::string, std::string> headers_;
|
|
||||||
std::string body_;
|
|
||||||
|
|
||||||
std::string pattern_;
|
// HTTP request
|
||||||
std::map<std::string, std::string> params_;
|
struct Request {
|
||||||
|
Map headers;
|
||||||
|
std::string body;
|
||||||
|
std::string pattern;
|
||||||
|
Map params;
|
||||||
};
|
};
|
||||||
|
|
||||||
// HTTP response
|
// HTTP response
|
||||||
class Response {
|
struct Response {
|
||||||
public:
|
MultiMap headers;
|
||||||
std::multimap<std::string, std::string> headers_;
|
std::string body;
|
||||||
std::string body_;
|
};
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
const Request request;
|
||||||
|
Response response;
|
||||||
};
|
};
|
||||||
|
|
||||||
// HTTP server
|
// HTTP server
|
||||||
class Server {
|
class Server {
|
||||||
public:
|
public:
|
||||||
typedef std::function<void (const Request&, Response& res)> Handler;
|
typedef std::function<void (Context& context)> Handler;
|
||||||
|
|
||||||
Server();
|
Server();
|
||||||
~Server();
|
~Server();
|
||||||
|
@ -71,8 +76,6 @@ public:
|
||||||
private:
|
private:
|
||||||
void process_request(int fd);
|
void process_request(int fd);
|
||||||
|
|
||||||
const size_t BUFSIZ_REQUESTLINE = 2048;
|
|
||||||
|
|
||||||
socket_t sock_;
|
socket_t sock_;
|
||||||
std::multimap<std::string, Handler> handlers_;
|
std::multimap<std::string, Handler> handlers_;
|
||||||
};
|
};
|
||||||
|
@ -200,18 +203,41 @@ inline void Server::stop()
|
||||||
sock_ = -1;
|
sock_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool parse_request_line(const char* s, std::string& cmd, std::string& url)
|
inline bool read_request_line(FILE* fp, std::string& method, std::string& url)
|
||||||
{
|
{
|
||||||
std::regex re("(GET|POST) (.+) HTTP/1\\.1\r\n");
|
static std::regex re("(GET|POST) (.+) HTTP/1\\.1\r\n");
|
||||||
|
|
||||||
|
const size_t BUFSIZ_REQUESTLINE = 2048;
|
||||||
|
char buf[BUFSIZ_REQUESTLINE];
|
||||||
|
fgets(buf, BUFSIZ_REQUESTLINE, fp);
|
||||||
|
|
||||||
std::cmatch m;
|
std::cmatch m;
|
||||||
if (std::regex_match(s, m, re)) {
|
if (std::regex_match(buf, m, re)) {
|
||||||
cmd = std::string(m[1]);
|
method = std::string(m[1]);
|
||||||
url = std::string(m[2]);
|
url = std::string(m[2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void read_headers(FILE* fp, Map& headers)
|
||||||
|
{
|
||||||
|
static std::regex re("(.+?): (.+?)\r\n");
|
||||||
|
|
||||||
|
const size_t BUFSIZ_HEADER = 2048;
|
||||||
|
char buf[BUFSIZ_HEADER];
|
||||||
|
|
||||||
|
while (fgets(buf, BUFSIZ_HEADER, fp) && strcmp(buf, "\r\n")) {
|
||||||
|
std::cmatch m;
|
||||||
|
if (std::regex_match(buf, m, re)) {
|
||||||
|
auto key = std::string(m[1]);
|
||||||
|
auto val = std::string(m[2]);
|
||||||
|
headers[key] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void write_plain_text(int fd, const char* s)
|
inline void write_plain_text(int fd, const char* s)
|
||||||
{
|
{
|
||||||
fdopen_b(fd, "w", [=](FILE* fp) {
|
fdopen_b(fd, "w", [=](FILE* fp) {
|
||||||
|
@ -254,20 +280,27 @@ inline void write_error(int fd, int code)
|
||||||
inline void Server::process_request(int fd)
|
inline void Server::process_request(int fd)
|
||||||
{
|
{
|
||||||
fdopen_b(fd, "r", [=](FILE* fp) {
|
fdopen_b(fd, "r", [=](FILE* fp) {
|
||||||
// Parse request line
|
// Read and parse request line
|
||||||
char request_line[BUFSIZ_REQUESTLINE];
|
std::string method, url;
|
||||||
fgets(request_line, BUFSIZ_REQUESTLINE, fp);
|
if (!read_request_line(fp, method, url)) {
|
||||||
|
|
||||||
std::string cmd, url;
|
|
||||||
if (!parse_request_line(request_line, cmd, url)) {
|
|
||||||
write_error(fd, 400);
|
write_error(fd, 400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read headers
|
||||||
|
Map headers;
|
||||||
|
read_headers(fp, headers);
|
||||||
|
|
||||||
// Write content
|
// Write content
|
||||||
char content[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
sprintf(content, "cmd: %s, url: %s\n", cmd.c_str(), url.c_str());
|
std::string content;
|
||||||
write_plain_text(fd, content);
|
sprintf(buf, "Method: %s, URL: %s\n", method.c_str(), url.c_str());
|
||||||
|
content += buf;
|
||||||
|
for (const auto& x : headers) {
|
||||||
|
sprintf(buf, "%s: %s\n", x.first.c_str(), x.second.c_str());
|
||||||
|
content += buf;
|
||||||
|
}
|
||||||
|
write_plain_text(fd, content.c_str());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue