C++ Rest SDK
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
http_client.h
1 /***
2 * ==++==
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * ==--==
17 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
18 *
19 * HTTP Library: Client-side APIs.
20 *
21 * For the latest on this and related APIs, please see http://casablanca.codeplex.com.
22 *
23 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
24 ****/
25 #pragma once
26 
27 #ifndef _CASA_HTTP_CLIENT_H
28 #define _CASA_HTTP_CLIENT_H
29 
30 #if defined (__cplusplus_winrt)
31 #if !defined(__WRL_NO_DEFAULT_LIB__)
32 #define __WRL_NO_DEFAULT_LIB__
33 #endif
34 #include <wrl.h>
35 #include <msxml6.h>
36 namespace web { namespace http{namespace client{
37 typedef IXMLHTTPRequest2* native_handle;}}}
38 #else
39 namespace web { namespace http{namespace client{
40 typedef void* native_handle;}}}
41 #endif // __cplusplus_winrt
42 
43 #include <memory>
44 #include <limits>
45 #if !defined(_WIN32) && !defined(__cplusplus_winrt)
46 #if defined(__clang__)
47 #pragma clang diagnostic push
48 #pragma clang diagnostic ignored "-Wconversion"
49 #endif
50 #include "boost/asio/ssl.hpp"
51 #if defined(__clang__)
52 #pragma clang diagnostic pop
53 #endif
54 #endif
55 
56 #include "pplx/pplxtasks.h"
57 #include "cpprest/http_msg.h"
58 #include "cpprest/json.h"
59 #include "cpprest/uri.h"
60 #include "cpprest/details/web_utilities.h"
61 #include "cpprest/details/basic_types.h"
62 #include "cpprest/asyncrt_utils.h"
63 
64 #if !defined(CPPREST_TARGET_XP)
65 #include "cpprest/oauth1.h"
66 #endif
67 
68 #include "cpprest/oauth2.h"
69 
71 namespace web
72 {
74 namespace http
75 {
77 namespace client
78 {
79 
80 // credentials and web_proxy class has been moved from web::http::client namespace to web namespace.
81 // The below using declarations ensure we don't break existing code.
82 // Please use the web::credentials and web::web_proxy class going forward.
83 using web::credentials;
84 using web::web_proxy;
85 
91 {
92 public:
94  m_guarantee_order(false),
95  m_timeout(std::chrono::seconds(30)),
96  m_chunksize(0)
97 #if !defined(__cplusplus_winrt)
98  , m_validate_certificates(true)
99 #endif
100  , m_set_user_nativehandle_options([](native_handle)->void{})
101 #if !defined(_WIN32) && !defined(__cplusplus_winrt)
102  , m_ssl_context_callback([](boost::asio::ssl::context&)->void{})
103 #endif
104 #if defined(_WIN32) && !defined(__cplusplus_winrt)
105  , m_buffer_request(false)
106 #endif
107  {
108  }
109 
110 #if !defined(CPPREST_TARGET_XP)
111  const std::shared_ptr<oauth1::experimental::oauth1_config> oauth1() const
116  {
117  return m_oauth1;
118  }
119 
125  {
126  m_oauth1 = std::make_shared<oauth1::experimental::oauth1_config>(std::move(config));
127  }
128 #endif
129 
134  const std::shared_ptr<oauth2::experimental::oauth2_config> oauth2() const
135  {
136  return m_oauth2;
137  }
138 
144  {
145  m_oauth2 = std::make_shared<oauth2::experimental::oauth2_config>(std::move(config));
146  }
147 
152  const web_proxy& proxy() const
153  {
154  return m_proxy;
155  }
156 
162  {
163  m_proxy = std::move(proxy);
164  }
165 
171  {
172  return m_credentials;
173  }
174 
180  {
181  m_credentials = cred;
182  }
183 
188  bool guarantee_order() const
189  {
190  return m_guarantee_order;
191  }
192 
197  CASABLANCA_DEPRECATED("Confusing API will be removed in future releases. If you need to order HTTP requests use task continuations.")
199  {
200  m_guarantee_order = guarantee_order;
201  }
202 
207  utility::seconds timeout() const
208  {
209  return std::chrono::duration_cast<utility::seconds>(m_timeout);
210  }
211 
216  template <class T>
217  T timeout() const
218  {
219  return std::chrono::duration_cast<T>(m_timeout);
220  }
225  template <class T>
226  void set_timeout(const T &timeout)
227  {
228  m_timeout = std::chrono::duration_cast<std::chrono::microseconds>(timeout);
229  }
230 
235  size_t chunksize() const
236  {
237  return m_chunksize == 0 ? 64 * 1024 : m_chunksize;
238  }
239 
245  void set_chunksize(size_t size)
246  {
247  m_chunksize = size;
248  }
249 
255  bool is_default_chunksize() const
256  {
257  return m_chunksize == 0;
258  }
259 
260 #if !defined(__cplusplus_winrt)
261  bool validate_certificates() const
266  {
267  return m_validate_certificates;
268  }
269 
275  void set_validate_certificates(bool validate_certs)
276  {
277  m_validate_certificates = validate_certs;
278  }
279 #endif
280 
281 #ifdef _WIN32
282 #if !defined(__cplusplus_winrt)
283  bool buffer_request() const
288  {
289  return m_buffer_request;
290  }
291 
299  void set_buffer_request(bool buffer_request)
300  {
301  m_buffer_request = buffer_request;
302  }
303 #endif
304 #endif
305 
318  void set_nativehandle_options(const std::function<void(native_handle)> &callback)
319  {
320  m_set_user_nativehandle_options = callback;
321  }
322 
327  void invoke_nativehandle_options(native_handle handle) const
328  {
329  m_set_user_nativehandle_options(handle);
330  }
331 
332 #if !defined(_WIN32) && !defined(__cplusplus_winrt)
333  void set_ssl_context_callback(const std::function<void(boost::asio::ssl::context&)>& callback)
338  {
339  m_ssl_context_callback = callback;
340  }
341 
345  const std::function<void(boost::asio::ssl::context&)>& get_ssl_context_callback() const
346  {
347  return m_ssl_context_callback;
348  }
349 #endif
350 
351 private:
352 #if !defined(CPPREST_TARGET_XP)
353  std::shared_ptr<oauth1::experimental::oauth1_config> m_oauth1;
354 #endif
355 
356  std::shared_ptr<oauth2::experimental::oauth2_config> m_oauth2;
357  web_proxy m_proxy;
358  http::client::credentials m_credentials;
359  // Whether or not to guarantee ordering, i.e. only using one underlying TCP connection.
360  bool m_guarantee_order;
361 
362  std::chrono::microseconds m_timeout;
363  size_t m_chunksize;
364 
365 #if !defined(__cplusplus_winrt)
366  // IXmlHttpRequest2 doesn't allow configuration of certificate verification.
367  bool m_validate_certificates;
368 #endif
369 
370  std::function<void(native_handle)> m_set_user_nativehandle_options;
371 
372 #if !defined(_WIN32) && !defined(__cplusplus_winrt)
373  std::function<void(boost::asio::ssl::context&)> m_ssl_context_callback;
374 #endif
375 #if defined(_WIN32) && !defined(__cplusplus_winrt)
376  bool m_buffer_request;
377 #endif
378 };
379 
384 {
385 public:
390  _ASYNCRTIMP http_client(const uri &base_uri);
391 
397  _ASYNCRTIMP http_client(const uri &base_uri, const http_client_config &client_config);
398 
403  ~http_client() CPPREST_NOEXCEPT {}
404 
411  _ASYNCRTIMP const uri& base_uri() const;
412 
417  _ASYNCRTIMP const http_client_config& client_config() const;
418 
423  void add_handler(const std::function<pplx::task<http_response>(http_request, std::shared_ptr<http::http_pipeline_stage>)> &handler)
424  {
425  m_pipeline->append(std::make_shared<::web::http::details::function_pipeline_wrapper>(handler));
426  }
427 
432  void add_handler(const std::shared_ptr<http::http_pipeline_stage> &stage)
433  {
434  m_pipeline->append(stage);
435  }
436 
444 
452  {
453  http_request msg(mtd);
454  return request(msg, token);
455  }
456 
465  const method &mtd,
466  const utility::string_t &path_query_fragment,
468  {
469  http_request msg(mtd);
470  msg.set_request_uri(path_query_fragment);
471  return request(msg, token);
472  }
473 
483  const method &mtd,
484  const utility::string_t &path_query_fragment,
485  const json::value &body_data,
487  {
488  http_request msg(mtd);
489  msg.set_request_uri(path_query_fragment);
490  msg.set_body(body_data);
491  return request(msg, token);
492  }
493 
505  const method &mtd,
506  const utf8string &path_query_fragment,
507  const utf8string &body_data,
508  const utf8string &content_type = "text/plain; charset=utf-8",
510  {
511  http_request msg(mtd);
512  msg.set_request_uri(::utility::conversions::to_string_t(path_query_fragment));
513  msg.set_body(body_data, content_type);
514  return request(msg, token);
515  }
516 
528  const method &mtd,
529  const utf8string &path_query_fragment,
530  utf8string &&body_data,
531  const utf8string &content_type = "text/plain; charset=utf-8",
533  {
534  http_request msg(mtd);
535  msg.set_request_uri(::utility::conversions::to_string_t(path_query_fragment));
536  msg.set_body(std::move(body_data), content_type);
537  return request(msg, token);
538  }
539 
551  const method &mtd,
552  const utf16string &path_query_fragment,
553  const utf16string &body_data,
554  const utf16string &content_type = ::utility::conversions::to_utf16string("text/plain"),
556  {
557  http_request msg(mtd);
558  msg.set_request_uri(::utility::conversions::to_string_t(path_query_fragment));
559  msg.set_body(body_data, content_type);
560  return request(msg, token);
561  }
562 
573  const method &mtd,
574  const utf8string &path_query_fragment,
575  const utf8string &body_data,
576  const pplx::cancellation_token &token)
577  {
578  return request(mtd, path_query_fragment, body_data, "text/plain; charset=utf-8", token);
579  }
580 
591  const method &mtd,
592  const utf8string &path_query_fragment,
593  utf8string &&body_data,
594  const pplx::cancellation_token &token)
595  {
596  http_request msg(mtd);
597  msg.set_request_uri(::utility::conversions::to_string_t(path_query_fragment));
598  msg.set_body(std::move(body_data), "text/plain; charset=utf-8");
599  return request(msg, token);
600  }
601 
612  const method &mtd,
613  const utf16string &path_query_fragment,
614  const utf16string &body_data,
615  const pplx::cancellation_token &token)
616  {
617  return request(mtd, path_query_fragment, body_data, ::utility::conversions::to_utf16string("text/plain"), token);
618  }
619 
620 #if !defined (__cplusplus_winrt)
631  const method &mtd,
632  const utility::string_t &path_query_fragment,
633  const concurrency::streams::istream &body,
634  const utility::string_t &content_type = _XPLATSTR("application/octet-stream"),
636  {
637  http_request msg(mtd);
638  msg.set_request_uri(path_query_fragment);
639  msg.set_body(body, content_type);
640  return request(msg, token);
641  }
642 
652  const method &mtd,
653  const utility::string_t &path_query_fragment,
654  const concurrency::streams::istream &body,
655  const pplx::cancellation_token &token)
656  {
657  return request(mtd, path_query_fragment, body, _XPLATSTR("application/octet-stream"), token);
658  }
659 #endif // __cplusplus_winrt
660 
673  const method &mtd,
674  const utility::string_t &path_query_fragment,
675  const concurrency::streams::istream &body,
676  size_t content_length,
677  const utility::string_t &content_type = _XPLATSTR("application/octet-stream"),
679  {
680  http_request msg(mtd);
681  msg.set_request_uri(path_query_fragment);
682  msg.set_body(body, content_length, content_type);
683  return request(msg, token);
684  }
685 
697  const method &mtd,
698  const utility::string_t &path_query_fragment,
699  const concurrency::streams::istream &body,
700  size_t content_length,
701  const pplx::cancellation_token &token)
702  {
703  return request(mtd, path_query_fragment, body, content_length, _XPLATSTR("application/octet-stream"), token);
704  }
705 
706 private:
707 
708  void build_pipeline(const uri &base_uri, const http_client_config &client_config);
709 
710  std::shared_ptr<::web::http::http_pipeline> m_pipeline;
711 };
712 
713 }}}
714 
715 #endif
Represents a set of user credentials (user name and password) to be used for authentication.
Definition: web_utilities.h:80
void set_request_uri(const uri &uri)
Set the underling URI of the request message.
Definition: http_msg.h:814
OAuth 2.0 configuration.
Definition: oauth2.h:212
const std::shared_ptr< oauth2::experimental::oauth2_config > oauth2() const
Get OAuth 2.0 configuration.
Definition: http_client.h:134
const http::client::credentials & credentials() const
Get the client credentials
Definition: http_client.h:170
pplx::task< http_response > request(const method &mtd, const utf16string &path_query_fragment, const utf16string &body_data, const utf16string &content_type=::utility::conversions::to_utf16string("text/plain"), const pplx::cancellation_token &token=pplx::cancellation_token::none())
Asynchronously sends an HTTP request with a string body. Assumes the character encoding of the string...
Definition: http_client.h:550
void add_handler(const std::shared_ptr< http::http_pipeline_stage > &stage)
Adds an HTTP pipeline stage to the client.
Definition: http_client.h:432
_ASYNCRTIMP http_client(const uri &base_uri)
Creates a new http_client connected to specified uri.
Definition: http_client_impl.h:419
A flexible, protocol independent URI implementation.
Definition: base_uri.h:151
pplx::task< http_response > request(const method &mtd, const utf16string &path_query_fragment, const utf16string &body_data, const pplx::cancellation_token &token)
Asynchronously sends an HTTP request with a string body. Assumes the character encoding of the string...
Definition: http_client.h:611
void set_nativehandle_options(const std::function< void(native_handle)> &callback)
Sets a callback to enable custom setting of platform specific options.
Definition: http_client.h:318
size_t chunksize() const
Get the client chunk size.
Definition: http_client.h:235
pplx::task< http_response > request(const method &mtd, const utf8string &path_query_fragment, utf8string &&body_data, const utf8string &content_type="text/plain; charset=utf-8", const pplx::cancellation_token &token=pplx::cancellation_token::none())
Asynchronously sends an HTTP request with a string body. Assumes the character encoding of the string...
Definition: http_client.h:527
pplx::task< http_response > request(const method &mtd, const utf8string &path_query_fragment, const utf8string &body_data, const utf8string &content_type="text/plain; charset=utf-8", const pplx::cancellation_token &token=pplx::cancellation_token::none())
Asynchronously sends an HTTP request with a string body. Assumes the character encoding of the string...
Definition: http_client.h:504
The web namespace contains functionality common to multiple protocols like HTTP and WebSockets...
Definition: base_uri.h:37
void set_guarantee_order(bool guarantee_order)
Set the 'guarantee order' property
Definition: http_client.h:198
const std::function< void(boost::asio::ssl::context &)> & get_ssl_context_callback() const
Gets the user's callback to allow for customization of the ssl context.
Definition: http_client.h:345
pplx::task< http_response > request(const method &mtd, const utility::string_t &path_query_fragment, const json::value &body_data, const pplx::cancellation_token &token=pplx::cancellation_token::none())
Asynchronously sends an HTTP request.
Definition: http_client.h:482
void set_chunksize(size_t size)
Sets the client chunk size.
Definition: http_client.h:245
HTTP client class, used to maintain a connection to an HTTP service for an extended session...
Definition: http_client.h:383
void set_validate_certificates(bool validate_certs)
Sets the server certificate validation property.
Definition: http_client.h:275
HTTP client configuration class, used to set the possible configuration options used to create an htt...
Definition: http_client.h:90
pplx::task< http_response > request(const method &mtd, const utf8string &path_query_fragment, const utf8string &body_data, const pplx::cancellation_token &token)
Asynchronously sends an HTTP request with a string body. Assumes the character encoding of the string...
Definition: http_client.h:572
utility::seconds timeout() const
Get the timeout
Definition: http_client.h:207
_ASYNCRTIMP pplx::task< http_response > request(http_request request, const pplx::cancellation_token &token=pplx::cancellation_token::none())
Asynchronously sends an HTTP request.
bool is_default_chunksize() const
Returns true if the default chunk size is in use.
Definition: http_client.h:255
_ASYNCRTIMP utility::string_t __cdecl to_string_t(std::string &&s)
Converts to a platform dependent Unicode string type.
void set_body(utf8string &&body_text, const utf8string &content_type=utf8string("text/plain; charset=utf-8"))
Sets the body of the message to a textual string and set the "Content-Type" header. Assumes the character encoding of the string is UTF-8.
Definition: http_msg.h:921
utility::string_t method
Predefined method strings for the standard HTTP methods mentioned in the HTTP 1.1 specification...
Definition: http_msg.h:62
web_proxy represents the concept of the web proxy, which can be auto-discovered, disabled, or specified explicitly by the user.
Definition: web_utilities.h:157
OAuth 1.0 configuration class.
Definition: oauth1.h:238
_ASYNCRTIMP const http_client_config & client_config() const
Get client configuration object
Definition: http_client_impl.h:454
_ASYNCRTIMP utf16string __cdecl to_utf16string(const std::string &value)
Converts to a UTF-16 from string.
~http_client() CPPREST_NOEXCEPT
Note the destructor doesn't necessarily close the connection and release resources. The connection is reference counted with the http_responses.
Definition: http_client.h:403
T timeout() const
Get the timeout
Definition: http_client.h:217
The Parallel Patterns Library (PPL) task class. A task object represents work that can be executed as...
Definition: pplxtasks.h:176
pplx::task< http_response > request(const method &mtd, const utf8string &path_query_fragment, utf8string &&body_data, const pplx::cancellation_token &token)
Asynchronously sends an HTTP request with a string body. Assumes the character encoding of the string...
Definition: http_client.h:590
The cancellation_token class represents the ability to determine whether some operation has been requ...
Definition: pplxcancellation_token.h:712
void invoke_nativehandle_options(native_handle handle) const
Invokes a user's callback to allow for customization of the request.
Definition: http_client.h:327
A JSON value represented as a C++ class.
Definition: json.h:83
_ASYNCRTIMP const uri & base_uri() const
Gets the base URI.
Definition: http_client_impl.h:460
const web_proxy & proxy() const
Get the web proxy object
Definition: http_client.h:152
void set_proxy(web_proxy proxy)
Set the web proxy object
Definition: http_client.h:161
pplx::task< http_response > request(const method &mtd, const pplx::cancellation_token &token=pplx::cancellation_token::none())
Asynchronously sends an HTTP request.
Definition: http_client.h:451
pplx::task< http_response > request(const method &mtd, const utility::string_t &path_query_fragment, const pplx::cancellation_token &token=pplx::cancellation_token::none())
Asynchronously sends an HTTP request.
Definition: http_client.h:464
static cancellation_token none()
Returns a cancellation token which can never be subject to cancellation.
Definition: pplxcancellation_token.h:724
Represents an HTTP request.
Definition: http_msg.h:771
bool guarantee_order() const
Get the 'guarantee order' property
Definition: http_client.h:188
pplx::task< http_response > request(const method &mtd, const utility::string_t &path_query_fragment, const concurrency::streams::istream &body, size_t content_length, const utility::string_t &content_type=_XPLATSTR("application/octet-stream"), const pplx::cancellation_token &token=pplx::cancellation_token::none())
Asynchronously sends an HTTP request.
Definition: http_client.h:672
const std::shared_ptr< oauth1::experimental::oauth1_config > oauth1() const
Get OAuth 1.0 configuration.
Definition: http_client.h:115
pplx::task< http_response > request(const method &mtd, const utility::string_t &path_query_fragment, const concurrency::streams::istream &body, size_t content_length, const pplx::cancellation_token &token)
Asynchronously sends an HTTP request.
Definition: http_client.h:696
void set_oauth1(oauth1::experimental::oauth1_config config)
Set OAuth 1.0 configuration.
Definition: http_client.h:124
void set_oauth2(oauth2::experimental::oauth2_config config)
Set OAuth 2.0 configuration.
Definition: http_client.h:143
void add_handler(const std::function< pplx::task< http_response >(http_request, std::shared_ptr< http::http_pipeline_stage >)> &handler)
Adds an HTTP pipeline stage to the client.
Definition: http_client.h:423
void set_ssl_context_callback(const std::function< void(boost::asio::ssl::context &)> &callback)
Sets a callback to enable custom setting of the ssl context, at construction time.
Definition: http_client.h:337
void set_credentials(const http::client::credentials &cred)
Set the client credentials
Definition: http_client.h:179
bool validate_certificates() const
Gets the server certificate validation property.
Definition: http_client.h:265
pplx::task< http_response > request(const method &mtd, const utility::string_t &path_query_fragment, const concurrency::streams::istream &body, const pplx::cancellation_token &token)
Asynchronously sends an HTTP request.
Definition: http_client.h:651
void set_timeout(const T &timeout)
Set the timeout
Definition: http_client.h:226