Sunday, May 2, 2010

HTTP client made easy by using the asio library

Recently I had another chance to code a couple of HTTP clients, making use of the asio library as the foundation. This time I refined the approach that I had taken a couple of years ago, by componentizing things as follows.
  • HTTP client hierarchy
  • Request classes
  • Response-handling classes
The client hierarchy consists of a base class that contains the primary logic flow common to both the ordinary (http://...) and secure (https://...) HTTP calls, for each of which a derived class is designed. The base and derived classes are tied together nicely by taking advantage of the template method pattern.

With the aid of asio, it takes just a few lines to code the core logic flow of the non-secure client, roughly as follows.
asio::ip::tcp::iostream s(serverAddress, serverPort);
HttpRequest req(...);
s << req << std::flush;
HttpResponse resp;
s >> resp;
It's a little more involved for the secure client, but still it requires just about a dozen or so lines of code.

What is left to do is to design and code the request and response classes specific to the particular service and/or operation offered on the server side. A request must be constructed as required by the server, and the corresponding response certainly varies by the service/operation requested/invoked. For a set of related or similar services/operations, it's not hard to imagine that hierarchies of requests and responses may be built, at least for code reuse.

The asio library started off stand alone, and it was header-only as of at least version 1.2, which is very nice, though I'm not sure about the latest. The more recent releases of the boost libraries include asio (brought in as a sub-namespace), but my understanding is that it may no longer be used header-only as part of boost, likely due to some decisions made at the time of integration.

No comments:

Post a Comment