tl; dr; see end of response to implement header parser
As a rule, licurl
used to write clients, see the FAQ :
5.17 Can I write a server with libcurl?
No. libcurl offers the internet protocol server. libcurl is only a client-side library. But there wasn’t even a need for a server. And there are really good stand-alone ones that have been tested and proven for many years. There is no need to reinvent them!
In free translation:
5.17 Can I use libcurl to write a server?
Not. libcurl does not offer functions or other building blocks to create any IP server. libcurl is only a client library. You need to continue your library searches to build a server. There are a large number of such open source libraries for most protocols. There is also a large number of applications tested over the years. You should not reinvent them.
Although to build the client, libcurl
really handy thing, as @Pink Tux mentioned in its answer. Including the headlines you get already broken down one by one.
To build a server, as one of the options, you can use mongoose (on c
, as a pair of .c/.h
added to your project, or one of the many c++
wrappers). An example of a minimal server is quite cumbersome, so I will not give here. You can see here .
Another option is the cpp-netlib library which was originally planned as part of the boost
(but then the developers' plans changed). In its simplest form, the http server looks like this:
namespace http = boost::network::http; struct handler; typedef http::server<handler> http_server; struct handler { void operator() (http_server::request const &request, http_server::response &response) { response = http_server::response::stock_reply( http_server::response::ok, "Hello, world!"); } void log(http_server::string_type const &info) { std::cerr << "ERROR: " << info << '\n'; } }; int main(int arg, char * argv[]) { handler handler_; http_server::options options(handler_); http_server server_( options.address("0.0.0.0") .port("8000")); server_.run(); }
If you need something more high-level (with template support, json, middlewares), you can take a crow that connects to your project with a single header file. In spirit, it resembles Python Flask . Sample server:
#include "crow_all.h" int main() { crow::SimpleApp app; CROW_ROUTE(app, "/")([](){ return "Hello world"; }); app.port(18080).multithreaded().run(); }
If it’s still interesting to parse the headers yourself, you can for example like this code:
std::istringstream rawstream(raw); std::map<std::string, std::string> headers; std::string header; while (std::getline(rawstream, header) && header != "\r") { std::string::size_type index = header.find(':'); if (index != std::string::npos) { headers.insert(std::make_pair( boost::algorithm::trim_copy(header.substr(0, index)), boost::algorithm::trim_copy(header.substr(index + 1)) )); } }
In raw
type std::string
place a string with your headers (or even an entire client request), in headers
get a map
from the names / values of the headers. Use for example:
std::cout << headers["Content-Type"] << std::endl;
Please note that according to the standard, the name of the header can be any case. Therefore, CONTENT-TYPE
, content-type
and Content-Type
are all one title, and for convenience, you can bring the title name into lowercase before adding to the map
:
headers.insert(std::make_pair( boost::algorithm::to_lower_copy(boost::algorithm::trim_copy(header.substr(0, index))), boost::algorithm::trim_copy(header.substr(index + 1)) ));
The current example is on Ideone.com .
PS For testing, instead of curl
you can use postman in which you can set headers, the body of the pages (including json), save sets of queries, etc.
\r
or\n
? Try reading man by strchr, strtok, strstr etc (although this is not C ++ at all). - PinkTux