[Curl] Use SQLite database in cookie jar implementation for Curl port
[WebKit-https.git] / Source / WebCore / platform / network / curl / CurlContext.h
1 /*
2  * Copyright (C) 2013 Apple Inc.  All rights reserved.
3  * Copyright (C) 2017 Sony Interactive Entertainment Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #pragma once
28
29 #include "CurlSSLHandle.h"
30 #include "URL.h"
31
32 #include <wtf/Lock.h>
33 #include <wtf/NeverDestroyed.h>
34 #include <wtf/Noncopyable.h>
35 #include <wtf/Threading.h>
36
37 #if OS(WINDOWS)
38 #include <windows.h>
39 #include <winsock2.h>
40 #endif
41
42 #include <curl/curl.h>
43
44 namespace WebCore {
45
46 enum class CurlProxyType {
47     Invalid = -1,
48     HTTP = CURLPROXY_HTTP,
49     Socks4 = CURLPROXY_SOCKS4,
50     Socks4A = CURLPROXY_SOCKS4A,
51     Socks5 = CURLPROXY_SOCKS5,
52     Socks5Hostname = CURLPROXY_SOCKS5_HOSTNAME
53 };
54
55 // CurlGlobal --------------------------------------------
56 // to make the initialization of libcurl happen before other initialization of CurlContext
57
58 class CurlGlobal {
59 protected:
60     CurlGlobal()
61     {
62         curl_global_init(CURL_GLOBAL_ALL);
63     }
64     
65     virtual ~CurlGlobal()
66     {
67         curl_global_cleanup();
68     }
69 };
70
71 // CurlShareHandle --------------------------------------------
72
73 class CurlShareHandle {
74     WTF_MAKE_NONCOPYABLE(CurlShareHandle);
75
76 public:
77     CurlShareHandle();
78     ~CurlShareHandle();
79
80     CURLSH* handle() const { return m_shareHandle; }
81
82 private:
83     static void lockCallback(CURL*, curl_lock_data, curl_lock_access, void*);
84     static void unlockCallback(CURL*, curl_lock_data, void*);
85     static StaticLock* mutexFor(curl_lock_data);
86
87     CURLSH* m_shareHandle { nullptr };
88 };
89
90 // CurlContext --------------------------------------------
91
92 class CurlContext : public CurlGlobal {
93     WTF_MAKE_NONCOPYABLE(CurlContext);
94     friend NeverDestroyed<CurlContext>;
95 public:
96     struct ProxyInfo {
97         String host;
98         unsigned long port;
99         CurlProxyType type { CurlProxyType::Invalid };
100         String username;
101         String password;
102
103         const String url() const;
104     };
105
106     static CurlContext& singleton();
107
108     virtual ~CurlContext();
109
110     const CurlShareHandle& shareHandle() { return m_shareHandle; }
111
112     // Proxy
113     const ProxyInfo& proxyInfo() const { return m_proxy; }
114     void setProxyInfo(const ProxyInfo& info) { m_proxy = info;  }
115     void setProxyInfo(const String& host = emptyString(), unsigned long port = 0, CurlProxyType = CurlProxyType::HTTP, const String& username = emptyString(), const String& password = emptyString());
116
117     // SSL
118     CurlSSLHandle& sslHandle() { return m_sslHandle; }
119
120     // HTTP/2
121     bool isHttp2Enabled() const;
122
123 #ifndef NDEBUG
124     FILE* getLogFile() const { return m_logFile; }
125     bool isVerbose() const { return m_verbose; }
126 #endif
127
128 private:
129     ProxyInfo m_proxy;
130     CurlShareHandle m_shareHandle;
131     CurlSSLHandle m_sslHandle;
132
133     CurlContext();
134     void initShareHandle();
135
136 #ifndef NDEBUG
137     FILE* m_logFile { nullptr };
138     bool m_verbose { false };
139 #endif
140 };
141
142 // CurlMultiHandle --------------------------------------------
143
144 class CurlMultiHandle {
145     WTF_MAKE_NONCOPYABLE(CurlMultiHandle);
146
147 public:
148     CurlMultiHandle();
149     ~CurlMultiHandle();
150
151     CURLMcode addHandle(CURL*);
152     CURLMcode removeHandle(CURL*);
153
154     CURLMcode getFdSet(fd_set&, fd_set&, fd_set&, int&);
155     CURLMcode perform(int&);
156     CURLMsg* readInfo(int&);
157
158 private:
159     CURLM* m_multiHandle { nullptr };
160 };
161
162 // CurlSList -------------------------------------------------
163
164 class CurlSList {
165 public:
166     CurlSList() { }
167     ~CurlSList() { clear(); }
168
169     operator struct curl_slist** () { return &m_list; }
170
171     const struct curl_slist* head() const { return m_list; }
172     bool isEmpty() const { return !m_list; }
173     void clear()
174     {
175         if (m_list) {
176             curl_slist_free_all(m_list);
177             m_list = nullptr;
178         }
179     }
180
181     void append(const char* str) { m_list = curl_slist_append(m_list, str); }
182     void append(const String& str) { append(str.latin1().data()); }
183
184 private:
185     struct curl_slist* m_list { nullptr };
186 };
187
188 // CurlHandle -------------------------------------------------
189
190 class HTTPHeaderMap;
191 class NetworkLoadMetrics;
192
193 class CurlHandle {
194     WTF_MAKE_NONCOPYABLE(CurlHandle);
195
196 public:
197     enum class VerifyPeer {
198         Disable = 0L,
199         Enable = 1L
200     };
201
202     enum class VerifyHost {
203         LooseNameCheck = 0,
204         StrictNameCheck = 2
205     };
206
207     CurlHandle();
208     virtual ~CurlHandle();
209
210     CURL* handle() const { return m_handle; }
211
212     void initialize();
213
214     CURLcode perform();
215     CURLcode pause(int);
216
217     static const String errorDescription(CURLcode);
218
219     void enableShareHandle();
220
221     void setUrl(const URL&);
222
223     void appendRequestHeaders(const HTTPHeaderMap&);
224     void appendRequestHeader(const String& name, const String& value);
225     void appendRequestHeader(const String& name);
226     void removeRequestHeader(const String& name);
227
228     void enableHttp();
229     void enableHttpGetRequest();
230     void enableHttpHeadRequest();
231     void enableHttpPostRequest();
232     void setPostFields(const char*, long);
233     void setPostFieldLarge(curl_off_t);
234     void enableHttpPutRequest();
235     void setInFileSizeLarge(curl_off_t);
236     void setHttpCustomRequest(const String&);
237
238     void enableAcceptEncoding();
239     void enableAllowedProtocols();
240
241     void enableHttpAuthentication(long);
242     void setHttpAuthUserPass(const String&, const String&);
243
244     void setCACertPath(const char*);
245     void setSslVerifyPeer(VerifyPeer);
246     void setSslVerifyHost(VerifyHost);
247     void setSslCert(const char*);
248     void setSslCertType(const char*);
249     void setSslKeyPassword(const char*);
250
251     void enableProxyIfExists();
252
253     void enableTimeout();
254     void setTimeout(long timeoutMilliseconds);
255
256     // Callback function
257     void setHeaderCallbackFunction(curl_write_callback, void*);
258     void setWriteCallbackFunction(curl_write_callback, void*);
259     void setReadCallbackFunction(curl_read_callback, void*);
260     void setSslCtxCallbackFunction(curl_ssl_ctx_callback, void*);
261
262     // Status
263     std::optional<uint16_t> getPrimaryPort();
264     std::optional<long> getResponseCode();
265     std::optional<long> getHttpConnectCode();
266     std::optional<long long> getContentLength();
267     std::optional<long> getHttpAuthAvail();
268     std::optional<long> getHttpVersion();
269     std::optional<NetworkLoadMetrics> getNetworkLoadMetrics();
270
271     static long long maxCurlOffT();
272
273 #ifndef NDEBUG
274     void enableVerboseIfUsed();
275     void enableStdErrIfUsed();
276 #endif
277
278 private:
279     void enableRequestHeaders();
280     static int expectedSizeOfCurlOffT();
281
282     CURL* m_handle { nullptr };
283     char m_errorBuffer[CURL_ERROR_SIZE] { };
284
285     CurlSList m_requestHeaders;
286 };
287
288 } // namespace WebCore