linuxc++11cpp-netlib

querying the request of cpp-netlib HTTP server


A question similar to (but more specific than) this unanswered question about headers in cpp-netlib HTTP server side.

This is with using cpp-netlib 0.11.1 on Linux/Debian/Sid/x86-64 with clang++ 3.5 or g++ 4.9 in -std=c++11mode.

BTW, I also asked some examples on cpp-netlib googlegroup ...

#include <fstream>
#include <iostream>
#include <boost/network/protocol/http/server.hpp>
#define DEBUG_OUT(Out) do {std::cout << __FILE__ << ":" << __LINE__ \
   << ' ' << Out << std::endl;} while(0)

namespace netlib_http = boost::network::http;

struct Yaca_web;
typedef netlib_http::server<Yaca_web> Yaca_server;

struct Yaca_web {
  void operator() (Yaca_server::request const& request,
                   Yaca_server::response &response)
  {
    DEBUG_OUT("web request source="
          << std::string(source(request))
          //<< " uri=" << std::string(uri(request)) ///@@@@@
          );
  };
  void log(const std::string&s) { DEBUG_OUT("log s=" << s); };
};              // end Yaca_web

void ya_web_service(int port) {
  DEBUG_OUT("ya_web_service start port=" << port);
  Yaca_web webhandler;
  Yaca_server::options weboptions {webhandler};
  weboptions.address("localhost");
  weboptions.port(std::to_string(port));
  weboptions.reuse_address(true);
  Yaca_server webserver {weboptions};
  DEBUG_OUT("ya_web_service before running server");
  webserver.run();
  DEBUG_OUT("ya_web_service end port=" << port);
}    

The above code does not compile if I uncomment the line with ///@@@@@ but I am using uri(request) as a blind guess:

In file included from ywebx.cc:4:
In file included from /usr/include/boost/network/protocol/http/server.hpp:13:
In file included from /usr/include/boost/network/protocol/http/request.hpp:18:
/usr/include/boost/network/protocol/http/message/wrappers/uri.hpp:25:44: error: 
      no member named 'uri' in
      'boost::network::http::basic_request<tags::http_server>'
  operator string_type() { return message_.uri().raw(); }
                                  ~~~~~~~~ ^
ywebx.cc:18:34: note: in instantiation of member function
      'boost::network::http::impl::uri_wrapper<boost::network::http::tags::http_server>::operator
      basic_string' requested here
              << " uri=" << std::string(uri(request))
                                        ^
./yacax.h:49:18: note: expanded from macro 'DEBUG_OUT'
       << ' ' << Out << std::endl;} while(0)
             ^

Does anyone knows how to get more information: in particular, method, path or URI, and for HTTP POST requests with the common application/x-www-form-urlencoded MIME type the dictionnary (if possible) of webform arguments?

I was not able to find a simple example of cpp-netlib HTTP service for Web forms (something similar for cpp-netlib in C++11 of the examples/post/ of libonion)


Solution

  • You can get the following fields from the server's request object (https://github.com/cpp-netlib/cpp-netlib/blob/0.11-devel/boost/network/protocol/http/impl/request.hpp#L126):

    If you're using the asynchronous version of the server's API, you can also get the body streaming by following the documentation from http://cpp-netlib.org/0.11.1/reference/http_server.html#connection-object -- this allows you to read chunks of the incoming request's body and then respond by setting the status of the response, add headers, etc.

    In your example, you can get what you want by doing this:

    struct Yaca_web {
      void operator()(Yaca_server::request const& req,
                      Yaca_server::response& res) {
        DEBUG_OUT("web request source="
          << std::string(source(request))
          << " uri=" << std::string(destination(request)) ///@@@@@
          );
      }
    };
    

    Alternatively, using the objects directly:

    struct Yaca_web {
      void operator()(Yaca_server::request const& req,
                      Yaca_server::response& res) {
        DEBUG_OUT("web request source="
          << req.source
          << " uri=" << req.destination
          );
      }
    };