azure-core
win_http_transport.hpp
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // SPDX-License-Identifier: MIT
3 
9 #pragma once
10 
11 #include "azure/core/context.hpp"
12 #include "azure/core/http/http.hpp"
14 
15 #include <azure/core/platform.hpp>
16 
17 #if defined(AZ_PLATFORM_WINDOWS)
18 #if !defined(WIN32_LEAN_AND_MEAN)
19 #define WIN32_LEAN_AND_MEAN
20 #endif
21 #if !defined(NOMINMAX)
22 #define NOMINMAX
23 #endif
24 #include <windows.h>
25 #endif
26 
27 #include <type_traits>
28 #include <vector>
29 #include <winhttp.h>
30 
31 namespace Azure { namespace Core { namespace Http {
32 
33  namespace _detail {
34 
35  constexpr static size_t DefaultUploadChunkSize = 1024 * 64;
36  constexpr static size_t MaximumUploadChunkSize = 1024 * 1024;
37 
38  struct HandleManager final
39  {
40  Context const& m_context;
41  Request& m_request;
42  HINTERNET m_connectionHandle;
43  HINTERNET m_requestHandle;
44 
45  HandleManager(Request& request, Context const& context)
46  : m_request(request), m_context(context)
47  {
48  m_connectionHandle = NULL;
49  m_requestHandle = NULL;
50  }
51 
52  ~HandleManager()
53  {
54  // Close the handles and set them to null to avoid multiple calls to WinHTTP to close the
55  // handles.
56  if (m_requestHandle)
57  {
58  WinHttpCloseHandle(m_requestHandle);
59  m_requestHandle = NULL;
60  }
61 
62  if (m_connectionHandle)
63  {
64  WinHttpCloseHandle(m_connectionHandle);
65  m_connectionHandle = NULL;
66  }
67  }
68  };
69 
70  class WinHttpStream final : public Azure::Core::IO::BodyStream {
71  private:
72  std::unique_ptr<HandleManager> m_handleManager;
73  bool m_isEOF;
74 
86  int64_t m_contentLength;
87 
88  int64_t m_streamTotalRead;
89 
99  size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override;
100 
101  public:
102  WinHttpStream(std::unique_ptr<HandleManager> handleManager, int64_t contentLength)
103  : m_handleManager(std::move(handleManager)), m_contentLength(contentLength),
104  m_isEOF(false), m_streamTotalRead(0)
105  {
106  }
107 
113  int64_t Length() const override { return this->m_contentLength; }
114  };
115  } // namespace _detail
116 
122  {
127  };
128 
133  class WinHttpTransport final : public HttpTransport {
134  private:
135  WinHttpTransportOptions m_options;
136 
137  // This should remain immutable and not be modified after calling the ctor, to avoid threading
138  // issues.
139  HINTERNET m_sessionHandle = NULL;
140 
141  HINTERNET CreateSessionHandle();
142  void CreateConnectionHandle(std::unique_ptr<_detail::HandleManager>& handleManager);
143  void CreateRequestHandle(std::unique_ptr<_detail::HandleManager>& handleManager);
144  void Upload(std::unique_ptr<_detail::HandleManager>& handleManager);
145  void SendRequest(std::unique_ptr<_detail::HandleManager>& handleManager);
146  void ReceiveResponse(std::unique_ptr<_detail::HandleManager>& handleManager);
147  int64_t GetContentLength(
148  std::unique_ptr<_detail::HandleManager>& handleManager,
149  HttpMethod requestMethod,
150  HttpStatusCode responseStatusCode);
151  std::unique_ptr<RawResponse> SendRequestAndGetResponse(
152  std::unique_ptr<_detail::HandleManager> handleManager,
153  HttpMethod requestMethod);
154 
155  public:
162 
171  virtual std::unique_ptr<RawResponse> Send(Request& request, Context const& context) override;
172 
174  {
175  // Close the handles and set them to null to avoid multiple calls to WinHTTP to close the
176  // handles.
177  if (m_sessionHandle)
178  {
179  WinHttpCloseHandle(m_sessionHandle);
180  m_sessionHandle = NULL;
181  }
182  }
183  };
184 
185 }}} // namespace Azure::Core::Http
Azure::Core::Http::WinHttpTransport::WinHttpTransport
WinHttpTransport(WinHttpTransportOptions const &options=WinHttpTransportOptions())
Constructs WinHttpTransport.
Definition: win_http_transport.cpp:276
context.hpp
Context for canceling long running operations.
Azure::Core::IO::BodyStream
Used to read data to/from a service.
Definition: body_stream.hpp:32
Azure::Core::Http::WinHttpTransportOptions
Sets the WinHTTP session and connection options used to customize the behavior of the transport.
Definition: win_http_transport.hpp:122
Azure::Core::Http::Request
A request message from a client to a server.
Definition: http.hpp:176
Azure::Core::Http::HttpMethod
The method to be performed on the resource identified by the Request.
Definition: http.hpp:94
Azure
Azure SDK abstractions.
Definition: azure_assert.hpp:55
http.hpp
HTTP request and response functionality.
Azure::Core::Http::HttpTransport
Base class for all HTTP transport implementations.
Definition: transport.hpp:19
Azure::Core::Http::WinHttpTransportOptions::IgnoreUnknownCertificateAuthority
bool IgnoreUnknownCertificateAuthority
When true, allows an invalid certificate authority.
Definition: win_http_transport.hpp:126
platform.hpp
Platform-specific macros.
transport.hpp
Utilities to be used by HTTP transport implementations.
Azure::Core::IO::BodyStream::Length
virtual int64_t Length() const =0
Get the length of the data.
Azure::Core::Context
A context is a node within a tree that represents deadlines and key/value pairs.
Definition: context.hpp:45
Azure::Core::Http::WinHttpTransport
Concrete implementation of an HTTP transport that uses WinHTTP when sending and receiving requests an...
Definition: win_http_transport.hpp:133
Azure::Core::Http::HttpStatusCode
HttpStatusCode
Defines the possible HTTP status codes.
Definition: http_status_code.hpp:18
Azure::Core::Http::WinHttpTransport::Send
virtual std::unique_ptr< RawResponse > Send(Request &request, Context const &context) override
Implements the HTTP transport interface to send an HTTP Request and produce an HTTP RawResponse.
Definition: win_http_transport.cpp:653