1 | /* |
2 | * IXHttpClient.h |
3 | * Author: Benjamin Sergeant |
4 | * Copyright (c) 2019 Machine Zone, Inc. All rights reserved. |
5 | */ |
6 | |
7 | #pragma once |
8 | |
9 | #include "IXHttp.h" |
10 | #include "IXSocket.h" |
11 | #include "IXSocketTLSOptions.h" |
12 | #include "IXWebSocketHttpHeaders.h" |
13 | #include <algorithm> |
14 | #include <atomic> |
15 | #include <condition_variable> |
16 | #include <functional> |
17 | #include <map> |
18 | #include <memory> |
19 | #include <mutex> |
20 | #include <queue> |
21 | #include <thread> |
22 | |
23 | namespace ix |
24 | { |
25 | class HttpClient |
26 | { |
27 | public: |
28 | HttpClient(bool async = false); |
29 | ~HttpClient(); |
30 | |
31 | HttpResponsePtr get(const std::string& url, HttpRequestArgsPtr args); |
32 | HttpResponsePtr (const std::string& url, HttpRequestArgsPtr args); |
33 | HttpResponsePtr Delete(const std::string& url, HttpRequestArgsPtr args); |
34 | |
35 | HttpResponsePtr post(const std::string& url, |
36 | const HttpParameters& httpParameters, |
37 | const HttpFormDataParameters& httpFormDataParameters, |
38 | HttpRequestArgsPtr args); |
39 | HttpResponsePtr post(const std::string& url, |
40 | const std::string& body, |
41 | HttpRequestArgsPtr args); |
42 | |
43 | HttpResponsePtr put(const std::string& url, |
44 | const HttpParameters& httpParameters, |
45 | const HttpFormDataParameters& httpFormDataParameters, |
46 | HttpRequestArgsPtr args); |
47 | HttpResponsePtr put(const std::string& url, |
48 | const std::string& body, |
49 | HttpRequestArgsPtr args); |
50 | |
51 | HttpResponsePtr patch(const std::string& url, |
52 | const HttpParameters& httpParameters, |
53 | const HttpFormDataParameters& httpFormDataParameters, |
54 | HttpRequestArgsPtr args); |
55 | HttpResponsePtr patch(const std::string& url, |
56 | const std::string& body, |
57 | HttpRequestArgsPtr args); |
58 | |
59 | HttpResponsePtr request(const std::string& url, |
60 | const std::string& verb, |
61 | const std::string& body, |
62 | HttpRequestArgsPtr args, |
63 | int redirects = 0); |
64 | |
65 | HttpResponsePtr request(const std::string& url, |
66 | const std::string& verb, |
67 | const HttpParameters& httpParameters, |
68 | const HttpFormDataParameters& httpFormDataParameters, |
69 | HttpRequestArgsPtr args); |
70 | |
71 | void setForceBody(bool value); |
72 | |
73 | // Async API |
74 | HttpRequestArgsPtr createRequest(const std::string& url = std::string(), |
75 | const std::string& verb = HttpClient::kGet); |
76 | |
77 | bool performRequest(HttpRequestArgsPtr request, |
78 | const OnResponseCallback& onResponseCallback); |
79 | |
80 | // TLS |
81 | void setTLSOptions(const SocketTLSOptions& tlsOptions); |
82 | |
83 | std::string serializeHttpParameters(const HttpParameters& httpParameters); |
84 | |
85 | std::string serializeHttpFormDataParameters( |
86 | const std::string& multipartBoundary, |
87 | const HttpFormDataParameters& httpFormDataParameters, |
88 | const HttpParameters& httpParameters = HttpParameters()); |
89 | |
90 | std::string generateMultipartBoundary(); |
91 | |
92 | std::string urlEncode(const std::string& value); |
93 | |
94 | const static std::string kPost; |
95 | const static std::string kGet; |
96 | const static std::string kHead; |
97 | const static std::string kDelete; |
98 | const static std::string kPut; |
99 | const static std::string kPatch; |
100 | |
101 | private: |
102 | void log(const std::string& msg, HttpRequestArgsPtr args); |
103 | |
104 | // Async API background thread runner |
105 | void run(); |
106 | // Async API |
107 | bool _async; |
108 | std::queue<std::pair<HttpRequestArgsPtr, OnResponseCallback>> _queue; |
109 | mutable std::mutex _queueMutex; |
110 | std::condition_variable _condition; |
111 | std::atomic<bool> _stop; |
112 | std::thread _thread; |
113 | |
114 | std::unique_ptr<Socket> _socket; |
115 | std::recursive_mutex _mutex; // to protect accessing the _socket (only one socket per |
116 | // client) the mutex needs to be recursive as this function |
117 | // might be called recursively to follow HTTP redirections |
118 | |
119 | SocketTLSOptions _tlsOptions; |
120 | |
121 | bool _forceBody; |
122 | }; |
123 | } // namespace ix |
124 | |