John Smith
John Smith

Reputation: 2341

how to parse http request in c++

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!

Upvotes: 12

Views: 35791

Answers (4)

masoud
masoud

Reputation: 56549

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, &params);
    srv.start();
    while (true)
        Thread::sleep(1000);
}

Upvotes: 3

firebush
firebush

Reputation: 5880

You may want to consider Proxygen, Facebook's C++ HTTP framework. It's open source under a BSD license.

Upvotes: 2

Konrad Rudolph
Konrad Rudolph

Reputation: 546143

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.

Upvotes: 2

Ferenc Deak
Ferenc Deak

Reputation: 35458

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.

Upvotes: 2

Related Questions