We released the C++ REST SDK (codename "Casablanca") as an open source project on CodePlex in Feb 2013. It enables writing modern, asynchronous C++ code that can connect with REST services.
Using the C++ REST SDK, you can create an HTTP client that can connect to HTTP server, send requests and handle responses. The following links are pre-requisites to get familiar with the C++ Rest SDK.
The C++ Rest HTTP Library offers an interesting feature which allows you to intercept your HTTP requests and responses before sending it out on the wire. This is useful for many scenarios and allows application developers to write custom handling of messages in one common place.
In this blog post, I will describe the intercepting technique in detail and will walk through few examples/scenarios where this can be used.
Intercepting HTTP requests is achieved by defining "stages" on the http client before it is sent. These stages form the full pipeline for the http client. Say if a client defines 3 new stages for the request, this would mean that the actual request will be processed by each of the stages in order before being passed on to the last stage. The last stage (which is implemented internally by the http_client) will interact with lower-level communication layers to actually send the message on the network. When creating a client instance, an application may add pipeline stages in front of the already existing stages.
A stage is defined by adding a handler using http_client.add_handler() API. This API has two overloads,
The scenarios that we will discuss below will demonstrate how to use these overloads.
A handler can do 2 things:
One can similarly define "stages" to intercept the response received.
Let us go through this with an example. Consider a client that uploads data to a service. However, this service has a limitation that it only accepts JSON data.
If a user sends xml or binary data in a PUT request, the service will reject this request. One way of avoiding this round-trip is by adding a step to the request processing pipeline, that checks the content-type and decides whether to continue with the request or not. In the below code-snippet, we have a content_handler lambda that does this for us:
This handler will check the content-type header and pass the request to the next stage only if the content-type is "application/json". The second input parameter to the handler is the next_stage. For any other content-types, it fails the request immediately by replying with the BadRequest (400) HTTP code.
Note: In the below snippet, we are only checking for the standard JSON MIME type. Sites can use other JSON MIME types too.
auto content_handler =
(http_request request, std::shared_ptr<http_pipeline_stage> next_stage) -> pplx::task<http_response>
auto content_type = request.headers().content_type();
if (0 != content_type.compare(L”application/json”))
// Short-circuit the HTTP request: construct a response object with status code = BadRequest
// and return a task containing the response.
// Content type is JSON, so call the next pipeline stage to send the request
client.request(methods::PUT, L"jsonentry1", filebuf.create_istream(), L"application/json")
// Print the status code.
ss << L"Server returned returned status code " << response.status_code() << L'.' << std::endl;
std::wcout << ss.str();
You can always add more than one handler, they will be executed in the order in which they were added.
Say in previous example, the client wants to add its version to every outgoing request. You can define a stage that can add a custom HTTP header named "AppVersion" with the client's current version.
We will be using following overload of http_client.add_handler to achieve this.
The add_custom_headers stage extends http_pipeline_stage. During request processing, the http client runs this stage against the given request and passes onto the next stage. Each stage has a reference to the next stage available in the http_pipeline_stage::next_stage. Implement the http_pipeline_stage::propagate()method to add your custom functionality. In the example below, this stageadds two new headers "AppVersion" and "ClientLocation" to the request message.
If the request was short circuited by the content_handler stage, the add_custom_headers stage will not be called. Only when the content_handler propagates the request to the next stage, will the headers be added.
// Pipeline stage used for adding custom headers
class add_custom_headers : public http_pipeline_stage
virtual pplx::task<http_response> propagate(http_request request)
std::shared_ptr<http_pipeline_stage> custom_stage = std::make_shared<add_custom_headers>();
In the above two illustrations, you saw how we can intercept the request pipeline. We can do the same with responses too. The client can add a new pipeline stage that will be executed before passing the response to the application. This stage can also modify the response received from the server.
The response_count_handler below increments a counter for each response received and also adds a new header to the response. The propagate()call returns a task of the response, its continuation can modify the response and return the updated one to the application.
Note that since multiple requests can be made simultaneously, accessing any data from within the handler must use synchronization. This will impact the performance and scalability of the application, which is a concern especially when implementing the handlers at the http_listener side. Hence, it is recommended to implement purely functional handlers: they should take a message, manipulate it and pass it to the next stage.
volatile long response_counter = 0;
auto response_count_handler =
[&response_counter](http_request request, std::shared_ptr<http_pipeline_stage> next_stage) -> pplx::task<http_response>
return next_stage->propagate(request).then([&response_counter](http_response resp) -> http_response
// Use synchronization primitives to access data from within the handlers.
This feature can be very useful for local testing as well. Instead of setting up a test server, you can add a stage that performs the server side validation at the client. These test hooks can reduce the test setup overhead significantly. For example: we can add a test handler that verifies a key and replies with the Forbidden (403) status code if the key is incorrect, thus performing a server side authentication step at the client itself.
auto test_auth_stage =
These handlers are good for adding extra processing at the level of HTTP messages. Some examples of when these can be used:
Any feedback or comments are welcome either below or at our codeplex forum.
Visual C++ QA