[webtools] Header fixed about User-Agent
[scilab.git] / scilab / modules / webtools / src / cpp / sciCurl.cpp
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
31 SciCurl* SciCurl::getInstance(void)
32 {
33     if(me == nullptr)
34     {
35         me = new SciCurl();
36     }
37
38     return me;
39 }
40
41 void SciCurl::destroyInstance(void)
42 {
43     if (me)
44     {
45         delete me;
46         me = nullptr;
47     }
48 }
49
50 SciCurl::SciCurl()
51 {
52     curl_global_init(CURL_GLOBAL_ALL);
53 }
54
55 SciCurl::~SciCurl()
56 {
57     curl_global_cleanup();
58 }
59
60 void SciCurl::getResultAsObject(CURL* curl)
61 {
62     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, SciCurl::write_result);
63     useFile = false;
64 }
65
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
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
91 void SciCurl::clear()
92 {
93     data.clear();
94 }
95
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)
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
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 }