PageRenderTime 91ms CodeModel.GetById 38ms RepoModel.GetById 1ms app.codeStats 3ms

/usr/src/lib/libkmsagent/common/SOAP/stdsoap2.cpp

https://bitbucket.org/a3217055/illumos-gate
C++ | 15632 lines | 14532 code | 411 blank | 689 comment | 3825 complexity | 41313bb0cdd7fc221e1d79b312e6d6df MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, LGPL-2.0, 0BSD, AGPL-3.0, GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * CDDL HEADER START
  3. *
  4. * The contents of this file are subject to the terms of the
  5. * Common Development and Distribution License (the "License").
  6. * You may not use this file except in compliance with the License.
  7. *
  8. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  9. * or http://www.opensolaris.org/os/licensing.
  10. * See the License for the specific language governing permissions
  11. * and limitations under the License.
  12. *
  13. * When distributing Covered Code, include this CDDL HEADER in each
  14. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15. * If applicable, add the following below this CDDL HEADER, with the
  16. * fields enclosed by brackets "[]" replaced with your own identifying
  17. * information: Portions Copyright [yyyy] [name of copyright owner]
  18. *
  19. * CDDL HEADER END
  20. */
  21. /*
  22. * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23. */
  24. /*
  25. stdsoap2.c[pp] 2.7.17
  26. gSOAP runtime engine
  27. gSOAP XML Web services tools
  28. Copyright (C) 2000-2010, Robert van Engelen, Genivia Inc., All Rights Reserved.
  29. This part of the software is released under ONE of the following licenses:
  30. GPL, or the gSOAP public license, or Genivia's license for commercial use.
  31. --------------------------------------------------------------------------------
  32. Contributors:
  33. Oracle, Inc. - additions are noted in the code commented with
  34. "Oracle customization"
  35. - customization of the SSL accept timeout
  36. - work around for SSL_Sleep reporting closed connection
  37. - Function ssl_auth_init was static, but is now exported for external override
  38. - redirection of gSoap debug logs when debug builds enabled
  39. - added SSL_CTX_set_cipher_list call to restrict the cipher suite to RSA-2048/AES
  40. TLS_RSA_WITH_AES_256_CBC_SHA is defined in RFC 3268
  41. also see http://www.openssl.org/docs/apps/ciphers.html
  42. - Added SSL_OP_NO_SSLv3 to force use of TLS
  43. - bug fix: added call to close socket handle in various places noted in the code,
  44. since the caller overwrites soap->socket with the return value
  45. - compile warning cleanup
  46. Wind River Systems Inc., for the following additions under gSOAP public license:
  47. - vxWorks compatible
  48. --------------------------------------------------------------------------------
  49. gSOAP public license.
  50. The contents of this file are subject to the gSOAP Public License Version 1.3
  51. (the "License"); you may not use this file except in compliance with the
  52. License. You may obtain a copy of the License at
  53. http://www.cs.fsu.edu/~engelen/soaplicense.html
  54. Software distributed under the License is distributed on an "AS IS" basis,
  55. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  56. for the specific language governing rights and limitations under the License.
  57. The Initial Developer of the Original Code is Robert A. van Engelen.
  58. Copyright (C) 2000-2010, Robert van Engelen, Genivia Inc., All Rights Reserved.
  59. --------------------------------------------------------------------------------
  60. GPL license.
  61. This program is free software; you can redistribute it and/or modify it under
  62. the terms of the GNU General Public License as published by the Free Software
  63. Foundation; either version 2 of the License, or (at your option) any later
  64. version.
  65. This program is distributed in the hope that it will be useful, but WITHOUT ANY
  66. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  67. PARTICULAR PURPOSE. See the GNU General Public License for more details.
  68. You should have received a copy of the GNU General Public License along with
  69. this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  70. Place, Suite 330, Boston, MA 02111-1307 USA
  71. Author contact information:
  72. engelen@genivia.com / engelen@acm.org
  73. This program is released under the GPL with the additional exemption that
  74. compiling, linking, and/or using OpenSSL is allowed.
  75. --------------------------------------------------------------------------------
  76. A commercial use license is available from Genivia, Inc., contact@genivia.com
  77. --------------------------------------------------------------------------------
  78. Installation note:
  79. Win32 build needs winsock.dll (Visual C++ "wsock32.lib")
  80. To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link"
  81. tab (the project file needs to be selected in the file view) and add
  82. "wsock32.lib" to the "Object/library modules" entry
  83. On Mac OS X with gcc (GCC) 3.1 20020420 (prerelease) you MUST compile with
  84. -fstack_check when using -O2 because gcc 3.1 has a bug that smashes the stack
  85. when locally allocated data exceeds 64K.
  86. */
  87. #ifdef AS400
  88. # pragma convert(819) /* EBCDIC to ASCII */
  89. #endif
  90. #include "stdsoap2.h"
  91. /*
  92. Oracle customization for OpenSSL 0.9.8 removal of deprecated function usage: RSA_generate_key
  93. */
  94. #ifdef WITH_OPENSSL
  95. #ifdef OPENSSL_NO_DEPRECATED
  96. #include <openssl/rsa.h>
  97. #include <openssl/bn.h>
  98. #include <openssl/dh.h>
  99. #endif
  100. #endif
  101. #ifdef SOAP_MEM_DEBUG
  102. #ifndef WIN32
  103. #include <ucontext.h> /* Oracle customization (for printstack(3C)) */
  104. #endif
  105. #endif
  106. #ifdef __BORLANDC__
  107. # pragma warn -8060
  108. #else
  109. # ifdef WIN32
  110. # ifdef UNDER_CE
  111. # pragma comment(lib, "winsock.lib")
  112. # else
  113. # pragma comment(lib, "wsock32.lib")
  114. # endif
  115. # pragma warning(disable : 4996) /* disable deprecation warnings */
  116. # endif
  117. #endif
  118. #ifdef __cplusplus
  119. SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.17 2010-05-10 00:00:00 GMT")
  120. extern "C" {
  121. #else
  122. SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.17 2010-05-10 00:00:00 GMT")
  123. #endif
  124. /* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale with multibyte support enabled) */
  125. #ifndef SOAP_UNKNOWN_CHAR
  126. #define SOAP_UNKNOWN_CHAR (127)
  127. #endif
  128. /* EOF=-1 */
  129. #define SOAP_LT (soap_wchar)(-2) /* XML character '<' */
  130. #define SOAP_TT (soap_wchar)(-3) /* XML character '</' */
  131. #define SOAP_GT (soap_wchar)(-4) /* XML character '>' */
  132. #define SOAP_QT (soap_wchar)(-5) /* XML character '"' */
  133. #define SOAP_AP (soap_wchar)(-6) /* XML character ''' */
  134. #define soap_blank(c) ((c) >= 0 && (c) <= 32)
  135. #define soap_notblank(c) ((c) > 32)
  136. #if defined(WIN32) && !defined(UNDER_CE)
  137. #define soap_hash_ptr(p) ((PtrToUlong(p) >> 3) & (SOAP_PTRHASH - 1))
  138. #else
  139. #define soap_hash_ptr(p) ((size_t)(((unsigned long)(p) >> 3) & (SOAP_PTRHASH-1)))
  140. #endif
  141. #if !defined(WITH_LEAN) || defined(SOAP_DEBUG)
  142. static void soap_init_logs(struct soap*);
  143. #endif
  144. #ifdef SOAP_DEBUG
  145. static void soap_close_logfile(struct soap*, int);
  146. static void soap_set_logfile(struct soap*, int, const char*);
  147. #endif
  148. #ifdef SOAP_MEM_DEBUG
  149. static void soap_init_mht(struct soap*);
  150. static void soap_free_mht(struct soap*);
  151. static void soap_track_unlink(struct soap*, const void*);
  152. #endif
  153. #ifndef PALM_2
  154. static int soap_set_error(struct soap*, const char*, const char*, const char*, const char*, int);
  155. static int soap_copy_fault(struct soap*, const char*, const char*, const char*, const char*);
  156. static int soap_getattrval(struct soap*, char*, size_t, soap_wchar);
  157. #endif
  158. #ifndef PALM_1
  159. static void soap_free_ns(struct soap *soap);
  160. static soap_wchar soap_char(struct soap*);
  161. static soap_wchar soap_get_pi(struct soap*);
  162. static int soap_isxdigit(int);
  163. static void *fplugin(struct soap*, const char*);
  164. static char *soap_get_http_body(struct soap*);
  165. static size_t soap_count_attachments(struct soap *soap);
  166. static int soap_try_connect_command(struct soap*, int http_command, const char *endpoint, const char *action);
  167. #ifndef WITH_NOIDREF
  168. static void soap_update_ptrs(struct soap*, char*, char*, char*, char*);
  169. static int soap_has_copies(struct soap*, const char*, const char*);
  170. static void soap_init_iht(struct soap*);
  171. static void soap_free_iht(struct soap*);
  172. static void soap_init_pht(struct soap*);
  173. static void soap_free_pht(struct soap*);
  174. #endif
  175. #endif
  176. #ifndef WITH_LEAN
  177. static const char *soap_set_validation_fault(struct soap*, const char*, const char*);
  178. static int soap_isnumeric(struct soap*, const char*);
  179. static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized);
  180. static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n);
  181. #endif
  182. #ifndef WITH_LEANER
  183. #ifndef PALM_1
  184. static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t);
  185. static int soap_putdimefield(struct soap*, const char*, size_t);
  186. static char *soap_getdimefield(struct soap*, size_t);
  187. static void soap_select_mime_boundary(struct soap*);
  188. static int soap_valid_mime_boundary(struct soap*);
  189. static void soap_resolve_attachment(struct soap*, struct soap_multipart*);
  190. #endif
  191. #endif
  192. #ifdef WITH_GZIP
  193. static int soap_getgziphdr(struct soap*);
  194. #endif
  195. #ifdef WITH_OPENSSL
  196. int soap_ssl_init_done = 0;
  197. //
  198. // Oracle customization
  199. //
  200. // Function ssl_auth_init was static, but is now exported for external override
  201. /*
  202. static int ssl_auth_init(struct soap*);
  203. */
  204. int ssl_auth_init(struct soap*);
  205. static int ssl_verify_callback(int, X509_STORE_CTX*);
  206. static int ssl_verify_callback_allow_expired_certificate(int, X509_STORE_CTX*);
  207. static int ssl_password(char*, int, int, void *);
  208. #endif
  209. #if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
  210. #ifndef PALM_1
  211. static const char *soap_decode(char*, size_t, const char*, const char*);
  212. #endif
  213. #endif
  214. #ifndef WITH_NOHTTP
  215. #ifndef PALM_1
  216. static soap_wchar soap_getchunkchar(struct soap*);
  217. static const char *http_error(struct soap*, int);
  218. static int http_get(struct soap*);
  219. static int http_405(struct soap*);
  220. static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t);
  221. static int http_send_header(struct soap*, const char*);
  222. static int http_post_header(struct soap*, const char*, const char*);
  223. static int http_response(struct soap*, int, size_t);
  224. static int http_parse(struct soap*);
  225. static int http_parse_header(struct soap*, const char*, const char*);
  226. #endif
  227. #endif
  228. #ifndef WITH_NOIO
  229. #ifndef PALM_1
  230. static int fsend(struct soap*, const char*, size_t);
  231. static size_t frecv(struct soap*, char*, size_t);
  232. static int tcp_init(struct soap*);
  233. static const char *tcp_error(struct soap*);
  234. #ifndef WITH_IPV6
  235. static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr);
  236. #endif
  237. static SOAP_SOCKET tcp_connect(struct soap*, const char *endpoint, const char *host, int port);
  238. static SOAP_SOCKET tcp_accept(struct soap*, SOAP_SOCKET, struct sockaddr*, int*);
  239. static int tcp_select(struct soap*, SOAP_SOCKET, int, int);
  240. static int tcp_disconnect(struct soap*);
  241. static int tcp_closesocket(struct soap*, SOAP_SOCKET);
  242. static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int);
  243. static const char *soap_strerror(struct soap*);
  244. #endif
  245. #define SOAP_TCP_SELECT_RCV 0x1
  246. #define SOAP_TCP_SELECT_SND 0x2
  247. #define SOAP_TCP_SELECT_ERR 0x4
  248. #define SOAP_TCP_SELECT_ALL 0x7
  249. #if defined(WIN32)
  250. #define SOAP_SOCKBLOCK(fd) \
  251. { u_long blocking = 0; \
  252. ioctlsocket(fd, FIONBIO, &blocking); \
  253. }
  254. #define SOAP_SOCKNONBLOCK(fd) \
  255. { u_long nonblocking = 1; \
  256. ioctlsocket(fd, FIONBIO, &nonblocking); \
  257. }
  258. #elif defined(VXWORKS)
  259. #define SOAP_SOCKBLOCK(fd) \
  260. { u_long blocking = 0; \
  261. ioctl(fd, FIONBIO, (int)(&blocking)); \
  262. }
  263. #define SOAP_SOCKNONBLOCK(fd) \
  264. { u_long nonblocking = 1; \
  265. ioctl(fd, FIONBIO, (int)(&nonblocking)); \
  266. }
  267. #elif defined(PALM)
  268. #define SOAP_SOCKBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)&~O_NONBLOCK);
  269. #define SOAP_SOCKNONBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK);
  270. #elif defined(SYMBIAN)
  271. #define SOAP_SOCKBLOCK(fd) \
  272. { long blocking = 0; \
  273. ioctl(fd, 0/*FIONBIO*/, &blocking); \
  274. }
  275. #define SOAP_SOCKNONBLOCK(fd) \
  276. { long nonblocking = 1; \
  277. ioctl(fd, 0/*FIONBIO*/, &nonblocking); \
  278. }
  279. #else
  280. #define SOAP_SOCKBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK);
  281. #define SOAP_SOCKNONBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
  282. #endif
  283. #endif
  284. #if defined(PALM) && !defined(PALM_2)
  285. unsigned short errno;
  286. #endif
  287. #ifndef PALM_1
  288. static const char soap_env1[42] = "http://schemas.xmlsoap.org/soap/envelope/";
  289. static const char soap_enc1[42] = "http://schemas.xmlsoap.org/soap/encoding/";
  290. static const char soap_env2[40] = "http://www.w3.org/2003/05/soap-envelope";
  291. static const char soap_enc2[40] = "http://www.w3.org/2003/05/soap-encoding";
  292. static const char soap_rpc[35] = "http://www.w3.org/2003/05/soap-rpc";
  293. #endif
  294. #ifndef PALM_1
  295. const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF};
  296. static const char soap_base64o[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  297. static const char soap_base64i[81] = "\76XXX\77\64\65\66\67\70\71\72\73\74\75XXXXXXX\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31XXXXXX\32\33\34\35\36\37\40\41\42\43\44\45\46\47\50\51\52\53\54\55\56\57\60\61\62\63";
  298. #endif
  299. #ifndef WITH_LEAN
  300. static const char soap_indent[11] = "\n\t\t\t\t\t\t\t\t\t";
  301. /* Alternative indentation form for SOAP_XML_INDENT:
  302. static const char soap_indent[21] = "\n ";
  303. */
  304. #endif
  305. #ifndef SOAP_CANARY
  306. # define SOAP_CANARY (0xC0DE)
  307. #endif
  308. static const char soap_padding[4] = "\0\0\0";
  309. #define SOAP_STR_PADDING (soap_padding)
  310. #define SOAP_STR_EOS (soap_padding)
  311. #define SOAP_NON_NULL (soap_padding)
  312. #ifndef WITH_LEAN
  313. static const struct soap_code_map html_entity_codes[] = /* entities for XHTML parsing */
  314. { { 160, "nbsp" },
  315. { 161, "iexcl" },
  316. { 162, "cent" },
  317. { 163, "pound" },
  318. { 164, "curren" },
  319. { 165, "yen" },
  320. { 166, "brvbar" },
  321. { 167, "sect" },
  322. { 168, "uml" },
  323. { 169, "copy" },
  324. { 170, "ordf" },
  325. { 171, "laquo" },
  326. { 172, "not" },
  327. { 173, "shy" },
  328. { 174, "reg" },
  329. { 175, "macr" },
  330. { 176, "deg" },
  331. { 177, "plusmn" },
  332. { 178, "sup2" },
  333. { 179, "sup3" },
  334. { 180, "acute" },
  335. { 181, "micro" },
  336. { 182, "para" },
  337. { 183, "middot" },
  338. { 184, "cedil" },
  339. { 185, "sup1" },
  340. { 186, "ordm" },
  341. { 187, "raquo" },
  342. { 188, "frac14" },
  343. { 189, "frac12" },
  344. { 190, "frac34" },
  345. { 191, "iquest" },
  346. { 192, "Agrave" },
  347. { 193, "Aacute" },
  348. { 194, "Acirc" },
  349. { 195, "Atilde" },
  350. { 196, "Auml" },
  351. { 197, "Aring" },
  352. { 198, "AElig" },
  353. { 199, "Ccedil" },
  354. { 200, "Egrave" },
  355. { 201, "Eacute" },
  356. { 202, "Ecirc" },
  357. { 203, "Euml" },
  358. { 204, "Igrave" },
  359. { 205, "Iacute" },
  360. { 206, "Icirc" },
  361. { 207, "Iuml" },
  362. { 208, "ETH" },
  363. { 209, "Ntilde" },
  364. { 210, "Ograve" },
  365. { 211, "Oacute" },
  366. { 212, "Ocirc" },
  367. { 213, "Otilde" },
  368. { 214, "Ouml" },
  369. { 215, "times" },
  370. { 216, "Oslash" },
  371. { 217, "Ugrave" },
  372. { 218, "Uacute" },
  373. { 219, "Ucirc" },
  374. { 220, "Uuml" },
  375. { 221, "Yacute" },
  376. { 222, "THORN" },
  377. { 223, "szlig" },
  378. { 224, "agrave" },
  379. { 225, "aacute" },
  380. { 226, "acirc" },
  381. { 227, "atilde" },
  382. { 228, "auml" },
  383. { 229, "aring" },
  384. { 230, "aelig" },
  385. { 231, "ccedil" },
  386. { 232, "egrave" },
  387. { 233, "eacute" },
  388. { 234, "ecirc" },
  389. { 235, "euml" },
  390. { 236, "igrave" },
  391. { 237, "iacute" },
  392. { 238, "icirc" },
  393. { 239, "iuml" },
  394. { 240, "eth" },
  395. { 241, "ntilde" },
  396. { 242, "ograve" },
  397. { 243, "oacute" },
  398. { 244, "ocirc" },
  399. { 245, "otilde" },
  400. { 246, "ouml" },
  401. { 247, "divide" },
  402. { 248, "oslash" },
  403. { 249, "ugrave" },
  404. { 250, "uacute" },
  405. { 251, "ucirc" },
  406. { 252, "uuml" },
  407. { 253, "yacute" },
  408. { 254, "thorn" },
  409. { 255, "yuml" },
  410. { 0, NULL }
  411. };
  412. #endif
  413. #ifndef WITH_NOIO
  414. #ifndef WITH_LEAN
  415. static const struct soap_code_map h_error_codes[] =
  416. {
  417. #ifdef HOST_NOT_FOUND
  418. { HOST_NOT_FOUND, "Host not found" },
  419. #endif
  420. #ifdef TRY_AGAIN
  421. { TRY_AGAIN, "Try Again" },
  422. #endif
  423. #ifdef NO_RECOVERY
  424. { NO_RECOVERY, "No Recovery" },
  425. #endif
  426. #ifdef NO_DATA
  427. { NO_DATA, "No Data" },
  428. #endif
  429. #ifdef NO_ADDRESS
  430. { NO_ADDRESS, "No Address" },
  431. #endif
  432. { 0, NULL }
  433. };
  434. #endif
  435. #endif
  436. #ifndef WITH_NOHTTP
  437. #ifndef WITH_LEAN
  438. static const struct soap_code_map h_http_error_codes[] =
  439. { { 200, "OK" },
  440. { 201, "Created" },
  441. { 202, "Accepted" },
  442. { 203, "Non-Authoritative Information" },
  443. { 204, "No Content" },
  444. { 205, "Reset Content" },
  445. { 206, "Partial Content" },
  446. { 300, "Multiple Choices" },
  447. { 301, "Moved Permanently" },
  448. { 302, "Found" },
  449. { 303, "See Other" },
  450. { 304, "Not Modified" },
  451. { 305, "Use Proxy" },
  452. { 307, "Temporary Redirect" },
  453. { 400, "Bad Request" },
  454. { 401, "Unauthorized" },
  455. { 402, "Payment Required" },
  456. { 403, "Forbidden" },
  457. { 404, "Not Found" },
  458. { 405, "Method Not Allowed" },
  459. { 406, "Not Acceptable" },
  460. { 407, "Proxy Authentication Required" },
  461. { 408, "Request Time-out" },
  462. { 409, "Conflict" },
  463. { 410, "Gone" },
  464. { 411, "Length Required" },
  465. { 412, "Precondition Failed" },
  466. { 413, "Request Entity Too Large" },
  467. { 414, "Request-URI Too Large" },
  468. { 415, "Unsupported Media Type" },
  469. { 416, "Requested range not satisfiable" },
  470. { 417, "Expectation Failed" },
  471. { 500, "Internal Server Error" },
  472. { 501, "Not Implemented" },
  473. { 502, "Bad Gateway" },
  474. { 503, "Service Unavailable" },
  475. { 504, "Gateway Time-out" },
  476. { 505, "HTTP Version not supported" },
  477. { 0, NULL }
  478. };
  479. #endif
  480. #endif
  481. #ifdef WITH_OPENSSL
  482. static const struct soap_code_map h_ssl_error_codes[] =
  483. {
  484. #define _SSL_ERROR(e) { e, #e }
  485. _SSL_ERROR(SSL_ERROR_SSL),
  486. _SSL_ERROR(SSL_ERROR_ZERO_RETURN),
  487. _SSL_ERROR(SSL_ERROR_WANT_READ),
  488. _SSL_ERROR(SSL_ERROR_WANT_WRITE),
  489. _SSL_ERROR(SSL_ERROR_WANT_CONNECT),
  490. _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP),
  491. _SSL_ERROR(SSL_ERROR_SYSCALL),
  492. { 0, NULL }
  493. };
  494. #endif
  495. #ifndef WITH_LEANER
  496. static const struct soap_code_map mime_codes[] =
  497. { { SOAP_MIME_7BIT, "7bit" },
  498. { SOAP_MIME_8BIT, "8bit" },
  499. { SOAP_MIME_BINARY, "binary" },
  500. { SOAP_MIME_QUOTED_PRINTABLE, "quoted-printable" },
  501. { SOAP_MIME_BASE64, "base64" },
  502. { SOAP_MIME_IETF_TOKEN, "ietf-token" },
  503. { SOAP_MIME_X_TOKEN, "x-token" },
  504. { 0, NULL }
  505. };
  506. #endif
  507. #ifdef WIN32
  508. static int tcp_done = 0;
  509. #endif
  510. #if defined(HP_UX) && defined(HAVE_GETHOSTBYNAME_R)
  511. extern int h_errno;
  512. #endif
  513. /******************************************************************************/
  514. #ifndef WITH_NOIO
  515. #ifndef PALM_1
  516. static int
  517. fsend(struct soap *soap, const char *s, size_t n)
  518. { register int nwritten, err;
  519. #if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT)
  520. if (soap->os)
  521. { soap->os->write(s, (std::streamsize)n);
  522. if (soap->os->good())
  523. return SOAP_OK;
  524. soap->errnum = 0;
  525. return SOAP_EOF;
  526. }
  527. #endif
  528. while (n)
  529. { if (soap_valid_socket(soap->socket))
  530. {
  531. if (soap->send_timeout)
  532. { for (;;)
  533. { register int r;
  534. #ifdef WITH_OPENSSL
  535. if (soap->ssl)
  536. r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ALL, soap->send_timeout);
  537. else
  538. #endif
  539. r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout);
  540. if (r > 0)
  541. break;
  542. if (!r)
  543. return SOAP_EOF;
  544. err = soap->errnum;
  545. if (!err)
  546. return soap->error;
  547. if (err != SOAP_EINTR && err != SOAP_EAGAIN && err != SOAP_EWOULDBLOCK)
  548. return SOAP_EOF;
  549. }
  550. }
  551. #ifdef WITH_OPENSSL
  552. if (soap->ssl)
  553. nwritten = SSL_write(soap->ssl, s, (int)n);
  554. else if (soap->bio)
  555. nwritten = BIO_write(soap->bio, s, (int)n);
  556. else
  557. #endif
  558. #ifndef WITH_LEAN
  559. if ((soap->omode & SOAP_IO_UDP))
  560. { if (soap->peerlen)
  561. nwritten = sendto(soap->socket, (char*)s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen);
  562. else
  563. nwritten = send(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags);
  564. /* retry and back-off algorithm */
  565. /* TODO: this is not very clear from specs so verify and limit conditions under which we should loop (e.g. ENOBUFS) */
  566. if (nwritten < 0)
  567. { int udp_repeat;
  568. int udp_delay;
  569. if ((soap->connect_flags & SO_BROADCAST))
  570. udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */
  571. else
  572. udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */
  573. udp_delay = (soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */
  574. do
  575. { tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ERR, -1000 * udp_delay);
  576. if (soap->peerlen)
  577. nwritten = sendto(soap->socket, (char*)s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen);
  578. else
  579. nwritten = send(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags);
  580. udp_delay <<= 1;
  581. if (udp_delay > 500) /* UDP_UPPER_DELAY */
  582. udp_delay = 500;
  583. }
  584. while (nwritten < 0 && --udp_repeat > 0);
  585. }
  586. }
  587. else
  588. #endif
  589. #if !defined(PALM) && !defined(AS400)
  590. nwritten = send(soap->socket, s, (int)n, soap->socket_flags);
  591. #else
  592. nwritten = send(soap->socket, (void*)s, n, soap->socket_flags);
  593. #endif
  594. if (nwritten <= 0)
  595. {
  596. register int r = 0;
  597. err = soap_socket_errno(soap->socket);
  598. #ifdef WITH_OPENSSL
  599. if (soap->ssl && (r = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
  600. { soap->errnum = err;
  601. return SOAP_EOF;
  602. }
  603. #endif
  604. if (err == SOAP_EWOULDBLOCK || err == SOAP_EAGAIN)
  605. {
  606. #ifdef WITH_OPENSSL
  607. if (soap->ssl && r == SSL_ERROR_WANT_READ)
  608. r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
  609. else
  610. r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
  611. #else
  612. r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->send_timeout ? soap->send_timeout : -10000);
  613. #endif
  614. if (!r && soap->send_timeout)
  615. return SOAP_EOF;
  616. if (r < 0 && soap->errnum != SOAP_EINTR)
  617. return SOAP_EOF;
  618. }
  619. else if (err && err != SOAP_EINTR)
  620. { soap->errnum = err;
  621. return SOAP_EOF;
  622. }
  623. nwritten = 0; /* and call write() again */
  624. }
  625. }
  626. else
  627. {
  628. #ifdef WITH_FASTCGI
  629. nwritten = fwrite((void*)s, 1, n, stdout);
  630. fflush(stdout);
  631. #else
  632. #ifdef UNDER_CE
  633. nwritten = fwrite(s, 1, n, soap->sendfd);
  634. #else
  635. #ifdef VXWORKS
  636. #ifdef WMW_RPM_IO
  637. if (soap->rpmreqid)
  638. nwritten = (httpBlockPut(soap->rpmreqid, (char*)s, n) == 0) ? n : -1;
  639. else
  640. #endif
  641. nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));
  642. #else
  643. #ifdef WIN32
  644. nwritten = _write(soap->sendfd, s, (unsigned int)n);
  645. #else
  646. nwritten = write(soap->sendfd, s, (unsigned int)n);
  647. #endif
  648. #endif
  649. #endif
  650. #endif
  651. if (nwritten <= 0)
  652. {
  653. #ifndef WITH_FASTCGI
  654. err = soap_errno;
  655. #else
  656. err = EOF;
  657. #endif
  658. if (err && err != SOAP_EINTR && err != SOAP_EWOULDBLOCK && err != SOAP_EAGAIN)
  659. { soap->errnum = err;
  660. return SOAP_EOF;
  661. }
  662. nwritten = 0; /* and call write() again */
  663. }
  664. }
  665. n -= nwritten;
  666. s += nwritten;
  667. }
  668. return SOAP_OK;
  669. }
  670. #endif
  671. #endif
  672. /******************************************************************************/
  673. #ifndef PALM_1
  674. SOAP_FMAC1
  675. int
  676. SOAP_FMAC2
  677. soap_send_raw(struct soap *soap, const char *s, size_t n)
  678. { if (!n)
  679. return SOAP_OK;
  680. if (soap->mode & SOAP_IO_LENGTH)
  681. { soap->count += n;
  682. #ifndef WITH_LEANER
  683. if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
  684. return soap->error = soap->fpreparesend(soap, s, n);
  685. #endif
  686. return SOAP_OK;
  687. }
  688. if (soap->mode & SOAP_IO)
  689. { register size_t i = SOAP_BUFLEN - soap->bufidx;
  690. while (n >= i)
  691. { memcpy(soap->buf + soap->bufidx, s, i);
  692. soap->bufidx = SOAP_BUFLEN;
  693. if (soap_flush(soap))
  694. return soap->error;
  695. s += i;
  696. n -= i;
  697. i = SOAP_BUFLEN;
  698. }
  699. memcpy(soap->buf + soap->bufidx, s, n);
  700. soap->bufidx += n;
  701. return SOAP_OK;
  702. }
  703. return soap_flush_raw(soap, s, n);
  704. }
  705. #endif
  706. /******************************************************************************/
  707. #ifndef PALM_1
  708. SOAP_FMAC1
  709. int
  710. SOAP_FMAC2
  711. soap_flush(struct soap *soap)
  712. { register size_t n = soap->bufidx;
  713. if (n)
  714. {
  715. #ifndef WITH_LEANER
  716. if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
  717. { register int r;
  718. if (soap->fpreparesend && (r = soap->fpreparesend(soap, soap->buf, n)))
  719. return soap->error = r;
  720. }
  721. #endif
  722. soap->bufidx = 0;
  723. #ifdef WITH_ZLIB
  724. if (soap->mode & SOAP_ENC_ZLIB)
  725. { soap->d_stream->next_in = (Byte*)soap->buf;
  726. soap->d_stream->avail_in = (unsigned int)n;
  727. #ifdef WITH_GZIP
  728. soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n);
  729. #endif
  730. do
  731. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream->avail_in));
  732. if (deflate(soap->d_stream, Z_NO_FLUSH) != Z_OK)
  733. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
  734. return soap->error = SOAP_ZLIB_ERROR;
  735. }
  736. if (!soap->d_stream->avail_out)
  737. { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN))
  738. return soap->error;
  739. soap->d_stream->next_out = (Byte*)soap->z_buf;
  740. soap->d_stream->avail_out = SOAP_BUFLEN;
  741. }
  742. } while (soap->d_stream->avail_in);
  743. }
  744. else
  745. #endif
  746. return soap_flush_raw(soap, soap->buf, n);
  747. }
  748. return SOAP_OK;
  749. }
  750. #endif
  751. /******************************************************************************/
  752. #ifndef PALM_1
  753. SOAP_FMAC1
  754. int
  755. SOAP_FMAC2
  756. soap_flush_raw(struct soap *soap, const char *s, size_t n)
  757. { if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
  758. { register char *t;
  759. if (!(t = (char*)soap_push_block(soap, NULL, n)))
  760. return soap->error = SOAP_EOM;
  761. memcpy(t, s, n);
  762. return SOAP_OK;
  763. }
  764. #ifndef WITH_LEANER
  765. if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
  766. { char t[16];
  767. sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n);
  768. DBGMSG(SENT, t, strlen(t));
  769. if ((soap->error = soap->fsend(soap, t, strlen(t))))
  770. return soap->error;
  771. soap->chunksize += n;
  772. }
  773. DBGMSG(SENT, s, n);
  774. #endif
  775. return soap->error = soap->fsend(soap, s, n);
  776. }
  777. #endif
  778. /******************************************************************************/
  779. #ifndef PALM_1
  780. SOAP_FMAC1
  781. int
  782. SOAP_FMAC2
  783. soap_send(struct soap *soap, const char *s)
  784. { if (s)
  785. return soap_send_raw(soap, s, strlen(s));
  786. return SOAP_OK;
  787. }
  788. #endif
  789. /******************************************************************************/
  790. #ifndef WITH_LEANER
  791. #ifndef PALM_1
  792. SOAP_FMAC1
  793. int
  794. SOAP_FMAC2
  795. soap_send2(struct soap *soap, const char *s1, const char *s2)
  796. { if (soap_send(soap, s1))
  797. return soap->error;
  798. return soap_send(soap, s2);
  799. }
  800. #endif
  801. #endif
  802. /******************************************************************************/
  803. #ifndef WITH_LEANER
  804. #ifndef PALM_1
  805. SOAP_FMAC1
  806. int
  807. SOAP_FMAC2
  808. soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3)
  809. { if (soap_send(soap, s1)
  810. || soap_send(soap, s2))
  811. return soap->error;
  812. return soap_send(soap, s3);
  813. }
  814. #endif
  815. #endif
  816. /******************************************************************************/
  817. #ifndef WITH_NOIO
  818. #ifndef PALM_1
  819. static size_t
  820. frecv(struct soap *soap, char *s, size_t n)
  821. { register int r;
  822. register int retries = 100; /* max 100 retries with non-blocking sockets */
  823. soap->errnum = 0;
  824. #if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT)
  825. if (soap->is)
  826. { if (soap->is->good())
  827. return soap->is->read(s, (std::streamsize)n).gcount();
  828. return 0;
  829. }
  830. #endif
  831. if (soap_valid_socket(soap->socket))
  832. { for (;;)
  833. {
  834. #ifdef WITH_OPENSSL
  835. register int err = 0;
  836. #endif
  837. #ifdef WITH_OPENSSL
  838. if (soap->recv_timeout && !soap->ssl) /* SSL: sockets are nonblocking */
  839. #else
  840. if (soap->recv_timeout)
  841. #endif
  842. { for (;;)
  843. { r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout);
  844. if (r > 0)
  845. break;
  846. if (!r)
  847. return 0;
  848. r = soap->errnum;
  849. if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK)
  850. return 0;
  851. }
  852. }
  853. #ifdef WITH_OPENSSL
  854. if (soap->ssl)
  855. { r = SSL_read(soap->ssl, s, (int)n);
  856. if (r > 0)
  857. return (size_t)r;
  858. err = SSL_get_error(soap->ssl, r);
  859. if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
  860. return 0;
  861. }
  862. else if (soap->bio)
  863. { r = BIO_read(soap->bio, s, (int)n);
  864. if (r > 0)
  865. return (size_t)r;
  866. return 0;
  867. }
  868. else
  869. #endif
  870. {
  871. #ifndef WITH_LEAN
  872. if ((soap->omode & SOAP_IO_UDP))
  873. { SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer);
  874. memset((void*)&soap->peer, 0, sizeof(soap->peer));
  875. r = recvfrom(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k); /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
  876. soap->peerlen = (size_t)k;
  877. #ifndef WITH_IPV6
  878. soap->ip = ntohl(soap->peer.sin_addr.s_addr);
  879. #endif
  880. }
  881. else
  882. #endif
  883. r = recv(soap->socket, s, (int)n, soap->socket_flags);
  884. #ifdef PALM
  885. /* CycleSyncDisplay(curStatusMsg); */
  886. #endif
  887. if (r >= 0)
  888. return (size_t)r;
  889. r = soap_socket_errno(soap->socket);
  890. if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK)
  891. { soap->errnum = r;
  892. return 0;
  893. }
  894. }
  895. #ifdef WITH_OPENSSL
  896. if (soap->ssl && err == SSL_ERROR_WANT_WRITE)
  897. r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_SND | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
  898. else
  899. r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
  900. #else
  901. r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, soap->recv_timeout ? soap->recv_timeout : 5);
  902. #endif
  903. if (!r && soap->recv_timeout)
  904. return 0;
  905. if (r < 0)
  906. { r = soap->errnum;
  907. if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK)
  908. return 0;
  909. }
  910. if (retries-- <= 0)
  911. return 0;
  912. #ifdef PALM
  913. r = soap_socket_errno(soap->socket);
  914. if (r != SOAP_EINTR && retries-- <= 0)
  915. { soap->errnum = r;
  916. return 0;
  917. }
  918. #endif
  919. }
  920. }
  921. #ifdef WITH_FASTCGI
  922. return fread(s, 1, n, stdin);
  923. #else
  924. #ifdef UNDER_CE
  925. return fread(s, 1, n, soap->recvfd);
  926. #else
  927. #ifdef WMW_RPM_IO
  928. if (soap->rpmreqid)
  929. r = httpBlockRead(soap->rpmreqid, s, n);
  930. else
  931. #endif
  932. #ifdef WIN32
  933. r = _read(soap->recvfd, s, (unsigned int)n);
  934. #else
  935. r = read(soap->recvfd, s, (unsigned int)n);
  936. #endif
  937. if (r >= 0)
  938. return (size_t)r;
  939. soap->errnum = soap_errno;
  940. return 0;
  941. #endif
  942. #endif
  943. }
  944. #endif
  945. #endif
  946. /******************************************************************************/
  947. #ifndef WITH_NOHTTP
  948. #ifndef PALM_1
  949. static soap_wchar
  950. soap_getchunkchar(struct soap *soap)
  951. { if (soap->bufidx < soap->buflen)
  952. return soap->buf[soap->bufidx++];
  953. soap->bufidx = 0;
  954. soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
  955. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket));
  956. DBGMSG(RECV, soap->buf, soap->buflen);
  957. if (soap->buflen)
  958. return soap->buf[soap->bufidx++];
  959. return EOF;
  960. }
  961. #endif
  962. #endif
  963. /******************************************************************************/
  964. #ifndef PALM_1
  965. static int
  966. soap_isxdigit(int c)
  967. { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
  968. }
  969. #endif
  970. /******************************************************************************/
  971. #ifndef PALM_1
  972. SOAP_FMAC1
  973. int
  974. SOAP_FMAC2
  975. soap_recv_raw(struct soap *soap)
  976. { register size_t ret;
  977. #if !defined(WITH_LEANER) || defined(WITH_ZLIB)
  978. register int r;
  979. #endif
  980. #ifdef WITH_ZLIB
  981. if (soap->mode & SOAP_ENC_ZLIB)
  982. { if (soap->d_stream->next_out == Z_NULL)
  983. return EOF;
  984. if (soap->d_stream->avail_in || !soap->d_stream->avail_out)
  985. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n"));
  986. soap->d_stream->next_out = (Byte*)soap->buf;
  987. soap->d_stream->avail_out = SOAP_BUFLEN;
  988. r = inflate(soap->d_stream, Z_NO_FLUSH);
  989. if (r == Z_NEED_DICT && soap->z_dict)
  990. r = inflateSetDictionary(soap->d_stream, (const Bytef*)soap->z_dict, soap->z_dict_len);
  991. if (r == Z_OK || r == Z_STREAM_END)
  992. { soap->bufidx = 0;
  993. ret = soap->buflen = SOAP_BUFLEN - soap->d_stream->avail_out;
  994. if (soap->zlib_in == SOAP_ZLIB_GZIP)
  995. soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)ret);
  996. if (r == Z_STREAM_END)
  997. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream->total_in, soap->d_stream->total_out));
  998. soap->z_ratio_in = (float)soap->d_stream->total_in / (float)soap->d_stream->total_out;
  999. soap->d_stream->next_out = Z_NULL;
  1000. }
  1001. if (ret)
  1002. { soap->count += ret;
  1003. DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n"));
  1004. DBGMSG(RECV, soap->buf, ret);
  1005. DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n----\n"));
  1006. #ifndef WITH_LEANER
  1007. if (soap->fpreparerecv && (r = soap->fpreparerecv(soap, soap->buf, ret)))
  1008. return soap->error = r;
  1009. #endif
  1010. return SOAP_OK;
  1011. }
  1012. }
  1013. else if (r != Z_BUF_ERROR)
  1014. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
  1015. soap->d_stream->next_out = Z_NULL;
  1016. soap->error = SOAP_ZLIB_ERROR;
  1017. return EOF;
  1018. }
  1019. }
  1020. zlib_again:
  1021. if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK && !soap->chunksize)
  1022. { memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN);
  1023. soap->buflen = soap->z_buflen;
  1024. }
  1025. DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- compressed ----\n"));
  1026. }
  1027. #endif
  1028. #ifndef WITH_NOHTTP
  1029. if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */
  1030. { for (;;)
  1031. { register soap_wchar c;
  1032. char *t, tmp[8];
  1033. if (soap->chunksize)
  1034. { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize);
  1035. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret));
  1036. DBGMSG(RECV, soap->buf, ret);
  1037. soap->bufidx = 0;
  1038. soap->chunksize -= ret;
  1039. break;
  1040. }
  1041. t = tmp;
  1042. if (!soap->chunkbuflen)
  1043. { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
  1044. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes (chunked) from socket %d\n", (unsigned int)ret, soap->socket));
  1045. DBGMSG(RECV, soap->buf, ret);
  1046. soap->bufidx = 0;
  1047. if (!ret)
  1048. return soap->ahead = EOF;
  1049. }
  1050. else
  1051. soap->bufidx = soap->buflen;
  1052. soap->buflen = soap->chunkbuflen;
  1053. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen));
  1054. while (!soap_isxdigit((int)(c = soap_getchunkchar(soap))))
  1055. { if ((int)c == EOF)
  1056. return soap->ahead = EOF;
  1057. }
  1058. do
  1059. *t++ = (char)c;
  1060. while (soap_isxdigit((int)(c = soap_getchunkchar(soap))) && t - tmp < 7);
  1061. while ((int)c != EOF && c != '\n')
  1062. c = soap_getchunkchar(soap);
  1063. if ((int)c == EOF)
  1064. return soap->ahead = EOF;
  1065. *t = '\0';
  1066. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunk size = %s (hex)\n", tmp));
  1067. soap->chunksize = soap_strtoul(tmp, &t, 16);
  1068. if (!soap->chunksize)
  1069. { soap->chunkbuflen = 0;
  1070. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n"));
  1071. while ((int)c != EOF && c != '\n')
  1072. c = soap_getchunkchar(soap);
  1073. ret = 0;
  1074. soap->ahead = EOF;
  1075. break;
  1076. }
  1077. soap->buflen = soap->bufidx + soap->chunksize;
  1078. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to idx=%u len=%u (%s)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen, tmp));
  1079. if (soap->buflen > soap->chunkbuflen)
  1080. { soap->buflen = soap->chunkbuflen;
  1081. soap->chunksize -= soap->buflen - soap->bufidx;
  1082. soap->chunkbuflen = 0;
  1083. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%u bytes left)\n", (unsigned int)(soap->buflen - soap->bufidx)));
  1084. }
  1085. else if (soap->chunkbuflen)
  1086. soap->chunksize = 0;
  1087. ret = soap->buflen - soap->bufidx;
  1088. if (ret)
  1089. break;
  1090. }
  1091. }
  1092. else
  1093. #endif
  1094. { soap->bufidx = 0;
  1095. soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
  1096. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket));
  1097. DBGMSG(RECV, soap->buf, ret);
  1098. }
  1099. #ifdef WITH_ZLIB
  1100. if (soap->mode & SOAP_ENC_ZLIB)
  1101. { memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
  1102. soap->d_stream->next_in = (Byte*)(soap->z_buf + soap->bufidx);
  1103. soap->d_stream->avail_in = (unsigned int)ret;
  1104. soap->d_stream->next_out = (Byte*)soap->buf;
  1105. soap->d_stream->avail_out = SOAP_BUFLEN;
  1106. r = inflate(soap->d_stream, Z_NO_FLUSH);
  1107. if (r == Z_NEED_DICT && soap->z_dict)
  1108. r = inflateSetDictionary(soap->d_stream, (const Bytef*)soap->z_dict, soap->z_dict_len);
  1109. if (r == Z_OK || r == Z_STREAM_END)
  1110. { soap->bufidx = 0;
  1111. soap->z_buflen = soap->buflen;
  1112. soap->buflen = SOAP_BUFLEN - soap->d_stream->avail_out;
  1113. if (soap->zlib_in == SOAP_ZLIB_GZIP)
  1114. soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen);
  1115. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)soap->buflen));
  1116. if (ret && !soap->buflen && r != Z_STREAM_END)
  1117. goto zlib_again;
  1118. ret = soap->buflen;
  1119. if (r == Z_STREAM_END)
  1120. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated total %lu->%lu bytes\n", soap->d_stream->total_in, soap->d_stream->total_out));
  1121. soap->z_ratio_in = (float)soap->d_stream->total_in / (float)soap->d_stream->total_out;
  1122. soap->d_stream->next_out = Z_NULL;
  1123. }
  1124. DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n"));
  1125. DBGMSG(RECV, soap->buf, ret);
  1126. #ifndef WITH_LEANER
  1127. if (soap->fpreparerecv && (r = soap->fpreparerecv(soap, soap->buf, ret)))
  1128. return soap->error = r;
  1129. #endif
  1130. }
  1131. else
  1132. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
  1133. soap->d_stream->next_out = Z_NULL;
  1134. soap->error = SOAP_ZLIB_ERROR;
  1135. return EOF;
  1136. }
  1137. }
  1138. #endif
  1139. #ifndef WITH_LEANER
  1140. if (soap->fpreparerecv
  1141. #ifdef WITH_ZLIB
  1142. && soap->zlib_in == SOAP_ZLIB_NONE
  1143. #endif
  1144. && (r = soap->fpreparerecv(soap, soap->buf + soap->bufidx, ret)))
  1145. return soap->error = r;
  1146. #endif
  1147. soap->count += ret;
  1148. return !ret;
  1149. }
  1150. #endif
  1151. /******************************************************************************/
  1152. #ifndef PALM_1
  1153. SOAP_FMAC1
  1154. int
  1155. SOAP_FMAC2
  1156. soap_recv(struct soap *soap)
  1157. {
  1158. #ifndef WITH_LEANER
  1159. if (soap->mode & SOAP_ENC_DIME)
  1160. { if (soap->dime.buflen)
  1161. { char *s;
  1162. int i;
  1163. unsigned char tmp[12];
  1164. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME hdr for chunked DIME is in buffer\n"));
  1165. soap->count += soap->dime.buflen - soap->buflen;
  1166. soap->buflen = soap->dime.buflen;
  1167. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Skip padding (%ld bytes)\n", -(long)soap->dime.size&3));
  1168. for (i = -(long)soap->dime.size&3; i > 0; i--)
  1169. { soap->bufidx++;
  1170. if (soap->bufidx >= soap->buflen)
  1171. if (soap_recv_raw(soap))
  1172. return EOF;
  1173. }
  1174. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME hdr for next chunk\n"));
  1175. s = (char*)tmp;
  1176. for (i = 12; i > 0; i--)
  1177. { *s++ = soap->buf[soap->bufidx++];
  1178. if (soap->bufidx >= soap->buflen)
  1179. if (soap_recv_raw(soap))
  1180. return EOF;
  1181. }
  1182. soap->dime.flags = tmp[0] & 0x7;
  1183. soap->dime.size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]);
  1184. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME chunk (%u bytes)\n", (unsigned int)soap->dime.size));
  1185. if (soap->dime.flags & SOAP_DIME_CF)
  1186. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "More chunking\n"));
  1187. soap->dime.chunksize = soap->dime.size;
  1188. if (soap->buflen - soap->bufidx >= soap->dime.size)
  1189. { soap->dime.buflen = soap->buflen;
  1190. soap->buflen = soap->bufidx + soap->dime.chunksize;
  1191. }
  1192. else
  1193. soap->dime.chunksize -= soap->buflen - soap->bufidx;
  1194. }
  1195. else
  1196. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Last chunk\n"));
  1197. soap->dime.buflen = 0;
  1198. soap->dime.chunksize = 0;
  1199. }
  1200. soap->count = soap->buflen - soap->bufidx;
  1201. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%u bytes remaining\n", (unsigned int)soap->count));
  1202. return SOAP_OK;
  1203. }
  1204. if (soap->dime.chunksize)
  1205. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (unsigned int)soap->dime.chunksize));
  1206. if (soap_recv_raw(soap))
  1207. return EOF;
  1208. if (soap->buflen - soap->bufidx >= soap->dime.chunksize)
  1209. { soap->dime.buflen = soap->buflen;
  1210. soap->count -= soap->buflen - soap->bufidx - soap->dime.chunksize;
  1211. soap->buflen = soap->bufidx + soap->dime.chunksize;
  1212. }
  1213. else
  1214. soap->dime.chunksize -= soap->buflen - soap->bufidx;
  1215. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%lu bytes remaining, count=%u\n", (unsigned long)(soap->buflen-soap->bufidx), (unsigned int)soap->count));
  1216. return SOAP_OK;
  1217. }
  1218. }
  1219. #endif
  1220. return soap_recv_raw(soap);
  1221. }
  1222. #endif
  1223. /******************************************************************************/
  1224. #ifndef PALM_1
  1225. SOAP_FMAC1
  1226. soap_wchar
  1227. SOAP_FMAC2
  1228. soap_getchar(struct soap *soap)
  1229. { register soap_wchar c;
  1230. c = soap->ahead;
  1231. if (c)
  1232. { if (c != EOF)
  1233. soap->ahead = 0;
  1234. return c;
  1235. }
  1236. return soap_get1(soap);
  1237. }
  1238. #endif
  1239. /******************************************************************************/
  1240. #ifndef PALM_1
  1241. SOAP_FMAC1
  1242. const struct soap_code_map*
  1243. SOAP_FMAC2
  1244. soap_code(const struct soap_code_map *code_map, const char *str)
  1245. { if (code_map && str)
  1246. { while (code_map->string)
  1247. { if (!strcmp(str, code_map->string)) /* case sensitive */
  1248. return code_map;
  1249. code_map++;
  1250. }
  1251. }
  1252. return NULL;
  1253. }
  1254. #endif
  1255. /******************************************************************************/
  1256. #ifndef PALM_1
  1257. SOAP_FMAC1
  1258. long
  1259. SOAP_FMAC2
  1260. soap_code_int(const struct soap_code_map *code_map, const char *str, long other)
  1261. { if (code_map)
  1262. { while (code_map->string)
  1263. { if (!soap_tag_cmp(str, code_map->string)) /* case insensitive */
  1264. return code_map->code;
  1265. code_map++;
  1266. }
  1267. }
  1268. return other;
  1269. }
  1270. #endif
  1271. /******************************************************************************/
  1272. #ifndef PALM_1
  1273. SOAP_FMAC1
  1274. const char*
  1275. SOAP_FMAC2
  1276. soap_code_str(const struct soap_code_map *code_map, long code)
  1277. { if (!code_map)
  1278. return NULL;
  1279. while (code_map->code != code && code_map->string)
  1280. code_map++;
  1281. return code_map->string;
  1282. }
  1283. #endif
  1284. /******************************************************************************/
  1285. #ifndef PALM_1
  1286. SOAP_FMAC1
  1287. long
  1288. SOAP_FMAC2
  1289. soap_code_bits(const struct soap_code_map *code_map, const char *str)
  1290. { register long bits = 0;
  1291. if (code_map)
  1292. { while (str && *str)
  1293. { const struct soap_code_map *p;
  1294. for (p = code_map; p->string; p++)
  1295. { register size_t n = strlen(p->string);
  1296. if (!strncmp(p->string, str, n) && soap_blank(str[n]))
  1297. { bits |= p->code;
  1298. str += n;
  1299. while (*str > 0 && *str <= 32)
  1300. str++;
  1301. break;
  1302. }
  1303. }
  1304. if (!p->string)
  1305. return 0;
  1306. }
  1307. }
  1308. return bits;
  1309. }
  1310. #endif
  1311. /******************************************************************************/
  1312. #ifndef PALM_1
  1313. SOAP_FMAC1
  1314. const char*
  1315. SOAP_FMAC2
  1316. soap_code_list(struct soap *soap, const struct soap_code_map *code_map, long code)
  1317. { register char *t = soap->tmpbuf;
  1318. if (code_map)
  1319. { while (code_map->string)
  1320. { if (code_map->code & code)
  1321. { register const char *s = code_map->string;
  1322. if (t != soap->tmpbuf)
  1323. *t++ = ' ';
  1324. while (*s && t < soap->tmpbuf + sizeof(soap->tmpbuf) - 1)
  1325. *t++ = *s++;
  1326. if (t == soap->tmpbuf + sizeof(soap->tmpbuf) - 1)
  1327. break;
  1328. }
  1329. code_map++;
  1330. }
  1331. }
  1332. *t = '\0';
  1333. return soap->tmpbuf;
  1334. }
  1335. #endif
  1336. /******************************************************************************/
  1337. #ifndef PALM_1
  1338. static soap_wchar
  1339. soap_char(struct soap *soap)
  1340. { char tmp[8];
  1341. register int i;
  1342. register soap_wchar c;
  1343. register char *s = tmp;
  1344. for (i = 0; i < 7; i++)
  1345. { c = soap_get1(soap);
  1346. if (c == ';' || (int)c == EOF)
  1347. break;
  1348. *s++ = (char)c;
  1349. }
  1350. *s = '\0';
  1351. if (*tmp == '#')
  1352. { if (tmp[1] == 'x' || tmp[1] == 'X')
  1353. return (soap_wchar)soap_strtol(tmp + 2, NULL, 16);
  1354. return (soap_wchar)soap_strtol(tmp + 1, NULL, 10);
  1355. }
  1356. if (!strcmp(tmp, "lt"))
  1357. return '<';
  1358. if (!strcmp(tmp, "gt"))
  1359. return '>';
  1360. if (!strcmp(tmp, "amp"))
  1361. return '&';
  1362. if (!strcmp(tmp, "quot"))
  1363. return '"';
  1364. if (!strcmp(tmp, "apos"))
  1365. return '\'';
  1366. #ifndef WITH_LEAN
  1367. return (soap_wchar)soap_code_int(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR);
  1368. #else
  1369. return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */
  1370. #endif
  1371. }
  1372. #endif
  1373. /******************************************************************************/
  1374. #ifdef WITH_LEAN
  1375. #ifndef PALM_1
  1376. soap_wchar
  1377. soap_get0(struct soap *soap)
  1378. { if (soap->bufidx >= soap->buflen && soap_recv(soap))
  1379. return EOF;
  1380. return (unsigned char)soap->buf[soap->bufidx];
  1381. }
  1382. #endif
  1383. #endif
  1384. /******************************************************************************/
  1385. #ifdef WITH_LEAN
  1386. #ifndef PALM_1
  1387. soap_wchar
  1388. soap_get1(struct soap *soap)
  1389. { if (soap->bufidx >= soap->buflen && soap_recv(soap))
  1390. return EOF;
  1391. return (unsigned char)soap->buf[soap->bufidx++];
  1392. }
  1393. #endif
  1394. #endif
  1395. /******************************************************************************/
  1396. #ifndef PALM_1
  1397. SOAP_FMAC1
  1398. soap_wchar
  1399. SOAP_FMAC2
  1400. soap_get(struct soap *soap)
  1401. { register soap_wchar c;
  1402. c = soap->ahead;
  1403. if (c)
  1404. { if ((int)c != EOF)
  1405. soap->ahead = 0;
  1406. }
  1407. else
  1408. c = soap_get1(soap);
  1409. while ((int)c != EOF)
  1410. { if (soap->cdata)
  1411. { if (c == ']')
  1412. { c = soap_get1(soap);
  1413. if (c == ']')
  1414. { c = soap_get0(soap);
  1415. if (c == '>')
  1416. { soap->cdata = 0;
  1417. soap_get1(soap);
  1418. c = soap_get1(soap);
  1419. }
  1420. else
  1421. { soap_unget(soap, ']');
  1422. return ']';
  1423. }
  1424. }
  1425. else
  1426. { soap_revget1(soap);
  1427. return ']';
  1428. }
  1429. }
  1430. else
  1431. return c;
  1432. }
  1433. switch (c)
  1434. { case '<':
  1435. do c = soap_get1(soap);
  1436. while (soap_blank(c));
  1437. if (c == '!' || c == '?' || c == '%')
  1438. { register int k = 1;
  1439. if (c == '!')
  1440. { c = soap_get1(soap);
  1441. if (c == '[')
  1442. { do c = soap_get1(soap);
  1443. while ((int)c != EOF && c != '[');
  1444. if ((int)c == EOF)
  1445. break;
  1446. soap->cdata = 1;
  1447. c = soap_get1(soap);
  1448. continue;
  1449. }
  1450. if (c == '-' && (c = soap_get1(soap)) == '-')
  1451. { do
  1452. { c = soap_get1(soap);
  1453. if (c == '-' && (c = soap_get1(soap)) == '-')
  1454. break;
  1455. } while ((int)c != EOF);
  1456. }
  1457. }
  1458. else if (c == '?')
  1459. c = soap_get_pi(soap);
  1460. while ((int)c != EOF)
  1461. { if (c == '<')
  1462. k++;
  1463. else if (c == '>')
  1464. { if (--k <= 0)
  1465. break;
  1466. }
  1467. c = soap_get1(soap);
  1468. }
  1469. if ((int)c == EOF)
  1470. break;
  1471. c = soap_get1(soap);
  1472. continue;
  1473. }
  1474. if (c == '/')
  1475. return SOAP_TT;
  1476. soap_revget1(soap);
  1477. return SOAP_LT;
  1478. case '>':
  1479. return SOAP_GT;
  1480. case '"':
  1481. return SOAP_QT;
  1482. case '\'':
  1483. return SOAP_AP;
  1484. case '&':
  1485. return soap_char(soap) | 0x80000000;
  1486. }
  1487. break;
  1488. }
  1489. return c;
  1490. }
  1491. #endif
  1492. /******************************************************************************/
  1493. #ifndef PALM_1
  1494. static soap_wchar
  1495. soap_get_pi(struct soap *soap)
  1496. { char buf[64];
  1497. register char *s = buf;
  1498. register int i = sizeof(buf);
  1499. register soap_wchar c = soap_getchar(soap);
  1500. /* This is a quick way to parse XML PI and we could use a callback instead to
  1501. * enable applications to intercept processing instructions */
  1502. while ((int)c != EOF && c != '?')
  1503. { if (--i > 0)
  1504. { if (soap_blank(c))
  1505. c = ' ';
  1506. *s++ = (char)c;
  1507. }
  1508. c = soap_getchar(soap);
  1509. }
  1510. *s = '\0';
  1511. DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI <?%s?>\n", buf));
  1512. if (!strncmp(buf, "xml ", 4))
  1513. { s = strstr(buf, " encoding=");
  1514. if (s && s[10])
  1515. { if (!soap_tag_cmp(s + 11, "iso-8859-1*")
  1516. || !soap_tag_cmp(s + 11, "latin1*"))
  1517. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to latin1 encoding\n"));
  1518. soap->mode |= SOAP_ENC_LATIN;
  1519. }
  1520. else if (!soap_tag_cmp(s + 11, "utf-8*"))
  1521. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to utf-8 encoding\n"));
  1522. soap->mode &= ~SOAP_ENC_LATIN;
  1523. }
  1524. }
  1525. }
  1526. if ((int)c != EOF)
  1527. c = soap_getchar(soap);
  1528. return c;
  1529. }
  1530. #endif
  1531. /******************************************************************************/
  1532. #ifndef WITH_LEANER
  1533. #ifndef PALM_1
  1534. SOAP_FMAC1
  1535. int
  1536. SOAP_FMAC2
  1537. soap_move(struct soap *soap, long n)
  1538. { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving %ld bytes forward\n", (long)n));
  1539. for (; n > 0; n--)
  1540. if ((int)soap_getchar(soap) == EOF)
  1541. return SOAP_EOF;
  1542. return SOAP_OK;
  1543. }
  1544. #endif
  1545. #endif
  1546. /******************************************************************************/
  1547. #ifndef WITH_LEANER
  1548. #ifndef PALM_1
  1549. SOAP_FMAC1
  1550. size_t
  1551. SOAP_FMAC2
  1552. soap_tell(struct soap *soap)
  1553. { return soap->count - soap->buflen + soap->bufidx - (soap->ahead != 0);
  1554. }
  1555. #endif
  1556. #endif

Large files files are truncated, but you can click here to view the full file