wsdlpull svntrunk
Loading...
Searching...
No Matches
XmlUtils.cpp
Go to the documentation of this file.
1/*
2* wsdlpull- A C++ parser for WSDL (Web services description language)
3* Copyright (C) 2005-2007 Vivek Krishna
4*
5* This library is free software; you can redistribute it and/or
6* modify it under the terms of the GNU Library General Public
7* License as published by the Free Software Foundation; either
8* version 2 of the License, or (at your option) any later version.
9*
10* This library is distributed in the hope that it will be useful,
11* but WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13* Library General Public License for more details.
14*
15* You should have received a copy of the GNU Library General Public
16* License along with this library; if not, write to the Free
17* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*
19*
20*/
21
22#ifdef _WIN32
23#include <windows.h>
24#include <winreg.h>
25#include <wininet.h>
26#include <w3c.h>
27#pragma comment(lib, "wininet.lib")
28#endif
29
30#ifdef HAVE_CONFIG_H //
31#include <config.h>
32#endif
33
34#ifndef _WIN32
35#include <termios.h>
36#include <unistd.h>
37#include <errno.h>
38#include <pthread.h>
39#include <cstdlib>
40#endif
41
42#ifdef WITH_CURL
43#include <curl/curl.h>
44#endif
45
46#include <ctime>
47#include <climits>
48#include <cstring>
49#include <fstream>
50#include <sstream>
51#include <map>
52#include <list>
53
54#include "xmlpull/XmlUtils.h"
55
56
57// Global variables
58#ifdef _WIN32
59CRITICAL_SECTION cs;
60#else
61static pthread_mutex_t url_mutex;
62#endif
63// key is uri+ProcId+ThreadId
64// elem is string with the uri
65std::map<std::string, std::string> urlCache_;
66
67//put all I/O and std::string manip utiliy functions here
68
69int
70XmlUtils::parseInt (std::string s, int radix)
71{
72 int len = s.size ();
73 int value = 0;
74 if (s.empty ())
75 return -1;
76 for (int i = 0; i < len; i++) {
77 if (radix == 10) {
78 if (s[i] <= '9' && s[i] >= '0')
79 value = (i == 0) ? (s[i] - '0') : radix * value + (s[i] - '0');
80
81 else
82 return value;//return what is parsed till then
83 }
84 else if (radix == 16) {
85 //assumes that the encoding format has arranges the alphabets and numbers in increasing order
86 if (s[i] <= '9' && s[i] >= 0)
87 value = (i == 0) ? (s[i] - '0') : radix * value + (s[i] - '0');
88
89 else if (s[i] <= 'F' && s[i] >= 'A')
90 value =
91 (i ==
92 0) ? (s[i] - 'A') + 10 : radix * value + (s[i] - 'A') + 10;
93
94 else if (s[i] <= 'f' && s[i] >= 'a')
95 value =(i ==0) ? (s[i] - 'a') + 10 : radix * value + (s[i] - 'a') + 10;
96 }
97 }
98 return value;
99}
100
101
102std::ostream &
103XmlUtils::dbsp (std::ostream & str)
104{
105 return str << " ";
106}
107
108
109std::ostream &
110XmlUtils::blk (std::ostream & str)
111{
112 return str << std::endl << "*************" << std::endl;
113}
114
115
116// get file name
117std::string
118XmlUtils::getFileName(std::string uri)
119{
120 std::string filename;
121
122 // unique key url + suffix, see also XmlUtils::creUriFile
123 std::string map_key(uri + XmlUtils::getSuffix());
124
125 // Lock actions on urlCache
127
128 if (urlCache_.find(map_key) != urlCache_.end()) {
129 filename = urlCache_[map_key];
130 }
131 else {
132 filename = "";
133 }
134
135 // Unlock actions on urlCache
137
138 return filename;
139}
140
141
142// Create unique file
143std::string
144XmlUtils::creUriFile(std::string uri)
145{
146 // unique key url + suffix, see also XmlUtils::getFileName
147 std::string map_key(uri + XmlUtils::getSuffix());
148
149#ifdef _WIN32
150 char uniqueFile[MAX_PATH];
151 GetTempFileName(".", "uri", 0, (LPSTR)uniqueFile);
152#else
153 char uniqueFile[PATH_MAX];
154 char ufile[] = "/tmp/wsdl_uri_XXXXXX";
155 int fd = mkstemp(ufile);
156 close(fd);
157 strcpy(uniqueFile, ufile);
158#endif
159
160 // Lock actions on urlCache
162
163 urlCache_[map_key] = uniqueFile;
164
165 // Unlock actions on urlCache
167
168 return uniqueFile;
169}
170
171
172// Only files belonging to current proces and thread are deleted
173void
175{
176 std::map<std::string, std::string>::iterator iter;
177 std::list<std::string> uris;
178
179 // Lock actions on urlCache
181
182 for (iter = urlCache_.begin(); iter != urlCache_.end(); iter++) {
183 if ((iter->first).find(XmlUtils::getSuffix()) != std::string::npos) {
184#ifdef _WIN32
185 ::DeleteFile((LPCSTR)iter->second.c_str());
186#else
187 unlink(iter->second.c_str());
188#endif
189 // remember the key to delete the items in the map
190 uris.push_back(iter->first);
191 }
192 }
193
194 // delete items in the map
195 while (!uris.empty()) {
196 iter = urlCache_.find(uris.front());
197 urlCache_.erase(iter);
198 uris.pop_front();
199 }
200
201 // Unlock actions on urlCache
203
204}
205
206
207// File name suffix is constructed of ProcessId and ThreadId
208std::string
210{
211 std::stringstream ssuffix;
212#ifdef _WIN32
213 ssuffix << GetCurrentProcessId() << "_" << GetCurrentThreadId();
214#else
215 ssuffix << getpid() << "_" << pthread_self();
216#endif
217
218 return ssuffix.str();
219}
220
221void
223{
224 /* initialise mutex for map operations */
225#ifdef _WIN32
226 InitializeCriticalSection(&cs);
227#else
228 pthread_mutex_init(&url_mutex, NULL);
229#endif
230}
231
232
233void
235{
236#ifdef _WIN32
237 static volatile int initialized = 0;
238 static HANDLE mtx;
239
240 if (!initialized) {
241 if (!mtx) {
242 HANDLE mymtx;
243 mymtx = CreateMutex(NULL, 0, NULL);
244 if (InterlockedCompareExchangePointer(&mtx, mymtx, NULL) != NULL)
245 CloseHandle(mymtx);
246 }
247
248 WaitForSingleObject(mtx, 0);
249 if (!initialized) {
250 uri_init();
251 initialized = 1;
252 }
253 ReleaseMutex(mtx);
254 }
255#else
256 static pthread_once_t url_once = PTHREAD_ONCE_INIT;
257 pthread_once(&url_once, uri_init);
258#endif
259}
260
261
262void
264{
265#ifdef _WIN32
266 // Request ownership of the critical section.
267 EnterCriticalSection(&cs);
268#else
269 // mutex_start
270 pthread_mutex_lock(&url_mutex);
271#endif
272}
273
274
275void
277{
278#ifdef _WIN32
279 // Release ownership of the critical section.
280 LeaveCriticalSection(&cs);
281#else
282 // mutex_end
283 pthread_mutex_unlock(&url_mutex);
284#endif
285}
286
287
288/*
289 * Fetch a document at the given URI and store it in a file
290 */
291bool
293XmlUtils::fetchUri(std::string uri,
294 std::string& filename)
295{
296
297
298 if (uri.find("http://") != std::string::npos ||
299 uri.find("https://") != std::string::npos ||
300 uri.find("ftp://") != std::string::npos) {
301
302 // mutex init for url map operations
304
305 // initial status is that file does not excist
306 bool file_cached = false;
307
308 // verify if the file already cached and fysical exists
309 filename = XmlUtils::getFileName(uri);
310 if (!filename.empty()) {
311 std::ifstream tfs;
312 tfs.open(filename.c_str());
313 file_cached = !tfs.fail();
314 tfs.close();
315 }
316
317 // if not cached create new file and cach it
318 if (!file_cached) {
319 filename = XmlUtils::creUriFile(uri);
320 }
321 // return if the file is already cached
322 else {
323 return true;
324 }
325
326#ifdef WITH_CURL
327 CURL * curl;
328 CURLcode res;
329 curl=curl_easy_init();
330 FILE * file;
331 if(curl){
332 file=fopen(filename.c_str(),"w");
333
334 if (file == NULL) {
335 fprintf(stderr, "Can't open file %s: %s\n", filename.c_str(),
336 strerror(errno));
337 exit(-1);
338 }
339
340 curl_easy_setopt(curl, CURLOPT_URL,uri.c_str());
341 curl_easy_setopt(curl,CURLOPT_FILE,(void*)file);
342 curl_easy_setopt(curl,CURLOPT_TIMEOUT,60);
343 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
344 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
345
346 if (XmlUtils::getProxy()){
347 curl_easy_setopt(curl,CURLOPT_PROXY,XmlUtils::getProxyHost().c_str());
348 std::string tmp=XmlUtils::getProxyUser()+":"+XmlUtils::getProxyPass();
349 curl_easy_setopt(curl,CURLOPT_PROXYUSERPWD,tmp.c_str());
350 }
351 res = curl_easy_perform(curl);
352
353 curl_easy_cleanup(curl);
354 fclose(file);
355 if(res)
356 return false;
357 else
358 return true;
359 }
360#elif _WIN32
361 std::ofstream ofs(filename.c_str());
362 unsigned long nread;
363 W3Client w3;
364
365 if(w3.Connect(uri.c_str())){
366 if(w3.Request(w3.GetURI())){
367 unsigned char buf[1024]="\0";
368 while((nread=w3.Response(buf, 1023))){
369 buf[nread]='\0';
370 ofs << buf;
371 }
372 }
373 w3.Close();
374 }
375 ofs.close();
376 return true;
377
378#else
379 return false;
380#endif
381 }
382 else {
383 /*
384 * assume its a file on the disk
385 */
386 // modifications from F.V. Fri Nov 30 09:42:06 CET 2007:
387 // - #ifdef replaced by #if !defined,
388 // - added p to get the start position,
389 // - revised offsets
390 // - use-case with a single '/' added (I am not sure this is conform to spec)
391// #ifdef _WIN32
392#if !defined(_WIN32)
393 /*
394 unsigned int p;
395 if ((p=uri.find("file:///"))!=std::string::npos)
396 {
397 uri = uri.substr(p+7, uri.length()-p-7);
398 }
399 else if ((p=uri.find("file://"))!=std::string::npos)
400 {
401 uri = uri.substr(p+6, uri.length()-p-6);
402 }
403 else if ((p=uri.find("file:/"))!=std::string::npos)
404 {
405 uri = uri.substr(p+5, uri.length()-p-5);
406 }
407 */
408 std::string::size_type p;
409 p = uri.find("file:");
410 if ( p !=std::string::npos)
411 {
412 uri = uri.substr(5);
413 }
414#endif
415
416 filename=uri;
417 std::ifstream ifs;
418 ifs.open(filename.c_str(),std::ios::in);
419 if(ifs.fail()) {
420 ifs.close();
421 return false;
422 }
423 else {
424 ifs.close();
425 return true;
426 }
427 }
428 return true;
429}
430
431
432std::string
434XmlUtils::acceptSecretKey(const std::string& field)
435{
436 std::cerr<<field<<": ";
437 char password [50];
438#ifndef _WIN32
439 tcflag_t oflags;
440 struct termios term;
441 tcgetattr(STDIN_FILENO, &term);
442 oflags = term.c_lflag;
443 term.c_lflag = oflags & ~(ECHO | ECHOK | ICANON);
444 term.c_cc[VTIME] = 1;
445 tcsetattr(STDIN_FILENO, TCSANOW, &term);
446
447 scanf("%s", password);
448
449 term.c_lflag = oflags;
450 term.c_cc[VTIME] = 0;
451 tcsetattr(STDIN_FILENO, TCSANOW, &term);
452#else
453 scanf("%s", password);
454#endif
455 return password;
456}
457
458#ifdef _WIN32
459void
460XmlUtils::winPost(const std::string uri,const std::string username,
461 const std::string password,const std::string data,
462 std::string action,char* &results)
463{
464 unsigned long nread;
465 W3Client w3;
466 const char* d = data.c_str() ;
467 if(w3.Connect(uri.c_str())){
468 w3.InitializePostArguments();
469 w3.setContentType("Content-Type: text/xml; charset=UTF-8\r\n");
470 w3.setAcceptTypes("Accept: text/xml\r\n");
471 w3.AddPostArgument(d,data.length());
472 std::string tmp="SOAPAction: ";
473 tmp+='"';
474 tmp+=action;
475 tmp+='"';
476 tmp+="\r\n";
477 w3.setSoapAction(tmp.c_str());
478
479 if(w3.RequestPost(w3.GetURI())){
480 unsigned long nread = 0,tot=0;
481 char buf[1024]="\0";
482
483 while((nread=w3.Response(reinterpret_cast<unsigned char *>(buf), 1023))){
484
485
486 if (results == 0){
487 results = (char*)malloc(sizeof(unsigned char) * (nread+1));
488 }
489 else{
490 results = (char*) realloc(results,sizeof(unsigned char) * (nread + tot+1));
491 }
492 memcpy (results+tot,buf,nread);
493 tot+=nread;
494 results[tot]='\0';
495 }
496 }
497 //std::cout<<results;
498 w3.Close();
499 }
500}
501#endif
502
503static bool g_bProxy = false;
504static std::string g_sProxyHost; //host:port format
505static std::string g_sProxyUser;
506static std::string g_sProxyPass;
507
508bool
511{
512 return g_bProxy;
513}
514
515void
517XmlUtils::setProxy (const bool bProxy)
518{
519 g_bProxy = bProxy;
520}
521
522std::string
525{
526 return g_sProxyHost;
527}
528
529void
531XmlUtils::setProxyHost (const std::string& sProxyHost)
532{
533 g_sProxyHost = sProxyHost;
534}
535
536std::string
539{
540 return g_sProxyUser;
541}
542
543void
545XmlUtils::setProxyUser (const std::string& sProxyUser)
546{
547 g_sProxyUser = sProxyUser;
548}
549
550std::string
553{
554 return g_sProxyPass;
555}
556
557void
559XmlUtils::setProxyPass (const std::string& sProxyPass)
560{
561 g_sProxyPass = sProxyPass;
562}
static pthread_mutex_t url_mutex
Definition XmlUtils.cpp:61
std::map< std::string, std::string > urlCache_
Definition XmlUtils.cpp:65
static std::string g_sProxyUser
Definition XmlUtils.cpp:505
static std::string g_sProxyHost
Definition XmlUtils.cpp:504
static std::string g_sProxyPass
Definition XmlUtils.cpp:506
void uri_init()
Definition XmlUtils.cpp:222
static bool g_bProxy
Definition XmlUtils.cpp:503
std::ostream & blk(std::ostream &str)
Definition XmlUtils.cpp:110
bool WSDLPULL_EXPORT getProxy()
Definition XmlUtils.cpp:510
std::string WSDLPULL_EXPORT getProxyHost()
Definition XmlUtils.cpp:524
int parseInt(std::string s, int radix=10)
Definition XmlUtils.cpp:70
std::string creUriFile(std::string)
Definition XmlUtils.cpp:144
void WSDLPULL_EXPORT setProxyPass(const std::string &sProxyPass)
Definition XmlUtils.cpp:559
void delUriFiles()
Definition XmlUtils.cpp:174
bool WSDLPULL_EXPORT fetchUri(std::string uri, std::string &path)
Definition XmlUtils.cpp:293
std::string WSDLPULL_EXPORT acceptSecretKey(const std::string &field)
Definition XmlUtils.cpp:434
void WSDLPULL_EXPORT setProxy(const bool bProxy)
Definition XmlUtils.cpp:517
std::string getSuffix()
Definition XmlUtils.cpp:209
std::string WSDLPULL_EXPORT getProxyUser()
Definition XmlUtils.cpp:538
void MutexUnlock()
Definition XmlUtils.cpp:276
void WSDLPULL_EXPORT setProxyUser(const std::string &sProxyUser)
Definition XmlUtils.cpp:545
std::string WSDLPULL_EXPORT getProxyPass()
Definition XmlUtils.cpp:552
void WSDLPULL_EXPORT setProxyHost(const std::string &sProxyHost)
Definition XmlUtils.cpp:531
void MutexLock()
Definition XmlUtils.cpp:263
std::string getFileName(std::string)
Definition XmlUtils.cpp:118
void MutexInit()
Definition XmlUtils.cpp:234
std::ostream & dbsp(std::ostream &str)
Definition XmlUtils.cpp:103
#define WSDLPULL_EXPORT