I'm trying to write a small c++ webserver which handles GET, POST, HEAD requests. My problem is I don't know how to parse the headers, message body, etc. It's listening on the socket, I can even write stuff out to the browser just fine, but I'm curious how should I do this in c++.
Afaik a standard GET/POST request should look something like this:
GET /index HTTP/1.1
Host: 192.168.0.199:80
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
this is the message body
All lines ended with '\r\n'.
Should I just split the request at '\n' and trim them (and if so how)?
Also how to handle files in post data?
Main thing I want to achieve is to get a vector containing headers key=>value pairs, a string with request method, the post data (like in PHP, if it's present), and the query string (/index for example) as string or vector splitted by '/'.
Thanks!
Before doing everything yourself, I introduce you Poco:
class MyHTTPRequestHandler : public HTTPRequestHandler
{
public:
virtual void handleRequest(HTTPServerRequest & request,
HTTPServerResponse & response) {
// Write your HTML response in res object
}
};
class MyRequestHandlerFactory : public HTTPRequestHandlerFactory
{
MyHTTPRequestHandler handler;
public:
MyRequestHandlerFactory(){}
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
{
const string method = request.getMethod();
if (method == "get" || method == "post")
return &handler;
return 0;
}
};
int main()
{
HTTPServerParams params;
params.setMaxQueued(100);
params.setMaxThreads(16);
ServerSocket svs(80);
MyRequestHandlerFactory factory;
HTTPServer srv(&factory, svs, ¶ms);
srv.start();
while (true)
Thread::sleep(1000);
}
Boost.Asio is a good library but relativel low-level. You’ll really want to use a higher level library. There’s a modern C++ library called node.native which you should check out. A very server can be implemented as follows:
#include <iostream>
#include <native/native.h>
using namespace native::http;
int main() {
http server;
if(!server.listen("0.0.0.0", 8080, [](request& req, response& res) {
res.set_status(200);
res.set_header("Content-Type", "text/plain");
res.end("C++ FTW\n");
})) return 1; // Failed to run server.
std::cout << "Server running at http://0.0.0.0:8080/" << std::endl;
return native::run();
}
It doesn’t get much simpler than this.
Yes, this is basically just string parsing and then the response creating that goes back to the browser, following the specification.
But if this is not just an hobby project and you do not want to take on a really big task you should use either Apache, if you need a web server you need to extend, or tntnet, if you need a c++ web framework, or cpp-netlib if you need C++ network stuff.
You may want to consider Proxygen, Facebook's C++ HTTP framework. It's open source under a BSD license.