{"id":1343,"date":"2013-07-10T10:44:00","date_gmt":"2013-07-10T10:44:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2013\/07\/10\/intercepting-http-requestresponse-using-c-rest-http-library\/"},"modified":"2021-09-28T16:50:39","modified_gmt":"2021-09-28T16:50:39","slug":"intercepting-http-requestresponse-using-c-rest-http-library","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/intercepting-http-requestresponse-using-c-rest-http-library\/","title":{"rendered":"Intercepting HTTP Request\/Response using C++ Rest HTTP Library"},"content":{"rendered":"<p>We released the C++ REST SDK (codename &#8220;Casablanca&#8221;) as an open source project on <a href=\"http:\/\/casablanca.codeplex.com\/\">CodePlex<\/a> in Feb 2013. It enables writing modern, asynchronous C++ code that can connect with REST services.<\/p>\n<p>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.<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vcblog\/archive\/2013\/02\/26\/the-c-rest-sdk-quot-casablanca-quot.aspx\">Introduction to the C++ REST SDK<\/a><\/li>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/jj950081.aspx\">How to connect to HTTP servers (C++ REST SDK)<\/a><\/li>\n<\/ul>\n<p>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.<\/p>\n<p>In this blog post, I will describe the intercepting technique in detail and will walk through few examples\/scenarios where this can be used.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/07\/5342.image-1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/07\/5342.image-1.png\" alt=\"Image 5342 image 1\" width=\"344\" height=\"588\" class=\"aligncenter size-full wp-image-28824\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/07\/5342.image-1.png 344w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/07\/5342.image-1-176x300.png 176w\" sizes=\"(max-width: 344px) 100vw, 344px\" \/><\/a><\/p>\n<h2>&#8220;Stages&#8221; of Http client message pipeline<\/h2>\n<p><span style=\"color: black\">Intercepting HTTP requests is achieved by defining &#8220;stages&#8221; 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 <\/span><span style=\"font-family: Courier New\">http_client<\/span><span style=\"color: black\">) 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. <\/span><\/p>\n<p><span style=\"color: black\">A stage is defined by adding a handler using <\/span><span style=\"font-family: Courier New\">http_client.add_handler() <\/span><span style=\"color: black\">API. This API has two overloads, <\/span><\/p>\n<ol>\n<li><span style=\"color: black\">Pass in a std::function object as the handler: Following will ensure lambda &#8220;<\/span><span style=\"font-family: Courier New\">foo<\/span><span style=\"color: black\">&#8221; gets called before the message is actually sent. <\/span>\n<p style=\"text-align: center\"><span style=\"font-family: Courier New\">http_client.add_handler(foo)<\/span><\/p>\n<\/li>\n<li><span style=\"color: black\">Implement a pipeline stage by deriving from the<\/span><span style=\"font-family: Courier New\"> http_pipeline_stage <\/span><span style=\"color: black\">class and pass it to the<\/span><span style=\"font-family: Courier New\"> add_handler <\/span><span style=\"color: black\">method. <\/span><\/li>\n<\/ol>\n<p><span style=\"color: black\">The scenarios that we will discuss below will demonstrate how to use these overloads. <\/span><\/p>\n<p>A handler can do 2 things:<\/p>\n<ol>\n<li>It can short-circuit the HTTP request and avoid sending the message over the network. The handler in this case should return a task representing the eventual response.<\/li>\n<li>Handler can do some extra processing of the message. For e.g. handler may update some counters, modify request\/response headers etc. In this case, the handler should call the next stage.<\/li>\n<\/ol>\n<p>One can similarly define &#8220;stages&#8221; to intercept the response received.<\/p>\n<h2>Scenario 1: Adding a stage to http_client request processing<\/h2>\n<p>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.<\/p>\n<p>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 <span style=\"font-family: Courier New\">content_handler<\/span> lambda that does this for us:<\/p>\n<p>This handler will check the content-type header and pass the request to the next stage only if the content-type is &#8220;application\/json&#8221;. 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.<\/p>\n<p>Note: In the below snippet, we are only checking for the <a href=\"http:\/\/www.ietf.org\/rfc\/rfc4627.txt\">standard JSON MIME type<\/a>. Sites can use other JSON MIME types too.<\/p>\n<table class=\"MsoTableGrid\" style=\"border: currentColor;border-collapse: collapse\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td style=\"width: 625.1pt;border: solid windowtext 1.0pt;padding: 0in 5.4pt 0in 5.4pt\" valign=\"top\" width=\"833\">\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> auto<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> content_handler = <\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>[](<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_request<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, std::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">shared_ptr<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_pipeline_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> next_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) -&gt; pplx::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">task<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_response<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> auto<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> content_type = <\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.headers().content_type();<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> if<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> (0 != content_type.compare(L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&rdquo;application\/json<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515\">&rdquo;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">))<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\"> \/\/ Short-circuit the HTTP request: construct a response object with status code = BadRequest<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\"> <span>&nbsp;<\/span><\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\"> \/\/ and return a task containing the response.<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> http_response<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> response;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>response.set_status_code(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">status_codes<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">::BadRequest);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> return<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> pplx::task_from_result(response);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> else<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\"> \/\/ Content type is JSON, so call the next pipeline stage to send the request<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> return<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> next_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">-&gt;propagate(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\">request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>};<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> http_client<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> client(L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;http:\/\/localhost:60009&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span> client.add_handler(content_handler);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>client.request(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">methods<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">::PUT, L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;jsonentry1&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, filebuf.create_istream(), L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;application\/json&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>.then([](<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_response<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> response<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\"> \/\/ Print the status code.<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>std::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">wostringstream<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ss;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>ss &lt;&lt; L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;Server returned returned status code &#8220;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &lt;&lt; <\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> response<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.status_code() &lt;&lt; L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8216;.&#8217;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &lt;&lt; std::endl;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>std::wcout &lt;&lt; ss.str();<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>});<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Scenario 2: Adding multiple stages to the client:<\/h2>\n<p>You can always add more than one handler, they will be executed in the order in which they were added.<\/p>\n<p>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 &#8220;AppVersion&#8221; with the client&#8217;s current version.<\/p>\n<p>We will be using following overload of <span style=\"color: black;font-family: Consolas;font-size: 9pt;background-color: white\">http_client.add_handler<\/span> to achieve this.<\/p>\n<p><span style=\"font-family: Courier New\">http_client.add_handler(std::shared_ptr&lt;http_pipeline_stage&gt;)<\/span><\/p>\n<p>The <span style=\"font-family: Courier New\">add_custom_headers <\/span>stage extends <span style=\"font-family: Courier New\">http_pipeline_stage<\/span>. 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 <span style=\"font-family: Courier New\">http_pipeline_stage::next_stage<\/span>. <br \/>Implement the <span style=\"font-family: Courier New\">http_pipeline_stage::propagate()<\/span>method to add your custom functionality. In the example below, this stageadds two new headers &#8220;AppVersion&#8221; and &#8220;ClientLocation&#8221; to the request message.<\/p>\n<p>If the request was short circuited by the <span style=\"font-family: Courier New\">content_handler<\/span> stage, the <span style=\"font-family: Courier New\">add_custom_headers<\/span> stage will not be called. Only when the <span style=\"font-family: Courier New\">content_handler<\/span> propagates the request to the next stage, will the headers be added.<\/p>\n<table class=\"MsoTableGrid\" style=\"border: currentColor;border-collapse: collapse\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td style=\"width: 611.6pt;border: solid windowtext 1.0pt;padding: 0in 5.4pt 0in 5.4pt\" valign=\"top\" width=\"815\">\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\"> \/\/ Pipeline stage used for adding custom headers<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> class<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> add_custom_headers<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> : <\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> public<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> http_pipeline_stage<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> public<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">:<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> virtual<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> pplx::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">task<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_response<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; propagate(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_request<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) <\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.headers().add(L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;AppVersion&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;1.0&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.headers().add(L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;ClientLocation&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, <\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #6f008a;background: white\"> L&rdquo;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">Redmond&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">));<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> return<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> next_stage()-&gt;propagate(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\">request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>};<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> &nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>http_client<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> client(L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;http:\/\/localhost:60009&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span> client.add_handler(content_handler);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>std::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">shared_ptr<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_pipeline_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; custom_stage = std::make_shared&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">add_custom_headers<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt;();<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span> client.add_handler(custom_stage);<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Scenario 3: Intercepting HTTP response messages<\/h2>\n<p>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.<\/p>\n<p>The <span style=\"font-family: Courier New\">response_count_handler<\/span> below increments a counter for each response received and also adds a new header to the response. The <span style=\"font-family: Courier New\">propagate()<\/span>call returns a task of the response, its continuation can modify the response and return the updated one to the application.<\/p>\n<p>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,&nbsp;which is a concern especially when implementing the handlers at the <span style=\"font-family: Courier New\">http_listener<\/span> side. Hence, it is recommended to implement purely functional handlers: they should take a message, manipulate it and pass it to the next stage.&nbsp;<\/p>\n<table class=\"MsoTableGrid\" style=\"border: currentColor;border-collapse: collapse\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td style=\"width: 980.6pt;border: solid windowtext 1.0pt;padding: 0in 5.4pt 0in 5.4pt\" valign=\"top\" width=\"1307\">\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> volatile<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> long<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> response_counter = 0;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> auto<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> response_count_handler = <\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>[&amp;response_counter](<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_request<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, std::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">shared_ptr<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_pipeline_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> next_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) -&gt; pplx::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">task<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_response<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> return<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> next_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">-&gt;propagate(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\">request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">).then([&amp;response_counter](<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_response<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> resp<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) -&gt; <\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> http_response<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\"> \/\/ Use synchronization primitives to access data from within the handlers.<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>::_InterlockedIncrement(&amp;response_counter);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> resp<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.headers().add(L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;ResponseHeader&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;App&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> return<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> resp<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>});<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span>};<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> http_client<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> client(L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&rdquo;http:\/\/localhost:60009&rdquo;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span> client.add_handler(response_count_handler);<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Scenario 4: Testing the HTTP client<\/h2>\n<p>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.&nbsp;<\/p>\n<table class=\"MsoTableGrid\" style=\"border: currentColor;border-collapse: collapse\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td style=\"width: 656.6pt;border: solid windowtext 1.0pt;padding: 0in 5.4pt 0in 5.4pt\" valign=\"top\" width=\"875\">\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> auto<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> test_auth_stage = <\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>[](<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_request<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">, std::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">shared_ptr<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_pipeline_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> next_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) -&gt; pplx::<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">task<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">http_response<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> if<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> (is_valid_key(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\">request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.headers()))<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> return<\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\"> next_stage<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">-&gt;propagate(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: gray;background: white\">request<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> else<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> http_response<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> response;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>response.set_status_code(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">status_codes<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">::Forbidden);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\"> return<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> pplx::task_from_result(response);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>}<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>};<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> &nbsp;<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span><\/span> <span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\"> http_client<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> client(L<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #a31515;background: white\">&#8220;https:\/\/www.cpprestsite.com&#8221;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">);<\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin-bottom: .0001pt\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> <span>&nbsp;&nbsp;&nbsp; <\/span> client.add_handler(test_auth_stage);<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>When can this come in handy?<\/h2>\n<p>These handlers are good for adding extra processing at the level of HTTP messages. Some examples of when these can be used:<\/p>\n<ol>\n<li>Logging purposes or to maintain counters for the number of requests and responses<\/li>\n<li>To add or modify the HTTP request or response headers.<\/li>\n<li>Perform some validation of the request before the actual processing. For example, you can check the authentication key and reject unauthorized requests. This way, you can avoid unnecessary roundtrips.<\/li>\n<li>Local testing: The handlers can act as test hooks and perform server side processing locally, without actually setting up a server.<\/li>\n<\/ol>\n<p>Any feedback or comments are welcome either below or at our <a href=\"http:\/\/casablanca.codeplex.com\/discussions\">codeplex forum<\/a>.<\/p>\n<p>Kavya Kotacherry,<\/p>\n<p>Visual C++ QA<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We released the C++ REST SDK (codename &#8220;Casablanca&#8221;) 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 [&hellip;]<\/p>\n","protected":false},"author":274,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>We released the C++ REST SDK (codename &#8220;Casablanca&#8221;) 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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/1343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/274"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=1343"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/1343\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=1343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=1343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=1343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}