mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 06:26:02 -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;
|
||||
|
||||
svr.post("/", [](const Request& /*req*/, Response& res) {
|
||||
res.body_ = "<html><head></head><body><ul></ul></body></html>";
|
||||
svr.get("/", [](Context& cxt) {
|
||||
cxt.response.body = "<html><head></head><body><ul></ul></body></html>";
|
||||
});
|
||||
|
||||
svr.post("/item", [](const Request& req, Response& res) {
|
||||
res.body_ = req.pattern_;
|
||||
svr.post("/item", [](Context& cxt) {
|
||||
cxt.response.body = cxt.request.pattern;
|
||||
});
|
||||
|
||||
svr.get("/item/:name", [](const Request& req, Response& res) {
|
||||
svr.get("/item/:name", [](Context& cxt) {
|
||||
try {
|
||||
res.body_ = req.params_.at("name");
|
||||
cxt.response.body = cxt.request.params.at("name");
|
||||
} catch (...) {
|
||||
// Error...
|
||||
}
|
||||
|
|
87
httpsvrkit.h
87
httpsvrkit.h
|
@ -37,27 +37,32 @@ typedef int socket_t;
|
|||
namespace httpsvrkit
|
||||
{
|
||||
|
||||
// HTTP request
|
||||
class Request {
|
||||
public:
|
||||
std::map<std::string, std::string> headers_;
|
||||
std::string body_;
|
||||
typedef std::map<std::string, std::string> Map;
|
||||
typedef std::multimap<std::string, std::string> MultiMap;
|
||||
|
||||
std::string pattern_;
|
||||
std::map<std::string, std::string> params_;
|
||||
// HTTP request
|
||||
struct Request {
|
||||
Map headers;
|
||||
std::string body;
|
||||
std::string pattern;
|
||||
Map params;
|
||||
};
|
||||
|
||||
// HTTP response
|
||||
class Response {
|
||||
public:
|
||||
std::multimap<std::string, std::string> headers_;
|
||||
std::string body_;
|
||||
struct Response {
|
||||
MultiMap headers;
|
||||
std::string body;
|
||||
};
|
||||
|
||||
struct Context {
|
||||
const Request request;
|
||||
Response response;
|
||||
};
|
||||
|
||||
// HTTP server
|
||||
class Server {
|
||||
public:
|
||||
typedef std::function<void (const Request&, Response& res)> Handler;
|
||||
typedef std::function<void (Context& context)> Handler;
|
||||
|
||||
Server();
|
||||
~Server();
|
||||
|
@ -71,8 +76,6 @@ public:
|
|||
private:
|
||||
void process_request(int fd);
|
||||
|
||||
const size_t BUFSIZ_REQUESTLINE = 2048;
|
||||
|
||||
socket_t sock_;
|
||||
std::multimap<std::string, Handler> handlers_;
|
||||
};
|
||||
|
@ -200,18 +203,41 @@ inline void Server::stop()
|
|||
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;
|
||||
if (std::regex_match(s, m, re)) {
|
||||
cmd = std::string(m[1]);
|
||||
if (std::regex_match(buf, m, re)) {
|
||||
method = std::string(m[1]);
|
||||
url = std::string(m[2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
fdopen_b(fd, "r", [=](FILE* fp) {
|
||||
// Parse request line
|
||||
char request_line[BUFSIZ_REQUESTLINE];
|
||||
fgets(request_line, BUFSIZ_REQUESTLINE, fp);
|
||||
|
||||
std::string cmd, url;
|
||||
if (!parse_request_line(request_line, cmd, url)) {
|
||||
// Read and parse request line
|
||||
std::string method, url;
|
||||
if (!read_request_line(fp, method, url)) {
|
||||
write_error(fd, 400);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read headers
|
||||
Map headers;
|
||||
read_headers(fp, headers);
|
||||
|
||||
// Write content
|
||||
char content[BUFSIZ];
|
||||
sprintf(content, "cmd: %s, url: %s\n", cmd.c_str(), url.c_str());
|
||||
write_plain_text(fd, content);
|
||||
char buf[BUFSIZ];
|
||||
std::string 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