1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *
4 * Copyright (C) 2017 - ESI-Group - Cedric Delamarre
5 *
6 * This file is hereby licensed under the terms of the GNU GPL v2.0,
7 * pursuant to article 5.3.4 of the CeCILL v.2.1.
8 * This file was originally licensed under the terms of the CeCILL v2.1,
9 * and continues to be available under such terms.
10 * For more information, see the COPYING file which you should have received
11 * along with this program.
12 *
13 */
14 #include <stdio.h>
15 #include "sciCurl.hxx"
16 #include "string.hxx"
17 #include "json.hxx"
18
19 extern "C"
20 {
21 #include "getScilabPreference.h"
22 #include "freeArrayOfString.h"
23 #include "getos.h"
24 #include "version.h"
25 }
26
27 SciCurl* SciCurl::me = nullptr;
28 std::string SciCurl::data;
29 bool SciCurl::useFile = false;
30
getInstance(void)31 SciCurl* SciCurl::getInstance(void)
32 {
33 if(me == nullptr)
34 {
35 me = new SciCurl();
36 }
37
38 return me;
39 }
40
destroyInstance(void)41 void SciCurl::destroyInstance(void)
42 {
43 if (me)
44 {
45 delete me;
46 me = nullptr;
47 }
48 }
49
SciCurl()50 SciCurl::SciCurl()
51 {
52 curl_global_init(CURL_GLOBAL_ALL);
53 }
54
~SciCurl()55 SciCurl::~SciCurl()
56 {
57 curl_global_cleanup();
58 }
59
getResultAsObject(CURL * curl)60 void SciCurl::getResultAsObject(CURL* curl)
61 {
62 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, SciCurl::write_result);
63 useFile = false;
64 }
65
getResultAsFile(CURL * curl,FILE * fd)66 void SciCurl::getResultAsFile(CURL* curl, FILE* fd)
67 {
68 #ifdef _MSC_VER
69 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, SciCurl::write_result);
70 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fd);
71 useFile = true;
72 #else
73 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
74 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fd);
75 #endif
76 }
77
getResult()78 types::InternalType* SciCurl::getResult()
79 {
80 types::InternalType* res = fromJSON(data);
81 if (res == nullptr)
82 {
83 res = new types::String(data.c_str());
84 }
85
86 clear();
87
88 return res;
89 }
90
clear()91 void SciCurl::clear()
92 {
93 data.clear();
94 }
95
write_result(char * pcInput,size_t size,size_t nmemb,void * output)96 int SciCurl::write_result(char* pcInput, size_t size, size_t nmemb, void* output)
97 {
98 #ifdef _MSC_VER
99 if(useFile)
100 {
101 FILE* fd = (FILE*)output;
102 fwrite(pcInput, size, nmemb, fd);
103 return static_cast<int>(size*nmemb);
104 }
105 #endif
106
107 std::string d(pcInput, size * nmemb);
108 data += d;
109 return static_cast<int>(size*nmemb);
110 }
111
112 // Proxy is configured in scilab preferences (internet tab)
setProxy(CURL * curl)113 int SciCurl::setProxy(CURL* curl)
114 {
115 char* proxyUserPwd = NULL;
116 const char* attrs[] = {"enabled", "host", "port", "user", "password"};
117 const unsigned int N = sizeof(attrs) / sizeof(char*);
118 char** values = getPrefAttributesValues("//web/body/proxy", attrs, N);
119
120 if (values == NULL)
121 {
122 // no proxy configured
123 return 0;
124 }
125
126 // proxy is configured and not enabled
127 if (stricmp(values[0]/*enabled*/, "false") == 0)
128 {
129 freeArrayOfString(values, N);
130 return 0;
131 }
132
133 const unsigned int host_len = (const unsigned int)strlen(values[1]);
134 const unsigned int port_len = (const unsigned int)strlen(values[2]);
135 const unsigned int user_len = (const unsigned int)strlen(values[3]);
136 const unsigned int pwd_len = (const unsigned int)strlen(values[4]);
137
138 if(host_len == 0 || port_len == 0 || user_len == 0)
139 {
140 freeArrayOfString(values, N);
141 return 1;
142 }
143
144 if (pwd_len == 0)
145 {
146 proxyUserPwd = values[3]; //user
147 }
148 else
149 {
150 proxyUserPwd = (char *)MALLOC((user_len + 1 + pwd_len + 1) * sizeof(char));
151 sprintf(proxyUserPwd, "%s:%s", values[3]/*user*/, values[4]/*password*/);
152 proxyUserPwd[user_len + 1 + pwd_len] = '\0';
153 }
154
155 // set cURL options
156 if(curl_easy_setopt(curl, CURLOPT_PROXY, values[1]) != CURLE_OK) //host
157 {
158 FREE(proxyUserPwd);
159 freeArrayOfString(values, N);
160 return 1;
161 }
162
163 if(curl_easy_setopt(curl, CURLOPT_PROXYPORT, strtol(values[2], NULL, 10)) != CURLE_OK) //port
164 {
165 FREE(proxyUserPwd);
166 freeArrayOfString(values, N);
167 return 1;
168 }
169
170 if(curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxyUserPwd) != CURLE_OK) //port
171 {
172 FREE(proxyUserPwd);
173 freeArrayOfString(values, N);
174 return 1;
175 }
176
177 FREE(proxyUserPwd);
178 freeArrayOfString(values, N);
179 return 0;
180 }
181
setCommonHeaders(CURL * curl)182 void SciCurl::setCommonHeaders(CURL* curl)
183 {
184 char* OperatingSystem = getOSFullName();
185 char* Release = getOSRelease();
186
187 // Scilab version
188 std::string pcUserAgent = "Scilab/" + std::to_string(SCI_VERSION_MAJOR)+"."+ std::to_string(SCI_VERSION_MINOR)+"."+ std::to_string(SCI_VERSION_MAINTENANCE);
189 // OS name
190 pcUserAgent += " (" + std::string(OperatingSystem) + " " + std::string(Release) + ")";
191 // set user agent header
192 curl_easy_setopt(curl, CURLOPT_USERAGENT, pcUserAgent.data());
193
194 FREE(OperatingSystem);
195 FREE(Release);
196 }