MiKTeX 26.5-next
A scalable TeX distribution
Loading...
Searching...
No Matches
CurlWebSession.h
1/* CurlWebSession.h: -*- C++ -*-
2
3 Copyright (C) 2001-2019 Christian Schenk
4
5 This file is part of MiKTeX Package Manager.
6
7 MiKTeX Package Manager is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2, or
10 (at your option) any later version.
11
12 MiKTeX Package Manager is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with MiKTeX Package Manager; if not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22#if !defined(A9010DA64FD34372A24071A29FA59EEC)
23#define A9010DA64FD34372A24071A29FA59EEC
24
25#if defined(HAVE_LIBCURL)
26
27#include <memory>
28#include <string>
29#include <unordered_map>
30
31#include <curl/curl.h>
32
33#include <miktex/Core/Session>
34#include <miktex/Trace/Trace>
35#include <miktex/Trace/TraceStream>
36
37#include "WebSession.h"
38#include "text.h"
39
40MPM_INTERNAL_BEGIN_NAMESPACE;
41
42class CurlWebSession :
43 public std::enable_shared_from_this<CurlWebSession>,
44 public WebSession
45{
46public:
47 CurlWebSession(IProgressNotify_* callback);
48
49public:
50 ~CurlWebSession() override;
51
52public:
53 std::unique_ptr<WebFile> OpenUrl(const std::string& url) override
54 {
55 return OpenUrl(url, {});
56 }
57
58public:
59 std::unique_ptr<WebFile> OpenUrl(const std::string& url, const std::unordered_map<std::string, std::string>& formData) override;
60
61public:
62 void Dispose() override;
63
64public:
65 void Connect();
66
67public:
68 void Perform();
69
70private:
71 void ReadInformationals();
72
73public:
74 std::string GetCurlErrorString(CURLMcode code) const
75 {
76#if LIBCURL_VERSION_NUM >= 0x70c00
77 if (curlVersionInfo->version_num >= 0x70c00)
78 {
79 return curl_multi_strerror(code);
80 }
81#endif
82 std::string str = T_("The cURL multi interface returned an error code: ");
83 str += std::to_string(code);
84 return str;
85 }
86
87public:
88 void FatalCurlError(CURLMcode code) const
89 {
90 MIKTEX_FATAL_ERROR(GetCurlErrorString(code));
91 }
92
93public:
94 void ExpectOK(CURLMcode code) const
95 {
96 if (code != CURLM_OK)
97 {
98 FatalCurlError(code);
99 }
100 }
101
102private:
103 CURL* pCurl = nullptr;
104
105private:
106 CURLM* pCurlm = nullptr;
107
108private:
109 int runningHandles = -1;
110
111public:
112 bool IsReady() const
113 {
114 return runningHandles == 0;
115 }
116
117public:
118 CURL* GetEasyHandle() const throw ()
119 {
120 return pCurl;
121 }
122
123public:
124 CURLM* GetMultiHandle() const throw ()
125 {
126 return pCurlm;
127 }
128
129public:
130 std::string GetCurlErrorString(CURLcode code) const
131 {
132#if LIBCURL_VERSION_NUM >= 0x70c00
133 if (curlVersionInfo->version_num >= 0x70c00)
134 {
135 return curl_easy_strerror(code);
136 }
137 else
138#endif
139 {
140 std::string str = T_("The cURL easy interface returned an error code: ");
141 str += std::to_string(code);
142 return str;
143 }
144 }
145
146public:
147 void FatalCurlError(CURLcode code, const char* effectiveUrl) const;
148
149public:
150 void ExpectOK(CURLcode code, const char* effectiveUrl) const
151 {
152 if (code != CURLE_OK)
153 {
154 FatalCurlError(code, effectiveUrl);
155 }
156 }
157
158public:
159 template<class T> void SetOption(CURLoption option, T val) const
160 {
161 CURLcode code = curl_easy_setopt(pCurl, option, val);
162 if (code != CURLE_OK)
163 {
164 MIKTEX_FATAL_ERROR_2(GetCurlErrorString(code), "option", std::to_string(option));
165 }
166 }
167
168public:
169 std::string UrlEncode(const std::string& s) const
170 {
171 char* encoded = curl_easy_escape(pCurl, s.c_str(), static_cast<int>(s.length()));
172 std::string result = encoded;
173 curl_free(encoded);
174 return result;
175 }
176
177public:
178 void SetCustomHeaders(const std::unordered_map<std::string, std::string>& headers) override;
179
180private:
181 void Initialize();
182
183private:
184 static int ProgressCallback(void* pv, double dltotal, double dlnow, double ultotal, double ulnow);
185
186private:
187 static int DebugCallback(CURL* pCurl, curl_infotype infoType, char* pData, std::size_t sizeData, void* pv);
188
189private:
190 std::string proxyPort;
191
192private:
193 std::string userPassword;
194
195private:
196 struct curl_slist* headers = nullptr;
197
198private:
199 curl_version_info_data* curlVersionInfo = nullptr;
200
201private:
202 std::unique_ptr<MiKTeX::Trace::TraceStream> trace_curl;
203
204private:
205 std::unique_ptr<MiKTeX::Trace::TraceStream> trace_mpm;
206
207private:
208 std::shared_ptr<MiKTeX::Core::Session> session = MIKTEX_SESSION();
209};
210
211MPM_INTERNAL_END_NAMESPACE;
212
213#endif
214
215#endif