Produced by Araxis Merge on 10/2/2017 1:40:10 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
| # | Location | File | Last Modified |
|---|---|---|---|
| 1 | chef-repo.zip\chef-repo\project_cookbooks\mocks\files\default\node-mocks\nodeMockServices-1.3.0.52.zip\node_modules\libxmljs\vendor\libxml | nanohttp.c | Fri Apr 11 14:19:04 2014 UTC |
| 2 | chef-repo.zip\chef-repo\project_cookbooks\mocks\files\default\node-mocks\nodeMockServices-1.3.0.52.zip\node_modules\libxmljs\vendor\libxml | nanohttp.c | Mon Oct 2 17:40:22 2017 UTC |
| Description | Between Files 1 and 2 |
|
|---|---|---|
| Text Blocks | Lines | |
| Unchanged | 3 | 3754 |
| Changed | 2 | 4 |
| Inserted | 0 | 0 |
| Removed | 0 | 0 |
| Whitespace | |
|---|---|
| Character case | Differences in character case are significant |
| Line endings | Differences in line endings (CR and LF characters) are ignored |
| CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
| 1 | /* | |
| 2 | * nanohtt p.c: minim alist HTTP GET imple mentation to fetch e xternal su bsets. | |
| 3 | * focus es on size , streamab ility, ree ntrancy an d portabil ity | |
| 4 | * | |
| 5 | * This is clearly n ot a gener al purpose HTTP impl ementation | |
| 6 | * If you look for o ne, check: | |
| 7 | * http://ww w.w3.org/L ibrary/ | |
| 8 | * | |
| 9 | * See Cop yright for the statu s of this software. | |
| 10 | * | |
| 11 | * daniel@ veillard.c om | |
| 12 | */ | |
| 13 | ||
| 14 | #define NE ED_SOCKETS | |
| 15 | #define IN _LIBXML | |
| 16 | #include " libxml.h" | |
| 17 | ||
| 18 | #ifdef LIB XML_HTTP_E NABLED | |
| 19 | #include < string.h> | |
| 20 | ||
| 21 | #ifdef HAV E_STDLIB_H | |
| 22 | #include < stdlib.h> | |
| 23 | #endif | |
| 24 | #ifdef HAV E_UNISTD_H | |
| 25 | #include < unistd.h> | |
| 26 | #endif | |
| 27 | #ifdef HAV E_SYS_TYPE S_H | |
| 28 | #include < sys/types. h> | |
| 29 | #endif | |
| 30 | #ifdef HAV E_SYS_SOCK ET_H | |
| 31 | #include < sys/socket .h> | |
| 32 | #endif | |
| 33 | #ifdef HAV E_NETINET_ IN_H | |
| 34 | #include < netinet/in .h> | |
| 35 | #endif | |
| 36 | #ifdef HAV E_ARPA_INE T_H | |
| 37 | #include < arpa/inet. h> | |
| 38 | #endif | |
| 39 | #ifdef HAV E_NETDB_H | |
| 40 | #include < netdb.h> | |
| 41 | #endif | |
| 42 | #ifdef HAV E_RESOLV_H | |
| 43 | #ifdef HAV E_ARPA_NAM ESER_H | |
| 44 | #include < arpa/names er.h> | |
| 45 | #endif | |
| 46 | #include < resolv.h> | |
| 47 | #endif | |
| 48 | #ifdef HAV E_FCNTL_H | |
| 49 | #include < fcntl.h> | |
| 50 | #endif | |
| 51 | #ifdef HAV E_ERRNO_H | |
| 52 | #include < errno.h> | |
| 53 | #endif | |
| 54 | #ifdef HAV E_SYS_TIME _H | |
| 55 | #include < sys/time.h > | |
| 56 | #endif | |
| 57 | #ifndef HA VE_POLL_H | |
| 58 | #ifdef HAV E_SYS_SELE CT_H | |
| 59 | #include < sys/select .h> | |
| 60 | #endif | |
| 61 | #else | |
| 62 | #include < poll.h> | |
| 63 | #endif | |
| 64 | #ifdef HAV E_STRINGS_ H | |
| 65 | #include < strings.h> | |
| 66 | #endif | |
| 67 | #ifdef HAV E_ZLIB_H | |
| 68 | #include < zlib.h> | |
| 69 | #endif | |
| 70 | ||
| 71 | ||
| 72 | #ifdef VMS | |
| 73 | #include < stropts> | |
| 74 | #define XM L_SOCKLEN_ T unsigned int | |
| 75 | #endif | |
| 76 | ||
| 77 | #if define d(__MINGW3 2__) || de fined(_WIN 32_WCE) | |
| 78 | #ifndef _W INSOCKAPI_ | |
| 79 | #define _W INSOCKAPI_ | |
| 80 | #endif | |
| 81 | #include < wsockcompa t.h> | |
| 82 | #include < winsock2.h > | |
| 83 | #undef XML _SOCKLEN_T | |
| 84 | #define XM L_SOCKLEN_ T unsigned int | |
| 85 | #endif | |
| 86 | ||
| 87 | #include < libxml/glo bals.h> | |
| 88 | #include < libxml/xml error.h> | |
| 89 | #include < libxml/xml memory.h> | |
| 90 | #include < libxml/par ser.h> /* for xmlStr (n)casecmp () */ | |
| 91 | #include < libxml/nan ohttp.h> | |
| 92 | #include < libxml/glo bals.h> | |
| 93 | #include < libxml/uri .h> | |
| 94 | ||
| 95 | /** | |
| 96 | * A coupl e portabil ity macros | |
| 97 | */ | |
| 98 | #ifndef _W INSOCKAPI_ | |
| 99 | #if !defin ed(__BEOS_ _) || defi ned(__HAIK U__) | |
| 100 | #define cl osesocket( s) close(s ) | |
| 101 | #endif | |
| 102 | #define SO CKET int | |
| 103 | #define IN VALID_SOCK ET (-1) | |
| 104 | #endif | |
| 105 | ||
| 106 | #ifdef __B EOS__ | |
| 107 | #ifndef PF _INET | |
| 108 | #define PF _INET AF_I NET | |
| 109 | #endif | |
| 110 | #endif | |
| 111 | ||
| 112 | #ifndef XM L_SOCKLEN_ T | |
| 113 | #define XM L_SOCKLEN_ T unsigned int | |
| 114 | #endif | |
| 115 | ||
| 116 | #ifdef STA NDALONE | |
| 117 | #define DE BUG_HTTP | |
| 118 | #define xm lStrncasec mp(a, b, n ) strncase cmp((char *)a, (char *)b, n) | |
| 119 | #define xm lStrcasecm pi(a, b) s trcasecmp( (char *)a, (char *)b ) | |
| 120 | #endif | |
| 121 | ||
| 122 | #define XM L_NANO_HTT P_MAX_REDI R 10 | |
| 123 | ||
| 124 | #define XM L_NANO_HTT P_CHUNK 4096 | |
| 125 | ||
| 126 | #define XM L_NANO_HTT P_CLOSED 0 | |
| 127 | #define XM L_NANO_HTT P_WRITE 1 | |
| 128 | #define XM L_NANO_HTT P_READ 2 | |
| 129 | #define XM L_NANO_HTT P_NONE 4 | |
| 130 | ||
| 131 | typedef st ruct xmlNa noHTTPCtxt { | |
| 132 | char * protocol; /* the protocol name */ | |
| 133 | char * hostname; /* the host name */ | |
| 134 | int po rt; /* the port */ | |
| 135 | char * path; /* the path with in the URL */ | |
| 136 | char * query; /* the query str ing */ | |
| 137 | SOCKET fd; /* the file desc riptor for the socke t */ | |
| 138 | int st ate; /* WRI TE / READ / CLOSED * / | |
| 139 | char * out; /* buf fer sent ( zero termi nated) */ | |
| 140 | char * outptr; /* ind ex within the buffer sent */ | |
| 141 | char * in; /* the receiving buffer */ | |
| 142 | char * content; /* the start of the conten t */ | |
| 143 | char * inptr; /* the next byte to read f rom networ k */ | |
| 144 | char * inrptr; /* the next byte to give b ack to the client */ | |
| 145 | int in len; /* len of the in put buffer */ | |
| 146 | int la st; /* ret urn code f or last op eration */ | |
| 147 | int re turnValue; /* the protocol return val ue */ | |
| 148 | int ve rsion; /* the protocol version */ | |
| 149 | int Co ntentLengt h; /* spe cified con tent lengt h from HTT P header * / | |
| 150 | char * contentTyp e; /* the MIME type for the i nput */ | |
| 151 | char * location; /* the new URL i n case of redirect * / | |
| 152 | char * authHeader ; /* con tents of { WWW,Proxy} -Authentic ate header */ | |
| 153 | char * encoding; /* enc oding extr acted from the conte ntType */ | |
| 154 | char * mimeType; /* Mim e-Type ext racted fro m the cont entType */ | |
| 155 | #ifdef HAV E_ZLIB_H | |
| 156 | z_stre am *strm; /* Zli b stream o bject */ | |
| 157 | int us esGzip; /* "Co ntent-Enco ding: gzip " was dete cted */ | |
| 158 | #endif | |
| 159 | } xmlNanoH TTPCtxt, * xmlNanoHTT PCtxtPtr; | |
| 160 | ||
| 161 | static int initializ ed = 0; | |
| 162 | static cha r *proxy = NULL; /* the proxy name if any */ | |
| 163 | static int proxyPort ; /* the proxy por t if any * / | |
| 164 | static uns igned int timeout = 60;/* the select() t imeout in seconds */ | |
| 165 | ||
| 166 | static int xmlNanoHT TPFetchCon tent( void * ctx, ch ar ** ptr, int * len ); | |
| 167 | ||
| 168 | /** | |
| 169 | * xmlHTTP ErrMemory: | |
| 170 | * @extra: extra in formations | |
| 171 | * | |
| 172 | * Handle an out of memory con dition | |
| 173 | */ | |
| 174 | static voi d | |
| 175 | xmlHTTPErr Memory(con st char *e xtra) | |
| 176 | { | |
| 177 | __xmlS impleError (XML_FROM_ HTTP, XML_ ERR_NO_MEM ORY, NULL, NULL, ext ra); | |
| 178 | } | |
| 179 | ||
| 180 | /** | |
| 181 | * A porta bility fun ction | |
| 182 | */ | |
| 183 | static int socket_er rno(void) { | |
| 184 | #ifdef _WI NSOCKAPI_ | |
| 185 | return (WSAGetLas tError()); | |
| 186 | #else | |
| 187 | return (errno); | |
| 188 | #endif | |
| 189 | } | |
| 190 | ||
| 191 | #ifdef SUP PORT_IP6 | |
| 192 | static | |
| 193 | int have_i pv6(void) { | |
| 194 | SOCKET s; | |
| 195 | ||
| 196 | s = so cket (AF_I NET6, SOCK _STREAM, 0 ); | |
| 197 | if (s != INVALID _SOCKET) { | |
| 198 | cl ose (s); | |
| 199 | re turn (1); | |
| 200 | } | |
| 201 | return (0); | |
| 202 | } | |
| 203 | #endif | |
| 204 | ||
| 205 | /** | |
| 206 | * xmlNano HTTPInit: | |
| 207 | * | |
| 208 | * Initial ize the HT TP protoco l layer. | |
| 209 | * Current ly it just checks fo r proxy in formations | |
| 210 | */ | |
| 211 | ||
| 212 | void | |
| 213 | xmlNanoHTT PInit(void ) { | |
| 214 | const char *env; | |
| 215 | #ifdef _WI NSOCKAPI_ | |
| 216 | WSADAT A wsaData; | |
| 217 | #endif | |
| 218 | ||
| 219 | if (in itialized) | |
| 220 | re turn; | |
| 221 | ||
| 222 | #ifdef _WI NSOCKAPI_ | |
| 223 | if (WS AStartup(M AKEWORD(1, 1), &wsaD ata) != 0) | |
| 224 | re turn; | |
| 225 | #endif | |
| 226 | ||
| 227 | if (pr oxy == NUL L) { | |
| 228 | pr oxyPort = PORT ; | |
| 229 | en v = getenv ("no_proxy "); | |
| 230 | if (env && ( (env[0] == '*') && ( env[1] == 0))) | |
| 231 | goto don e; | |
| 232 | en v = getenv ("http_pro xy"); | |
| 233 | if (env != N ULL) { | |
| 234 | xmlNanoH TTPScanPro xy(env); | |
| 235 | goto don e; | |
| 236 | } | |
| 237 | en v = getenv ("HTTP_PRO XY"); | |
| 238 | if (env != N ULL) { | |
| 239 | xmlNanoH TTPScanPro xy(env); | |
| 240 | goto don e; | |
| 241 | } | |
| 242 | } | |
| 243 | done: | |
| 244 | initia lized = 1; | |
| 245 | } | |
| 246 | ||
| 247 | /** | |
| 248 | * xmlNano HTTPCleanu p: | |
| 249 | * | |
| 250 | * Cleanup the HTTP protocol l ayer. | |
| 251 | */ | |
| 252 | ||
| 253 | void | |
| 254 | xmlNanoHTT PCleanup(v oid) { | |
| 255 | if (pr oxy != NUL L) { | |
| 256 | xm lFree(prox y); | |
| 257 | pr oxy = NULL ; | |
| 258 | } | |
| 259 | #ifdef _WI NSOCKAPI_ | |
| 260 | if (in itialized) | |
| 261 | WS ACleanup() ; | |
| 262 | #endif | |
| 263 | initia lized = 0; | |
| 264 | return ; | |
| 265 | } | |
| 266 | ||
| 267 | /** | |
| 268 | * xmlNano HTTPScanUR L: | |
| 269 | * @ctxt: an HTTP c ontext | |
| 270 | * @URL: The URL us ed to init ialize the context | |
| 271 | * | |
| 272 | * (Re)Ini tialize an HTTP cont ext by par sing the U RL and fin ding | |
| 273 | * the pro tocol host port and path it in dicates. | |
| 274 | */ | |
| 275 | ||
| 276 | static voi d | |
| 277 | xmlNanoHTT PScanURL(x mlNanoHTTP CtxtPtr ct xt, const char *URL) { | |
| 278 | xmlURI Ptr uri; | |
| 279 | /* | |
| 280 | * Cle ar any exi sting data from the context | |
| 281 | */ | |
| 282 | if (ct xt->protoc ol != NULL ) { | |
| 283 | xm lFree(ctxt ->protocol ); | |
| 284 | ct xt->protoc ol = NULL; | |
| 285 | } | |
| 286 | if (ct xt->hostna me != NULL ) { | |
| 287 | xm lFree(ctxt ->hostname ); | |
| 288 | ct xt->hostna me = NULL; | |
| 289 | } | |
| 290 | if (ct xt->path ! = NULL) { | |
| 291 | xm lFree(ctxt ->path); | |
| 292 | ct xt->path = NULL; | |
| 293 | } | |
| 294 | if (ct xt->query != NULL) { | |
| 295 | xm lFree(ctxt ->query); | |
| 296 | ct xt->query = NULL; | |
| 297 | } | |
| 298 | if (UR L == NULL) return; | |
| 299 | ||
| 300 | uri = xmlParseUR IRaw(URL, 1); | |
| 301 | if (ur i == NULL) | |
| 302 | re turn; | |
| 303 | ||
| 304 | if ((u ri->scheme == NULL) || (uri->s erver == N ULL)) { | |
| 305 | xm lFreeURI(u ri); | |
| 306 | re turn; | |
| 307 | } | |
| 308 | ||
| 309 | ctxt-> protocol = xmlMemStr dup(uri->s cheme); | |
| 310 | ctxt-> hostname = xmlMemStr dup(uri->s erver); | |
| 311 | if (ur i->path != NULL) | |
| 312 | ct xt->path = xmlMemStr dup(uri->p ath); | |
| 313 | else | |
| 314 | ct xt->path = xmlMemStr dup("/"); | |
| 315 | if (ur i->query ! = NULL) | |
| 316 | ct xt->query = xmlMemSt rdup(uri-> query); | |
| 317 | if (ur i->port != 0) | |
| 318 | ct xt->port = uri->port ; | |
| 319 | ||
| 320 | xmlFre eURI(uri); | |
| 321 | } | |
| 322 | ||
| 323 | /** | |
| 324 | * xmlNano HTTPScanPr oxy: | |
| 325 | * @URL: The proxy URL used t o initiali ze the pro xy context | |
| 326 | * | |
| 327 | * (Re)Ini tialize th e HTTP Pro xy context by parsin g the URL and findin g | |
| 328 | * the pro tocol host port it i ndicates. | |
| 329 | * Should be like ht tp://mypro xy/ or htt p://myprox y:3128/ | |
| 330 | * A NULL URL cleans up proxy informatio ns. | |
| 331 | */ | |
| 332 | ||
| 333 | void | |
| 334 | xmlNanoHTT PScanProxy (const cha r *URL) { | |
| 335 | xmlURI Ptr uri; | |
| 336 | ||
| 337 | if (pr oxy != NUL L) { | |
| 338 | xm lFree(prox y); | |
| 339 | pr oxy = NULL ; | |
| 340 | } | |
| 341 | proxyP ort = 0; | |
| 342 | ||
| 343 | #ifdef DEB UG_HTTP | |
| 344 | if (UR L == NULL) | |
| 345 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 346 | "Rem oving HTTP proxy inf o\n"); | |
| 347 | else | |
| 348 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 349 | "Usi ng HTTP pr oxy %s\n", URL); | |
| 350 | #endif | |
| 351 | if (UR L == NULL) return; | |
| 352 | ||
| 353 | uri = xmlParseUR IRaw(URL, 1); | |
| 354 | if ((u ri == NULL ) || (uri- >scheme == NULL) || | |
| 355 | (s trcmp(uri- >scheme, " http")) || (uri->ser ver == NUL L)) { | |
| 356 | __ xmlIOErr(X ML_FROM_HT TP, XML_HT TP_URL_SYN TAX, "Synt ax Error\n "); | |
| 357 | if (uri != N ULL) | |
| 358 | xmlFreeU RI(uri); | |
| 359 | re turn; | |
| 360 | } | |
| 361 | ||
| 362 | proxy = xmlMemSt rdup(uri-> server); | |
| 363 | if (ur i->port != 0) | |
| 364 | pr oxyPort = uri->port; | |
| 365 | ||
| 366 | xmlFre eURI(uri); | |
| 367 | } | |
| 368 | ||
| 369 | /** | |
| 370 | * xmlNano HTTPNewCtx t: | |
| 371 | * @URL: The URL us ed to init ialize the context | |
| 372 | * | |
| 373 | * Allocat e and init ialize a n ew HTTP co ntext. | |
| 374 | * | |
| 375 | * Returns an HTTP c ontext or NULL in ca se of erro r. | |
| 376 | */ | |
| 377 | ||
| 378 | static xml NanoHTTPCt xtPtr | |
| 379 | xmlNanoHTT PNewCtxt(c onst char *URL) { | |
| 380 | xmlNan oHTTPCtxtP tr ret; | |
| 381 | ||
| 382 | ret = (xmlNanoHT TPCtxtPtr) xmlMalloc (sizeof(xm lNanoHTTPC txt)); | |
| 383 | if (re t == NULL) { | |
| 384 | xm lHTTPErrMe mory("allo cating con text"); | |
| 385 | re turn(NULL) ; | |
| 386 | } | |
| 387 | ||
| 388 | memset (ret, 0, s izeof(xmlN anoHTTPCtx t)); | |
| 389 | ret->port = PORT ; | |
| 390 | ret->r eturnValue = 0; | |
| 391 | ret->f d = INVALI D_SOCKET; | |
| 392 | ret->C ontentLeng th = -1; | |
| 393 | ||
| 394 | xmlNan oHTTPScanU RL(ret, UR L); | |
| 395 | ||
| 396 | return (ret); | |
| 397 | } | |
| 398 | ||
| 399 | /** | |
| 400 | * xmlNano HTTPFreeCt xt: | |
| 401 | * @ctxt: an HTTP c ontext | |
| 402 | * | |
| 403 | * Frees t he context after clo sing the c onnection. | |
| 404 | */ | |
| 405 | ||
| 406 | static voi d | |
| 407 | xmlNanoHTT PFreeCtxt( xmlNanoHTT PCtxtPtr c txt) { | |
| 408 | if (ct xt == NULL ) return; | |
| 409 | if (ct xt->hostna me != NULL ) xmlFree( ctxt->host name); | |
| 410 | if (ct xt->protoc ol != NULL ) xmlFree( ctxt->prot ocol); | |
| 411 | if (ct xt->path ! = NULL) xm lFree(ctxt ->path); | |
| 412 | if (ct xt->query != NULL) x mlFree(ctx t->query); | |
| 413 | if (ct xt->out != NULL) xml Free(ctxt- >out); | |
| 414 | if (ct xt->in != NULL) xmlF ree(ctxt-> in); | |
| 415 | if (ct xt->conten tType != N ULL) xmlFr ee(ctxt->c ontentType ); | |
| 416 | if (ct xt->encodi ng != NULL ) xmlFree( ctxt->enco ding); | |
| 417 | if (ct xt->mimeTy pe != NULL ) xmlFree( ctxt->mime Type); | |
| 418 | if (ct xt->locati on != NULL ) xmlFree( ctxt->loca tion); | |
| 419 | if (ct xt->authHe ader != NU LL) xmlFre e(ctxt->au thHeader); | |
| 420 | #ifdef HAV E_ZLIB_H | |
| 421 | if (ct xt->strm ! = NULL) { | |
| 422 | in flateEnd(c txt->strm) ; | |
| 423 | xm lFree(ctxt ->strm); | |
| 424 | } | |
| 425 | #endif | |
| 426 | ||
| 427 | ctxt-> state = XM L_NANO_HTT P_NONE; | |
| 428 | if (ct xt->fd != INVALID_SO CKET) clos esocket(ct xt->fd); | |
| 429 | ctxt-> fd = INVAL ID_SOCKET; | |
| 430 | xmlFre e(ctxt); | |
| 431 | } | |
| 432 | ||
| 433 | /** | |
| 434 | * xmlNano HTTPSend: | |
| 435 | * @ctxt: an HTTP c ontext | |
| 436 | * | |
| 437 | * Send th e input ne eded to in itiate the processin g on the s erver side | |
| 438 | * Returns number of bytes sen t or -1 on error. | |
| 439 | */ | |
| 440 | ||
| 441 | static int | |
| 442 | xmlNanoHTT PSend(xmlN anoHTTPCtx tPtr ctxt, const cha r *xmt_ptr , int outl en) | |
| 443 | { | |
| 444 | int to tal_sent = 0; | |
| 445 | #ifdef HAV E_POLL_H | |
| 446 | struct pollfd p; | |
| 447 | #else | |
| 448 | struct timeval t v; | |
| 449 | fd_set wfd; | |
| 450 | #endif | |
| 451 | ||
| 452 | if ((c txt->state & XML_NAN O_HTTP_WRI TE) && (xm t_ptr != N ULL)) { | |
| 453 | wh ile (total _sent < ou tlen) { | |
| 454 | int nsen t = send(c txt->fd, x mt_ptr + t otal_sent, | |
| 455 | o utlen - to tal_sent, 0); | |
| 456 | ||
| 457 | if (nsen t > 0) | |
| 458 | tota l_sent += nsent; | |
| 459 | else if ((nsent == -1) && | |
| 460 | #if define d(EAGAIN) && EAGAIN != EWOULDB LOCK | |
| 461 | (socket_e rrno() != EAGAIN) && | |
| 462 | #endif | |
| 463 | (socket_e rrno() != EWOULDBLOC K)) { | |
| 464 | __xm lIOErr(XML _FROM_HTTP , 0, "send failed\n" ); | |
| 465 | if ( total_sent == 0) | |
| 466 | total_sent = -1; | |
| 467 | brea k; | |
| 468 | } else { | |
| 469 | /* | |
| 470 | * N o data sen t | |
| 471 | * S ince non-b locking so ckets are used, wait for | |
| 472 | * s ocket to b e writable or defaul t timeout prior | |
| 473 | * t o retrying . | |
| 474 | */ | |
| 475 | #ifndef HA VE_POLL_H | |
| 476 | #ifndef _W INSOCKAPI_ | |
| 477 | if ( ctxt->fd > FD_SETSIZ E) | |
| 478 | return -1; | |
| 479 | #endif | |
| 480 | ||
| 481 | tv.t v_sec = ti meout; | |
| 482 | tv.t v_usec = 0 ; | |
| 483 | FD_Z ERO(&wfd); | |
| 484 | #ifdef _MS C_VER | |
| 485 | #pragma wa rning(push ) | |
| 486 | #pragma wa rning(disa ble: 4018) | |
| 487 | #endif | |
| 488 | FD_S ET(ctxt->f d, &wfd); | |
| 489 | #ifdef _MS C_VER | |
| 490 | #pragma wa rning(pop) | |
| 491 | #endif | |
| 492 | (voi d) select( ctxt->fd + 1, NULL, &wfd, NULL , &tv); | |
| 493 | #else | |
| 494 | p.fd = ctxt->f d; | |
| 495 | p.ev ents = POL LOUT; | |
| 496 | (voi d) poll(&p , 1, timeo ut * 1000) ; | |
| 497 | #endif /* !HAVE_POLL _H */ | |
| 498 | } | |
| 499 | } | |
| 500 | } | |
| 501 | ||
| 502 | return total_sen t; | |
| 503 | } | |
| 504 | ||
| 505 | /** | |
| 506 | * xmlNano HTTPRecv: | |
| 507 | * @ctxt: an HTTP c ontext | |
| 508 | * | |
| 509 | * Read in formation coming fro m the HTTP connectio n. | |
| 510 | * This is a blockin g call (bu t it block s in selec t(), not r ead()). | |
| 511 | * | |
| 512 | * Returns the numbe r of byte read or -1 in case o f error. | |
| 513 | */ | |
| 514 | ||
| 515 | static int | |
| 516 | xmlNanoHTT PRecv(xmlN anoHTTPCtx tPtr ctxt) | |
| 517 | { | |
| 518 | #ifdef HAV E_POLL_H | |
| 519 | struct pollfd p; | |
| 520 | #else | |
| 521 | fd_set rfd; | |
| 522 | struct timeval t v; | |
| 523 | #endif | |
| 524 | ||
| 525 | ||
| 526 | while (ctxt->sta te & XML_N ANO_HTTP_R EAD) { | |
| 527 | if (ctxt->in == NULL) { | |
| 528 | ctxt->in = (char * ) xmlMallo cAtomic(65 000 * size of(char)); | |
| 529 | if (ctxt ->in == NU LL) { | |
| 530 | xmlH TTPErrMemo ry("alloca ting input "); | |
| 531 | ctxt ->last = - 1; | |
| 532 | retu rn (-1); | |
| 533 | } | |
| 534 | ctxt->in len = 6500 0; | |
| 535 | ctxt->in ptr = ctxt ->content = ctxt->in rptr = ctx t->in; | |
| 536 | } | |
| 537 | if (ctxt->in rptr > ctx t->in + XM L_NANO_HTT P_CHUNK) { | |
| 538 | int delt a = ctxt-> inrptr - c txt->in; | |
| 539 | int len = ctxt->in ptr - ctxt ->inrptr; | |
| 540 | ||
| 541 | memmove( ctxt->in, ctxt->inrp tr, len); | |
| 542 | ctxt->in rptr -= de lta; | |
| 543 | ctxt->co ntent -= d elta; | |
| 544 | ctxt->in ptr -= del ta; | |
| 545 | } | |
| 546 | if ((ctxt->i n + ctxt-> inlen) < ( ctxt->inpt r + XML_NA NO_HTTP_CH UNK)) { | |
| 547 | int d_in ptr = ctxt ->inptr - ctxt->in; | |
| 548 | int d_co ntent = ct xt->conten t - ctxt-> in; | |
| 549 | int d_in rptr = ctx t->inrptr - ctxt->in ; | |
| 550 | char *tm p_ptr = ct xt->in; | |
| 551 | ||
| 552 | ctxt->in len *= 2; | |
| 553 | ctxt->in = (char * ) xmlReall oc(tmp_ptr , ctxt->in len); | |
| 554 | if (ctxt ->in == NU LL) { | |
| 555 | xmlH TTPErrMemo ry("alloca ting input buffer"); | |
| 556 | xmlF ree(tmp_pt r); | |
| 557 | ctxt ->last = - 1; | |
| 558 | retu rn (-1); | |
| 559 | } | |
| 560 | ctxt->in ptr = ctxt ->in + d_i nptr; | |
| 561 | ctxt->co ntent = ct xt->in + d _content; | |
| 562 | ctxt->in rptr = ctx t->in + d_ inrptr; | |
| 563 | } | |
| 564 | ct xt->last = recv(ctxt ->fd, ctxt ->inptr, X ML_NANO_HT TP_CHUNK, 0); | |
| 565 | if (ctxt->la st > 0) { | |
| 566 | ctxt->in ptr += ctx t->last; | |
| 567 | return ( ctxt->last ); | |
| 568 | } | |
| 569 | if (ctxt->la st == 0) { | |
| 570 | return ( 0); | |
| 571 | } | |
| 572 | if (ctxt->la st == -1) { | |
| 573 | switch ( socket_err no()) { | |
| 574 | case EINPROGRE SS: | |
| 575 | case EWOULDBLO CK: | |
| 576 | #if define d(EAGAIN) && EAGAIN != EWOULDB LOCK | |
| 577 | case EAGAIN: | |
| 578 | #endif | |
| 579 | break; | |
| 580 | ||
| 581 | case ECONNRESE T: | |
| 582 | case ESHUTDOWN : | |
| 583 | return (0) ; | |
| 584 | ||
| 585 | defa ult: | |
| 586 | __xmlIOErr (XML_FROM_ HTTP, 0, " recv faile d\n"); | |
| 587 | return (-1 ); | |
| 588 | } | |
| 589 | } | |
| 590 | #ifdef HAV E_POLL_H | |
| 591 | p. fd = ctxt- >fd; | |
| 592 | p. events = P OLLIN; | |
| 593 | if ((poll(&p , 1, timeo ut * 1000) < 1) | |
| 594 | #if define d(EINTR) | |
| 595 | && (errn o != EINTR ) | |
| 596 | #endif | |
| 597 | ) | |
| 598 | return ( 0); | |
| 599 | #else /* ! HAVE_POLL_ H */ | |
| 600 | #ifndef _W INSOCKAPI_ | |
| 601 | if (ctxt->fd > FD_SETS IZE) | |
| 602 | return 0 ; | |
| 603 | #endif | |
| 604 | ||
| 605 | tv .tv_sec = timeout; | |
| 606 | tv .tv_usec = 0; | |
| 607 | FD _ZERO(&rfd ); | |
| 608 | ||
| 609 | #ifdef _MS C_VER | |
| 610 | #pragma wa rning(push ) | |
| 611 | #pragma wa rning(disa ble: 4018) | |
| 612 | #endif | |
| 613 | ||
| 614 | FD _SET(ctxt- >fd, &rfd) ; | |
| 615 | ||
| 616 | #ifdef _MS C_VER | |
| 617 | #pragma wa rning(pop) | |
| 618 | #endif | |
| 619 | ||
| 620 | if ((select( ctxt->fd + 1, &rfd, NULL, NULL , &tv) < 1 ) | |
| 621 | #if define d(EINTR) | |
| 622 | && (errn o != EINTR ) | |
| 623 | #endif | |
| 624 | ) | |
| 625 | return ( 0); | |
| 626 | #endif /* !HAVE_POLL _H */ | |
| 627 | } | |
| 628 | return (0); | |
| 629 | } | |
| 630 | ||
| 631 | /** | |
| 632 | * xmlNano HTTPReadLi ne: | |
| 633 | * @ctxt: an HTTP c ontext | |
| 634 | * | |
| 635 | * Read on e line in the HTTP s erver outp ut, usuall y for extr acting | |
| 636 | * the HTT P protocol informati ons from t he answer header. | |
| 637 | * | |
| 638 | * Returns a newly a llocated s tring with a copy of the line, or NULL | |
| 639 | * which ind icate the end of the input. | |
| 640 | */ | |
| 641 | ||
| 642 | static cha r * | |
| 643 | xmlNanoHTT PReadLine( xmlNanoHTT PCtxtPtr c txt) { | |
| 644 | char b uf[4096]; | |
| 645 | char * bp = buf; | |
| 646 | int rc ; | |
| 647 | ||
| 648 | while (bp - buf < 4095) { | |
| 649 | if (ctxt->in rptr == ct xt->inptr) { | |
| 650 | if ( (rc = xmlNano HTTPRecv(c txt)) == 0 ) { | |
| 651 | if ( bp == buf) | |
| 652 | return(NUL L); | |
| 653 | else | |
| 654 | *bp = 0; | |
| 655 | retu rn(xmlMemS trdup(buf) ); | |
| 656 | } | |
| 657 | else if ( rc == -1 ) { | |
| 658 | retu rn ( NULL ); | |
| 659 | } | |
| 660 | } | |
| 661 | *b p = *ctxt- >inrptr++; | |
| 662 | if (*bp == ' \n') { | |
| 663 | *bp = 0; | |
| 664 | return(x mlMemStrdu p(buf)); | |
| 665 | } | |
| 666 | if (*bp != ' \r') | |
| 667 | bp++; | |
| 668 | } | |
| 669 | buf[40 95] = 0; | |
| 670 | return (xmlMemStr dup(buf)); | |
| 671 | } | |
| 672 | ||
| 673 | ||
| 674 | /** | |
| 675 | * xmlNano HTTPScanAn swer: | |
| 676 | * @ctxt: an HTTP c ontext | |
| 677 | * @line: an HTTP h eader line | |
| 678 | * | |
| 679 | * Try to extract us eful infor mations fr om the ser ver answer . | |
| 680 | * We curr ently pars e and proc ess: | |
| 681 | * - The HTTP revis ion/ retur n code | |
| 682 | * - The Content-Ty pe, Mime-T ype and ch arset used | |
| 683 | * - The Location f or redirec t processi ng. | |
| 684 | * | |
| 685 | * Returns -1 in cas e of failu re, the fi le descrip tor number otherwise | |
| 686 | */ | |
| 687 | ||
| 688 | static voi d | |
| 689 | xmlNanoHTT PScanAnswe r(xmlNanoH TTPCtxtPtr ctxt, con st char *l ine) { | |
| 690 | const char *cur = line; | |
| 691 | ||
| 692 | if (li ne == NULL ) return; | |
| 693 | ||
| 694 | if (!s trncmp(lin e, "HTTP/" , 5)) { | |
| 695 | in t version = 0; | |
| 696 | in t ret = 0; | |
| 697 | ||
| 698 | cu r += 5; | |
| 699 | wh ile ((*cur >= '0') & & (*cur <= '9')) { | |
| 700 | version *= 10; | |
| 701 | version += *cur - '0'; | |
| 702 | cur++; | |
| 703 | } | |
| 704 | if (*cur == '.') { | |
| 705 | cur++; | |
| 706 | if ((*cu r >= '0') && (*cur < = '9')) { | |
| 707 | vers ion *= 10; | |
| 708 | vers ion += *cu r - '0'; | |
| 709 | cur+ +; | |
| 710 | } | |
| 711 | while (( *cur >= '0 ') && (*cu r <= '9')) | |
| 712 | cur+ +; | |
| 713 | } else | |
| 714 | version *= 10; | |
| 715 | if ((*cur != ' ') && ( *cur != '\ t')) retur n; | |
| 716 | wh ile ((*cur == ' ') | | (*cur == '\t')) cu r++; | |
| 717 | if ((*cur < '0') || (* cur > '9') ) return; | |
| 718 | wh ile ((*cur >= '0') & & (*cur <= '9')) { | |
| 719 | ret *= 1 0; | |
| 720 | ret += * cur - '0'; | |
| 721 | cur++; | |
| 722 | } | |
| 723 | if ((*cur != 0) && (*c ur != ' ') && (*cur != '\t')) return; | |
| 724 | ct xt->return Value = re t; | |
| 725 | ct xt->versio n = versio n; | |
| 726 | } else if (!xmlS trncasecmp (BAD_CAST line, BAD_ CAST"Conte nt-Type:", 13)) { | |
| 727 | co nst xmlCha r *charset , *last, * mime; | |
| 728 | cu r += 13; | |
| 729 | wh ile ((*cur == ' ') | | (*cur == '\t')) cu r++; | |
| 730 | if (ctxt->co ntentType != NULL) | |
| 731 | xmlFree( ctxt->cont entType); | |
| 732 | ct xt->conten tType = xm lMemStrdup (cur); | |
| 733 | mi me = (cons t xmlChar *) cur; | |
| 734 | la st = mime; | |
| 735 | wh ile ((*las t != 0) && (*last != ' ') && ( *last != ' \t') && | |
| 736 | (*las t != ';') && (*last != ',')) | |
| 737 | last++; | |
| 738 | if (ctxt->mi meType != NULL) | |
| 739 | xmlFree( ctxt->mime Type); | |
| 740 | ct xt->mimeTy pe = (char *) xmlStr ndup(mime, last - mi me); | |
| 741 | ch arset = xm lStrstr(BA D_CAST ctx t->content Type, BAD_ CAST "char set="); | |
| 742 | if (charset != NULL) { | |
| 743 | charset += 8; | |
| 744 | last = c harset; | |
| 745 | while (( *last != 0 ) && (*las t != ' ') && (*last != '\t') & & | |
| 746 | ( *last != ' ;') && (*l ast != ',' )) | |
| 747 | last ++; | |
| 748 | if (ctxt ->encoding != NULL) | |
| 749 | xmlF ree(ctxt-> encoding); | |
| 750 | ctxt->en coding = ( char *) xm lStrndup(c harset, la st - chars et); | |
| 751 | } | |
| 752 | } else if (!xmlS trncasecmp (BAD_CAST line, BAD_ CAST"Conte ntType:", 12)) { | |
| 753 | co nst xmlCha r *charset , *last, * mime; | |
| 754 | cu r += 12; | |
| 755 | if (ctxt->co ntentType != NULL) r eturn; | |
| 756 | wh ile ((*cur == ' ') | | (*cur == '\t')) cu r++; | |
| 757 | ct xt->conten tType = xm lMemStrdup (cur); | |
| 758 | mi me = (cons t xmlChar *) cur; | |
| 759 | la st = mime; | |
| 760 | wh ile ((*las t != 0) && (*last != ' ') && ( *last != ' \t') && | |
| 761 | (*las t != ';') && (*last != ',')) | |
| 762 | last++; | |
| 763 | if (ctxt->mi meType != NULL) | |
| 764 | xmlFree( ctxt->mime Type); | |
| 765 | ct xt->mimeTy pe = (char *) xmlStr ndup(mime, last - mi me); | |
| 766 | ch arset = xm lStrstr(BA D_CAST ctx t->content Type, BAD_ CAST "char set="); | |
| 767 | if (charset != NULL) { | |
| 768 | charset += 8; | |
| 769 | last = c harset; | |
| 770 | while (( *last != 0 ) && (*las t != ' ') && (*last != '\t') & & | |
| 771 | ( *last != ' ;') && (*l ast != ',' )) | |
| 772 | last ++; | |
| 773 | if (ctxt ->encoding != NULL) | |
| 774 | xmlF ree(ctxt-> encoding); | |
| 775 | ctxt->en coding = ( char *) xm lStrndup(c harset, la st - chars et); | |
| 776 | } | |
| 777 | } else if (!xmlS trncasecmp (BAD_CAST line, BAD_ CAST"Locat ion:", 9)) { | |
| 778 | cu r += 9; | |
| 779 | wh ile ((*cur == ' ') | | (*cur == '\t')) cu r++; | |
| 780 | if (ctxt->lo cation != NULL) | |
| 781 | xmlFree( ctxt->loca tion); | |
| 782 | if (*cur == '/') { | |
| 783 | xmlChar *tmp_http = xmlStrdu p(BAD_CAST "http://" ); | |
| 784 | xmlChar *tmp_loc = | |
| 785 | xmlS trcat(tmp_ http, (con st xmlChar *) ctxt-> hostname); | |
| 786 | ctxt->lo cation = | |
| 787 | (cha r *) xmlSt rcat (tmp_ loc, (cons t xmlChar *) cur); | |
| 788 | } else { | |
| 789 | ctxt->lo cation = x mlMemStrdu p(cur); | |
| 790 | } | |
| 791 | } else if (!xmlS trncasecmp (BAD_CAST line, BAD_ CAST"WWW-A uthenticat e:", 17)) { | |
| 792 | cu r += 17; | |
| 793 | wh ile ((*cur == ' ') | | (*cur == '\t')) cu r++; | |
| 794 | if (ctxt->au thHeader ! = NULL) | |
| 795 | xmlFree( ctxt->auth Header); | |
| 796 | ct xt->authHe ader = xml MemStrdup( cur); | |
| 797 | } else if (!xmlS trncasecmp (BAD_CAST line, BAD_ CAST"Proxy -Authentic ate:", 19) ) { | |
| 798 | cu r += 19; | |
| 799 | wh ile ((*cur == ' ') | | (*cur == '\t')) cu r++; | |
| 800 | if (ctxt->au thHeader ! = NULL) | |
| 801 | xmlFree( ctxt->auth Header); | |
| 802 | ct xt->authHe ader = xml MemStrdup( cur); | |
| 803 | #ifdef HAV E_ZLIB_H | |
| 804 | } else if ( !xml Strncasecm p( BAD_CAS T line, BA D_CAST"Con tent-Encod ing:", 17) ) { | |
| 805 | cu r += 17; | |
| 806 | wh ile ((*cur == ' ') | | (*cur == '\t')) cu r++; | |
| 807 | if ( !xmlStr ncasecmp( BAD_CAST c ur, BAD_CA ST"gzip", 4) ) { | |
| 808 | ctxt->us esGzip = 1 ; | |
| 809 | ||
| 810 | ctxt->st rm = xmlMa lloc(sizeo f(z_stream )); | |
| 811 | ||
| 812 | if (ctxt ->strm != NULL) { | |
| 813 | ctxt ->strm->za lloc = Z_N ULL; | |
| 814 | ctxt ->strm->zf ree = Z_NU LL; | |
| 815 | ctxt ->strm->op aque = Z_N ULL; | |
| 816 | ctxt ->strm->av ail_in = 0 ; | |
| 817 | ctxt ->strm->ne xt_in = Z_ NULL; | |
| 818 | ||
| 819 | infl ateInit2( ctxt->strm , 31 ); | |
| 820 | } | |
| 821 | } | |
| 822 | #endif | |
| 823 | } else if ( !xml Strncasecm p( BAD_CAS T line, BA D_CAST"Con tent-Lengt h:", 15) ) { | |
| 824 | cu r += 15; | |
| 825 | ct xt->Conten tLength = strtol( cu r, NULL, 1 0 ); | |
| 826 | } | |
| 827 | } | |
| 828 | ||
| 829 | /** | |
| 830 | * xmlNano HTTPConnec tAttempt: | |
| 831 | * @addr: a socket address st ructure | |
| 832 | * | |
| 833 | * Attempt a connect ion to the given IP: port endpo int. It fo rces | |
| 834 | * non-blo cking sema ntic on th e socket, and allow 60 seconds for | |
| 835 | * the hos t to answe r. | |
| 836 | * | |
| 837 | * Returns -1 in cas e of failu re, the fi le descrip tor number otherwise | |
| 838 | */ | |
| 839 | ||
| 840 | static SOC KET | |
| 841 | xmlNanoHTT PConnectAt tempt(stru ct sockadd r *addr) | |
| 842 | { | |
| 843 | #ifndef HA VE_POLL_H | |
| 844 | fd_set wfd; | |
| 845 | #ifdef _WI NSOCKAPI_ | |
| 846 | fd_set xfd; | |
| 847 | #endif | |
| 848 | struct timeval t v; | |
| 849 | #else /* ! HAVE_POLL_ H */ | |
| 850 | struct pollfd p; | |
| 851 | #endif /* !HAVE_POLL _H */ | |
| 852 | int st atus; | |
| 853 | ||
| 854 | int ad drlen; | |
| 855 | ||
| 856 | SOCKET s; | |
| 857 | ||
| 858 | #ifdef SUP PORT_IP6 | |
| 859 | if (ad dr->sa_fam ily == AF_ INET6) { | |
| 860 | s = socket(P F_INET6, S OCK_STREAM , IPPROTO_ TCP); | |
| 861 | ad drlen = si zeof(struc t sockaddr _in6); | |
| 862 | } else | |
| 863 | #endif | |
| 864 | { | |
| 865 | s = socket(P F_INET, SO CK_STREAM, IPPROTO_T CP); | |
| 866 | ad drlen = si zeof(struc t sockaddr _in); | |
| 867 | } | |
| 868 | if (s == INVALID _SOCKET) { | |
| 869 | #ifdef DEB UG_HTTP | |
| 870 | pe rror("sock et"); | |
| 871 | #endif | |
| 872 | __ xmlIOErr(X ML_FROM_HT TP, 0, "so cket faile d\n"); | |
| 873 | re turn INVAL ID_SOCKET; | |
| 874 | } | |
| 875 | #ifdef _WI NSOCKAPI_ | |
| 876 | { | |
| 877 | u_ long one = 1; | |
| 878 | ||
| 879 | st atus = ioc tlsocket(s , FIONBIO, &one) == SOCKET_ERR OR ? -1 : 0; | |
| 880 | } | |
| 881 | #else /* _ WINSOCKAPI _ */ | |
| 882 | #if define d(VMS) | |
| 883 | { | |
| 884 | in t enable = 1; | |
| 885 | ||
| 886 | st atus = ioc tl(s, FION BIO, &enab le); | |
| 887 | } | |
| 888 | #else /* V MS */ | |
| 889 | #if define d(__BEOS__ ) && !defi ned(__HAIK U__) | |
| 890 | { | |
| 891 | bo ol noblock = true; | |
| 892 | ||
| 893 | st atus = | |
| 894 | setsocko pt(s, SOL_ SOCKET, SO _NONBLOCK, &noblock, | |
| 895 | sizeof( noblock)); | |
| 896 | } | |
| 897 | #else /* _ _BEOS__ */ | |
| 898 | if ((s tatus = fc ntl(s, F_G ETFL, 0)) != -1) { | |
| 899 | #ifdef O_N ONBLOCK | |
| 900 | st atus |= O_ NONBLOCK; | |
| 901 | #else /* O _NONBLOCK */ | |
| 902 | #ifdef F_N DELAY | |
| 903 | st atus |= F_ NDELAY; | |
| 904 | #endif /* F_NDELAY * / | |
| 905 | #endif /* !O_NONBLOC K */ | |
| 906 | st atus = fcn tl(s, F_SE TFL, statu s); | |
| 907 | } | |
| 908 | if (st atus < 0) { | |
| 909 | #ifdef DEB UG_HTTP | |
| 910 | pe rror("nonb locking"); | |
| 911 | #endif | |
| 912 | __ xmlIOErr(X ML_FROM_HT TP, 0, "er ror settin g non-bloc king IO\n" ); | |
| 913 | cl osesocket( s); | |
| 914 | re turn INVAL ID_SOCKET; | |
| 915 | } | |
| 916 | #endif /* !__BEOS__ */ | |
| 917 | #endif /* !VMS */ | |
| 918 | #endif /* !_WINSOCKA PI_ */ | |
| 919 | ||
| 920 | if (co nnect(s, a ddr, addrl en) == -1) { | |
| 921 | sw itch (sock et_errno() ) { | |
| 922 | case EIN PROGRESS: | |
| 923 | case EWO ULDBLOCK: | |
| 924 | brea k; | |
| 925 | default: | |
| 926 | __xm lIOErr(XML _FROM_HTTP , 0, | |
| 927 | "er ror connec ting to HT TP server" ); | |
| 928 | clos esocket(s) ; | |
| 929 | retu rn INVALID _SOCKET; | |
| 930 | } | |
| 931 | } | |
| 932 | #ifndef HA VE_POLL_H | |
| 933 | tv.tv_ sec = time out; | |
| 934 | tv.tv_ usec = 0; | |
| 935 | ||
| 936 | #ifdef _MS C_VER | |
| 937 | #pragma wa rning(push ) | |
| 938 | #pragma wa rning(disa ble: 4018) | |
| 939 | #endif | |
| 940 | #ifndef _W INSOCKAPI_ | |
| 941 | if (s > FD_SETSI ZE) | |
| 942 | re turn INVAL ID_SOCKET; | |
| 943 | #endif | |
| 944 | FD_ZER O(&wfd); | |
| 945 | FD_SET (s, &wfd); | |
| 946 | ||
| 947 | #ifdef _WI NSOCKAPI_ | |
| 948 | FD_ZER O(&xfd); | |
| 949 | FD_SET (s, &xfd); | |
| 950 | ||
| 951 | switch (select(s + 1, NULL , &wfd, &x fd, &tv)) | |
| 952 | #else | |
| 953 | switch (select(s + 1, NULL , &wfd, NU LL, &tv)) | |
| 954 | #endif | |
| 955 | #ifdef _MS C_VER | |
| 956 | #pragma wa rning(pop) | |
| 957 | #endif | |
| 958 | ||
| 959 | #else /* ! HAVE_POLL_ H */ | |
| 960 | p.fd = s; | |
| 961 | p.even ts = POLLO UT; | |
| 962 | switch (poll(&p, 1, timeou t * 1000)) | |
| 963 | #endif /* !HAVE_POLL _H */ | |
| 964 | ||
| 965 | { | |
| 966 | ca se 0: | |
| 967 | /* Time out */ | |
| 968 | __xmlIOE rr(XML_FRO M_HTTP, 0, "Connect attempt ti med out"); | |
| 969 | closesoc ket(s); | |
| 970 | return I NVALID_SOC KET; | |
| 971 | ca se -1: | |
| 972 | /* Ermm. . ?? */ | |
| 973 | __xmlIOE rr(XML_FRO M_HTTP, 0, "Connect failed"); | |
| 974 | closesoc ket(s); | |
| 975 | return I NVALID_SOC KET; | |
| 976 | } | |
| 977 | ||
| 978 | #ifndef HA VE_POLL_H | |
| 979 | if (FD _ISSET(s, &wfd) | |
| 980 | #ifdef _WI NSOCKAPI_ | |
| 981 | || FD_ISSET( s, &xfd) | |
| 982 | #endif | |
| 983 | ) | |
| 984 | #else /* ! HAVE_POLL_ H */ | |
| 985 | if (p. revents == POLLOUT) | |
| 986 | #endif /* !HAVE_POLL _H */ | |
| 987 | { | |
| 988 | XM L_SOCKLEN_ T len; | |
| 989 | ||
| 990 | le n = sizeof (status); | |
| 991 | #ifdef SO_ ERROR | |
| 992 | if (getsocko pt(s, SOL_ SOCKET, SO _ERROR, (c har *) &st atus, &len ) < | |
| 993 | 0) { | |
| 994 | /* Solar is error c ode */ | |
| 995 | __xmlIOE rr(XML_FRO M_HTTP, 0, "getsocko pt failed\ n"); | |
| 996 | return I NVALID_SOC KET; | |
| 997 | } | |
| 998 | #endif | |
| 999 | if (status) { | |
| 1000 | __xmlIOE rr(XML_FRO M_HTTP, 0, | |
| 1001 | "Error connecting to remote host"); | |
| 1002 | closesoc ket(s); | |
| 1003 | errno = status; | |
| 1004 | return I NVALID_SOC KET; | |
| 1005 | } | |
| 1006 | } else { | |
| 1007 | /* pbm */ | |
| 1008 | __ xmlIOErr(X ML_FROM_HT TP, 0, "se lect faile d\n"); | |
| 1009 | cl osesocket( s); | |
| 1010 | re turn INVAL ID_SOCKET; | |
| 1011 | } | |
| 1012 | ||
| 1013 | return (s); | |
| 1014 | } | |
| 1015 | ||
| 1016 | /** | |
| 1017 | * xmlNano HTTPConnec tHost: | |
| 1018 | * @host: the host name | |
| 1019 | * @port: the port number | |
| 1020 | * | |
| 1021 | * Attempt a connect ion to the given hos t:port end point. It tries | |
| 1022 | * the mul tiple IP p rovided by the DNS i f availabl e. | |
| 1023 | * | |
| 1024 | * Returns -1 in cas e of failu re, the fi le descrip tor number otherwise | |
| 1025 | */ | |
| 1026 | ||
| 1027 | static SOC KET | |
| 1028 | xmlNanoHTT PConnectHo st(const c har *host, int port) | |
| 1029 | { | |
| 1030 | struct hostent * h; | |
| 1031 | struct sockaddr *addr = NU LL; | |
| 1032 | struct in_addr i a; | |
| 1033 | struct sockaddr_ in sockin; | |
| 1034 | ||
| 1035 | #ifdef SUP PORT_IP6 | |
| 1036 | struct in6_addr ia6; | |
| 1037 | struct sockaddr_ in6 sockin 6; | |
| 1038 | #endif | |
| 1039 | int i; | |
| 1040 | SOCKET s; | |
| 1041 | ||
| 1042 | memset (&sockin, 0, sizeof (sockin)); | |
| 1043 | #ifdef SUP PORT_IP6 | |
| 1044 | memset (&sockin6 , 0, sizeo f(sockin6) ); | |
| 1045 | #endif | |
| 1046 | ||
| 1047 | #if !defin ed(HAVE_GE TADDRINFO) && define d(SUPPORT_ IP6) && de fined(RES_ USE_INET6) | |
| 1048 | if (ha ve_ipv6 () ) | |
| 1049 | { | |
| 1050 | if (!(_res.o ptions & R ES_INIT)) | |
| 1051 | res_init (); | |
| 1052 | _r es.options |= RES_US E_INET6; | |
| 1053 | } | |
| 1054 | #endif | |
| 1055 | ||
| 1056 | #if define d(HAVE_GET ADDRINFO) && defined (SUPPORT_I P6) && !de fined(_WIN 32) | |
| 1057 | if (ha ve_ipv6 () ) | |
| 1058 | #endif | |
| 1059 | #if define d(HAVE_GET ADDRINFO) && (define d(SUPPORT_ IP6) || de fined(_WIN 32)) | |
| 1060 | { | |
| 1061 | in t status; | |
| 1062 | st ruct addri nfo hints, *res, *re sult; | |
| 1063 | ||
| 1064 | re sult = NUL L; | |
| 1065 | me mset (&hin ts, 0,size of(hints)) ; | |
| 1066 | hi nts.ai_soc ktype = SO CK_STREAM; | |
| 1067 | ||
| 1068 | st atus = get addrinfo ( host, NULL , &hints, &result); | |
| 1069 | if (status) { | |
| 1070 | __xmlIOE rr(XML_FRO M_HTTP, 0, "getaddri nfo failed \n"); | |
| 1071 | return I NVALID_SOC KET; | |
| 1072 | } | |
| 1073 | ||
| 1074 | fo r (res = r esult; res ; res = re s->ai_next ) { | |
| 1075 | if (res- >ai_family == AF_INE T) { | |
| 1076 | if ( res->ai_ad drlen > si zeof(socki n)) { | |
| 1077 | __xmlIOErr (XML_FROM_ HTTP, 0, " address si ze mismatc h\n"); | |
| 1078 | freeaddrin fo (result ); | |
| 1079 | return INV ALID_SOCKE T; | |
| 1080 | } | |
| 1081 | memc py (&socki n, res->ai _addr, res ->ai_addrl en); | |
| 1082 | sock in.sin_por t = htons (port); | |
| 1083 | addr = (struct sockaddr *)&sockin; | |
| 1084 | #ifdef SUP PORT_IP6 | |
| 1085 | } else i f (have_ip v6 () && ( res->ai_fa mily == AF _INET6)) { | |
| 1086 | if ( res->ai_ad drlen > si zeof(socki n6)) { | |
| 1087 | __xmlIOErr (XML_FROM_ HTTP, 0, " address si ze mismatc h\n"); | |
| 1088 | freeaddrin fo (result ); | |
| 1089 | return INV ALID_SOCKE T; | |
| 1090 | } | |
| 1091 | memc py (&socki n6, res->a i_addr, re s->ai_addr len); | |
| 1092 | sock in6.sin6_p ort = hton s (port); | |
| 1093 | addr = (struct sockaddr *)&sockin6 ; | |
| 1094 | #endif | |
| 1095 | } else | |
| 1096 | cont inue; / * for */ | |
| 1097 | ||
| 1098 | s = xmlN anoHTTPCon nectAttemp t (addr); | |
| 1099 | if (s != INVALID_S OCKET) { | |
| 1100 | free addrinfo ( result); | |
| 1101 | retu rn (s); | |
| 1102 | } | |
| 1103 | } | |
| 1104 | ||
| 1105 | if (result) | |
| 1106 | freeaddr info (resu lt); | |
| 1107 | } | |
| 1108 | #endif | |
| 1109 | #if define d(HAVE_GET ADDRINFO) && defined (SUPPORT_I P6) && !de fined(_WIN 32) | |
| 1110 | else | |
| 1111 | #endif | |
| 1112 | #if !defin ed(HAVE_GE TADDRINFO) || !defin ed(_WIN32) | |
| 1113 | { | |
| 1114 | h = gethostb yname (hos t); | |
| 1115 | if (h == NUL L) { | |
| 1116 | ||
| 1117 | /* | |
| 1118 | * Okay, I got fed u p by the n on-portabi lity of th is error m essage | |
| 1119 | * extract ion code. it work on Linux, if it work o n your pla tform | |
| 1120 | * and one want to e nable it, send me th e defined( foobar) ne eded | |
| 1121 | */ | |
| 1122 | #if define d(HAVE_NET DB_H) && d efined(HOS T_NOT_FOUN D) && defi ned(linux) | |
| 1123 | const ch ar *h_err_ txt = ""; | |
| 1124 | ||
| 1125 | switch ( h_errno) { | |
| 1126 | case HOST_NOT_ FOUND: | |
| 1127 | h_err_txt = "Authori tive host not found" ; | |
| 1128 | break; | |
| 1129 | ||
| 1130 | case TRY_AGAIN : | |
| 1131 | h_err_txt = | |
| 1132 | "Non-a uthoritive host not found or s erver fail ure."; | |
| 1133 | break; | |
| 1134 | ||
| 1135 | case NO_RECOVE RY: | |
| 1136 | h_err_txt = | |
| 1137 | "Non-r ecoverable errors: FORMERR, R EFUSED, or NOTIMP."; | |
| 1138 | break; | |
| 1139 | ||
| 1140 | #ifdef NO_ ADDRESS | |
| 1141 | case NO_ADDRES S: | |
| 1142 | h_err_txt = | |
| 1143 | "Valid name, no data recor d of reque sted type. "; | |
| 1144 | break; | |
| 1145 | #endif | |
| 1146 | ||
| 1147 | defa ult: | |
| 1148 | h_err_txt = "No erro r text def ined."; | |
| 1149 | break; | |
| 1150 | } | |
| 1151 | __xmlIOE rr(XML_FRO M_HTTP, 0, h_err_txt ); | |
| 1152 | #else | |
| 1153 | __xmlIOE rr(XML_FRO M_HTTP, 0, "Failed t o resolve host"); | |
| 1154 | #endif | |
| 1155 | return I NVALID_SOC KET; | |
| 1156 | } | |
| 1157 | ||
| 1158 | fo r (i = 0; h->h_addr_ list[i]; i ++) { | |
| 1159 | if (h->h _addrtype == AF_INET ) { | |
| 1160 | /* A records ( IPv4) */ | |
| 1161 | if ( (unsigned int) h->h_ length > s izeof(ia)) { | |
| 1162 | __xmlIOErr (XML_FROM_ HTTP, 0, " address si ze mismatc h\n"); | |
| 1163 | return INV ALID_SOCKE T; | |
| 1164 | } | |
| 1165 | memc py (&ia, h ->h_addr_l ist[i], h- >h_length) ; | |
| 1166 | sock in.sin_fam ily = h->h _addrtype; | |
| 1167 | sock in.sin_add r = ia; | |
| 1168 | sock in.sin_por t = (unsig ned short) htons ((un signed sho rt)port); | |
| 1169 | addr = (struct sockaddr *) &sockin ; | |
| 1170 | #ifdef SUP PORT_IP6 | |
| 1171 | } else i f (have_ip v6 () && ( h->h_addrt ype == AF_ INET6)) { | |
| 1172 | /* A AAA record s (IPv6) * / | |
| 1173 | if ( (unsigned int) h->h_ length > s izeof(ia6) ) { | |
| 1174 | __xmlIOErr (XML_FROM_ HTTP, 0, " address si ze mismatc h\n"); | |
| 1175 | return INV ALID_SOCKE T; | |
| 1176 | } | |
| 1177 | memc py (&ia6, h->h_addr_ list[i], h ->h_length ); | |
| 1178 | sock in6.sin6_f amily = h- >h_addrtyp e; | |
| 1179 | sock in6.sin6_a ddr = ia6; | |
| 1180 | sock in6.sin6_p ort = hton s (port); | |
| 1181 | addr = (struct sockaddr *) &sockin 6; | |
| 1182 | #endif | |
| 1183 | } else | |
| 1184 | brea k; /* f or */ | |
| 1185 | ||
| 1186 | s = xmlN anoHTTPCon nectAttemp t (addr); | |
| 1187 | if (s != INVALID_S OCKET) | |
| 1188 | retu rn (s); | |
| 1189 | } | |
| 1190 | } | |
| 1191 | #endif | |
| 1192 | ||
| 1193 | #ifdef DEB UG_HTTP | |
| 1194 | xmlGen ericError( xmlGeneric ErrorConte xt, | |
| 1195 | "xmlNanoHT TPConnectH ost: unab le to conn ect to '%s '.\n", | |
| 1196 | host); | |
| 1197 | #endif | |
| 1198 | return INVALID_S OCKET; | |
| 1199 | } | |
| 1200 | ||
| 1201 | ||
| 1202 | /** | |
| 1203 | * xmlNano HTTPOpen: | |
| 1204 | * @URL: The URL to load | |
| 1205 | * @conten tType: if available the Conte nt-Type in formation will be | |
| 1206 | * re turned at that locat ion | |
| 1207 | * | |
| 1208 | * This fu nction try to open a connectio n to the i ndicated r esource | |
| 1209 | * via HTT P GET. | |
| 1210 | * | |
| 1211 | * Returns NULL in c ase of fai lure, othe rwise a re quest hand ler. | |
| 1212 | * The contentTy pe, if pro vided must be freed by the cal ler | |
| 1213 | */ | |
| 1214 | ||
| 1215 | void* | |
| 1216 | xmlNanoHTT POpen(cons t char *UR L, char ** contentTyp e) { | |
| 1217 | if (co ntentType != NULL) * contentTyp e = NULL; | |
| 1218 | return (xmlNanoHT TPMethod(U RL, NULL, NULL, cont entType, N ULL, 0)); | |
| 1219 | } | |
| 1220 | ||
| 1221 | /** | |
| 1222 | * xmlNano HTTPOpenRe dir: | |
| 1223 | * @URL: The URL to load | |
| 1224 | * @conten tType: if available the Conte nt-Type in formation will be | |
| 1225 | * re turned at that locat ion | |
| 1226 | * @redir: if availa ble the re directed U RL will be returned | |
| 1227 | * | |
| 1228 | * This fu nction try to open a connectio n to the i ndicated r esource | |
| 1229 | * via HTT P GET. | |
| 1230 | * | |
| 1231 | * Returns NULL in c ase of fai lure, othe rwise a re quest hand ler. | |
| 1232 | * The contentTy pe, if pro vided must be freed by the cal ler | |
| 1233 | */ | |
| 1234 | ||
| 1235 | void* | |
| 1236 | xmlNanoHTT POpenRedir (const cha r *URL, ch ar **conte ntType, ch ar **redir ) { | |
| 1237 | if (co ntentType != NULL) * contentTyp e = NULL; | |
| 1238 | if (re dir != NUL L) *redir = NULL; | |
| 1239 | return (xmlNanoHT TPMethodRe dir(URL, N ULL, NULL, contentTy pe, redir, NULL,0)); | |
| 1240 | } | |
| 1241 | ||
| 1242 | /** | |
| 1243 | * xmlNano HTTPRead: | |
| 1244 | * @ctx: the HTTP c ontext | |
| 1245 | * @dest: a buffer | |
| 1246 | * @len: the buffer length | |
| 1247 | * | |
| 1248 | * This fu nction tri es to read @len byte s from the existing HTTP conne ction | |
| 1249 | * and sav es them in @dest. Th is is a bl ocking cal l. | |
| 1250 | * | |
| 1251 | * Returns the numbe r of byte read. 0 is an indica tion of an end of co nnection. | |
| 1252 | * -1 indica tes a para meter erro r. | |
| 1253 | */ | |
| 1254 | int | |
| 1255 | xmlNanoHTT PRead(void *ctx, voi d *dest, i nt len) { | |
| 1256 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoHT TPCtxtPtr) ctx; | |
| 1257 | #ifdef HAV E_ZLIB_H | |
| 1258 | int by tes_read = 0; | |
| 1259 | int or ig_avail_i n; | |
| 1260 | int z_ ret; | |
| 1261 | #endif | |
| 1262 | ||
| 1263 | if (ct x == NULL) return(-1 ); | |
| 1264 | if (de st == NULL ) return(- 1); | |
| 1265 | if (le n <= 0) re turn(0); | |
| 1266 | ||
| 1267 | #ifdef HAV E_ZLIB_H | |
| 1268 | if (ct xt->usesGz ip == 1) { | |
| 1269 | if (ctxt->st rm == NULL ) return(0 ); | |
| 1270 | ||
| 1271 | ct xt->strm-> next_out = dest; | |
| 1272 | ct xt->strm-> avail_out = len; | |
| 1273 | ct xt->strm-> avail_in = ctxt->inp tr - ctxt- >inrptr; | |
| 1274 | ||
| 1275 | wh ile (ctxt- >strm->ava il_out > 0 && | |
| 1276 | (ctxt ->strm->av ail_in > 0 || xmlNan oHTTPRecv( ctxt) > 0) ) { | |
| 1277 | orig_ava il_in = ct xt->strm-> avail_in = | |
| 1278 | ct xt->inptr - ctxt->in rptr - byt es_read; | |
| 1279 | ctxt->st rm->next_i n = BAD_CA ST (ctxt-> inrptr + b ytes_read) ; | |
| 1280 | ||
| 1281 | z_ret = inflate(ct xt->strm, Z_NO_FLUSH ); | |
| 1282 | bytes_re ad += orig _avail_in - ctxt->st rm->avail_ in; | |
| 1283 | ||
| 1284 | if (z_re t != Z_OK) break; | |
| 1285 | } | |
| 1286 | ||
| 1287 | ct xt->inrptr += bytes_ read; | |
| 1288 | re turn(len - ctxt->str m->avail_o ut); | |
| 1289 | } | |
| 1290 | #endif | |
| 1291 | ||
| 1292 | while (ctxt->inp tr - ctxt- >inrptr < len) { | |
| 1293 | if (xmlNanoH TTPRecv(ct xt) <= 0) break; | |
| 1294 | } | |
| 1295 | if (ct xt->inptr - ctxt->in rptr < len ) | |
| 1296 | le n = ctxt-> inptr - ct xt->inrptr ; | |
| 1297 | memcpy (dest, ctx t->inrptr, len); | |
| 1298 | ctxt-> inrptr += len; | |
| 1299 | return (len); | |
| 1300 | } | |
| 1301 | ||
| 1302 | /** | |
| 1303 | * xmlNano HTTPClose: | |
| 1304 | * @ctx: the HTTP c ontext | |
| 1305 | * | |
| 1306 | * This fu nction clo ses an HTT P context, it ends u p the conn ection and | |
| 1307 | * free al l data rel ated to it . | |
| 1308 | */ | |
| 1309 | void | |
| 1310 | xmlNanoHTT PClose(voi d *ctx) { | |
| 1311 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoHT TPCtxtPtr) ctx; | |
| 1312 | ||
| 1313 | if (ct x == NULL) return; | |
| 1314 | ||
| 1315 | xmlNan oHTTPFreeC txt(ctxt); | |
| 1316 | } | |
| 1317 | ||
| 1318 | /** | |
| 1319 | * xmlNano HTTPMethod Redir: | |
| 1320 | * @URL: The URL to load | |
| 1321 | * @method : the HTT P method t o use | |
| 1322 | * @input: the inpu t string i f any | |
| 1323 | * @conten tType: th e Content- Type infor mation IN and OUT | |
| 1324 | * @redir: the redi rected URL OUT | |
| 1325 | * @header s: the ex tra header s | |
| 1326 | * @ilen: input len gth | |
| 1327 | * | |
| 1328 | * This fu nction try to open a connectio n to the i ndicated r esource | |
| 1329 | * via HTT P using th e given @m ethod, add ing the gi ven extra headers | |
| 1330 | * and the input buf fer for th e request content. | |
| 1331 | * | |
| 1332 | * Returns NULL in c ase of fai lure, othe rwise a re quest hand ler. | |
| 1333 | * The contentTy pe, or red ir, if pro vided must be freed by the cal ler | |
| 1334 | */ | |
| 1335 | ||
| 1336 | void* | |
| 1337 | xmlNanoHTT PMethodRed ir(const c har *URL, const char *method, const char *input, | |
| 1338 | ch ar **conte ntType, ch ar **redir , | |
| 1339 | co nst char * headers, i nt ilen ) { | |
| 1340 | xmlNan oHTTPCtxtP tr ctxt; | |
| 1341 | char * bp, *p; | |
| 1342 | int bl en; | |
| 1343 | SOCKET ret; | |
| 1344 | int nb Redirects = 0; | |
| 1345 | char * redirURL = NULL; | |
| 1346 | #ifdef DEB UG_HTTP | |
| 1347 | int xm t_bytes; | |
| 1348 | #endif | |
| 1349 | ||
| 1350 | if (UR L == NULL) return(NU LL); | |
| 1351 | if (me thod == NU LL) method = "GET"; | |
| 1352 | xmlNan oHTTPInit( ); | |
| 1353 | ||
| 1354 | retry: | |
| 1355 | if (re dirURL == NULL) | |
| 1356 | ct xt = xmlNa noHTTPNewC txt(URL); | |
| 1357 | else { | |
| 1358 | ct xt = xmlNa noHTTPNewC txt(redirU RL); | |
| 1359 | ct xt->locati on = xmlMe mStrdup(re dirURL); | |
| 1360 | } | |
| 1361 | ||
| 1362 | if ( c txt == NUL L ) { | |
| 1363 | re turn ( NUL L ); | |
| 1364 | } | |
| 1365 | ||
| 1366 | if ((c txt->proto col == NUL L) || (str cmp(ctxt-> protocol, "http"))) { | |
| 1367 | __ xmlIOErr(X ML_FROM_HT TP, XML_HT TP_URL_SYN TAX, "Not a valid HT TP URI"); | |
| 1368 | xm lNanoHTTPF reeCtxt(ct xt); | |
| 1369 | if (redirURL != NULL) xmlFree(re dirURL); | |
| 1370 | re turn(NULL) ; | |
| 1371 | } | |
| 1372 | if (ct xt->hostna me == NULL ) { | |
| 1373 | __ xmlIOErr(X ML_FROM_HT TP, XML_HT TP_UNKNOWN _HOST, | |
| 1374 | " Failed to identify h ost in URI "); | |
| 1375 | xm lNanoHTTPF reeCtxt(ct xt); | |
| 1376 | if (redirURL != NULL) xmlFree(re dirURL); | |
| 1377 | re turn(NULL) ; | |
| 1378 | } | |
| 1379 | if (pr oxy) { | |
| 1380 | bl en = strle n(ctxt->ho stname) * 2 + 16; | |
| 1381 | re t = xmlNan oHTTPConne ctHost(pro xy, proxyP ort); | |
| 1382 | } | |
| 1383 | else { | |
| 1384 | bl en = strle n(ctxt->ho stname); | |
| 1385 | re t = xmlNan oHTTPConne ctHost(ctx t->hostnam e, ctxt->p ort); | |
| 1386 | } | |
| 1387 | if (re t == INVAL ID_SOCKET) { | |
| 1388 | xm lNanoHTTPF reeCtxt(ct xt); | |
| 1389 | if (redirURL != NULL) xmlFree(re dirURL); | |
| 1390 | re turn(NULL) ; | |
| 1391 | } | |
| 1392 | ctxt-> fd = ret; | |
| 1393 | ||
| 1394 | if (in put == NUL L) | |
| 1395 | il en = 0; | |
| 1396 | else | |
| 1397 | bl en += 36; | |
| 1398 | ||
| 1399 | if (he aders != N ULL) | |
| 1400 | bl en += strl en(headers ) + 2; | |
| 1401 | if (co ntentType && *conten tType) | |
| 1402 | /* reserve f or string plus 'Cont ent-Type: \r\n" */ | |
| 1403 | bl en += strl en(*conten tType) + 1 6; | |
| 1404 | if (ct xt->query != NULL) | |
| 1405 | /* 1 for '?' */ | |
| 1406 | bl en += strl en(ctxt->q uery) + 1; | |
| 1407 | blen + = strlen(m ethod) + s trlen(ctxt ->path) + 24; | |
| 1408 | #ifdef HAV E_ZLIB_H | |
| 1409 | /* res erve for p ossible 'A ccept-Enco ding: gzip ' string * / | |
| 1410 | blen + = 23; | |
| 1411 | #endif | |
| 1412 | if (ct xt->port ! = 80) { | |
| 1413 | /* reserve s pace for ' :xxxxx', i ncl. poten tial proxy */ | |
| 1414 | if (proxy) | |
| 1415 | blen += 12; | |
| 1416 | el se | |
| 1417 | blen += 6; | |
| 1418 | } | |
| 1419 | bp = ( char*)xmlM allocAtomi c(blen); | |
| 1420 | if ( b p == NULL ) { | |
| 1421 | xm lNanoHTTPF reeCtxt( c txt ); | |
| 1422 | xm lHTTPErrMe mory("allo cating hea der buffer "); | |
| 1423 | re turn ( NUL L ); | |
| 1424 | } | |
| 1425 | ||
| 1426 | p = bp ; | |
| 1427 | ||
| 1428 | if (pr oxy) { | |
| 1429 | if (ctxt->po rt != 80) { | |
| 1430 | p += snp rintf( p, blen - (p - bp), "%s http://%s :%d%s", | |
| 1431 | method , ctxt->ho stname, | |
| 1432 | ctxt-> port, ctxt ->path ); | |
| 1433 | } | |
| 1434 | el se | |
| 1435 | p += snp rintf( p, blen - (p - bp), "%s http://%s %s", metho d, | |
| 1436 | ctxt-> hostname, ctxt->path ); | |
| 1437 | } | |
| 1438 | else | |
| 1439 | p += snprint f( p, blen - (p - bp ), "%s %s" , method, ctxt->path ); | |
| 1440 | ||
| 1441 | if (ct xt->query != NULL) | |
| 1442 | p += snprint f( p, blen - (p - bp ), "?%s", ctxt->quer y); | |
| 1443 | ||
| 1444 | if (ct xt->port = = 80) { | |
| 1445 | p += snprint f( p, blen - (p - bp ), " HTTP/ 1.0\r\nHos t: %s\r\n" , | |
| 1446 | ctxt->host name); | |
| 1447 | } else { | |
| 1448 | p += snprint f( p, blen - (p - bp ), " HTTP/ 1.0\r\nHos t: %s:%d\r \n", | |
| 1449 | ctxt->host name, ctxt ->port); | |
| 1450 | } | |
| 1451 | ||
| 1452 | #ifdef HAV E_ZLIB_H | |
| 1453 | p += s nprintf(p, blen - (p - bp), "A ccept-Enco ding: gzip \r\n"); | |
| 1454 | #endif | |
| 1455 | ||
| 1456 | if (co ntentType != NULL && *contentT ype) | |
| 1457 | p += snprint f(p, blen - (p - bp) , "Content -Type: %s\ r\n", *con tentType); | |
| 1458 | ||
| 1459 | if (he aders != N ULL) | |
| 1460 | p += snprint f( p, blen - (p - bp ), "%s", h eaders ); | |
| 1461 | ||
| 1462 | if (in put != NUL L) | |
| 1463 | sn printf(p, blen - (p - bp), "Co ntent-Leng th: %d\r\n \r\n", ile n ); | |
| 1464 | else | |
| 1465 | sn printf(p, blen - (p - bp), "\r \n"); | |
| 1466 | ||
| 1467 | #ifdef DEB UG_HTTP | |
| 1468 | xmlGen ericError( xmlGeneric ErrorConte xt, | |
| 1469 | "-> %s%s ", proxy? "(Proxy) " : "", bp) ; | |
| 1470 | if ((b len -= str len(bp)+1) < 0) | |
| 1471 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 1472 | "ERR OR: overfl owed buffe r by %d by tes\n", -b len); | |
| 1473 | #endif | |
| 1474 | ctxt-> outptr = c txt->out = bp; | |
| 1475 | ctxt-> state = XM L_NANO_HTT P_WRITE; | |
| 1476 | blen = strlen( c txt->out ) ; | |
| 1477 | #ifdef DEB UG_HTTP | |
| 1478 | xmt_by tes = xmlN anoHTTPSen d(ctxt, ct xt->out, b len ); | |
| 1479 | if ( x mt_bytes ! = blen ) | |
| 1480 | xm lGenericEr ror( xmlGe nericError Context, | |
| 1481 | "xmlNa noHTTPMeth odRedir: Only %d of %d %s %s\ n", | |
| 1482 | xmt_by tes, blen, | |
| 1483 | "bytes of HTTP h eaders sen t to host" , | |
| 1484 | ctxt-> hostname ) ; | |
| 1485 | #else | |
| 1486 | xmlNan oHTTPSend( ctxt, ctxt ->out, ble n ); | |
| 1487 | #endif | |
| 1488 | ||
| 1489 | if ( i nput != NU LL ) { | |
| 1490 | #ifdef DEB UG_HTTP | |
| 1491 | xm t_bytes = xmlNanoHTT PSend( ctx t, input, ilen ); | |
| 1492 | ||
| 1493 | if ( xmt_byt es != ilen ) | |
| 1494 | xmlGener icError( x mlGenericE rrorContex t, | |
| 1495 | "xmlNa noHTTPMeth odRedir: Only %d of %d %s %s\ n", | |
| 1496 | xmt_by tes, ilen, | |
| 1497 | "bytes of HTTP c ontent sen t to host" , | |
| 1498 | ctxt-> hostname ) ; | |
| 1499 | #else | |
| 1500 | xm lNanoHTTPS end( ctxt, input, il en ); | |
| 1501 | #endif | |
| 1502 | } | |
| 1503 | ||
| 1504 | ctxt-> state = XM L_NANO_HTT P_READ; | |
| 1505 | ||
| 1506 | while ((p = xmlN anoHTTPRea dLine(ctxt )) != NULL ) { | |
| 1507 | if (*p == 0) { | |
| 1508 | ctxt->co ntent = ct xt->inrptr ; | |
| 1509 | xmlFree( p); | |
| 1510 | break; | |
| 1511 | } | |
| 1512 | xm lNanoHTTPS canAnswer( ctxt, p); | |
| 1513 | ||
| 1514 | #ifdef DEB UG_HTTP | |
| 1515 | xm lGenericEr ror(xmlGen ericErrorC ontext, "< - %s\n", p ); | |
| 1516 | #endif | |
| 1517 | xm lFree(p); | |
| 1518 | } | |
| 1519 | ||
| 1520 | if ((c txt->locat ion != NUL L) && (ctx t->returnV alue >= 30 0) && | |
| 1521 | (c txt->retur nValue < 4 00)) { | |
| 1522 | #ifdef DEB UG_HTTP | |
| 1523 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 1524 | "\nR edirect to : %s\n", c txt->locat ion); | |
| 1525 | #endif | |
| 1526 | wh ile ( xmlN anoHTTPRec v(ctxt) > 0 ) ; | |
| 1527 | if (nbRedire cts < XML_ NANO_HTTP_ MAX_REDIR) { | |
| 1528 | nbRedire cts++; | |
| 1529 | if (redi rURL != NU LL) | |
| 1530 | xmlF ree(redirU RL); | |
| 1531 | redirURL = xmlMemS trdup(ctxt ->location ); | |
| 1532 | xmlNanoH TTPFreeCtx t(ctxt); | |
| 1533 | goto ret ry; | |
| 1534 | } | |
| 1535 | xm lNanoHTTPF reeCtxt(ct xt); | |
| 1536 | if (redirURL != NULL) xmlFree(re dirURL); | |
| 1537 | #ifdef DEB UG_HTTP | |
| 1538 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 1539 | "xml NanoHTTPMe thodRedir: Too many redirects, aborting ...\n"); | |
| 1540 | #endif | |
| 1541 | re turn(NULL) ; | |
| 1542 | } | |
| 1543 | ||
| 1544 | if (co ntentType != NULL) { | |
| 1545 | if (ctxt->co ntentType != NULL) | |
| 1546 | *content Type = xml MemStrdup( ctxt->cont entType); | |
| 1547 | el se | |
| 1548 | *content Type = NUL L; | |
| 1549 | } | |
| 1550 | ||
| 1551 | if ((r edir != NU LL) && (re dirURL != NULL)) { | |
| 1552 | *r edir = red irURL; | |
| 1553 | } else { | |
| 1554 | if (redirURL != NULL) | |
| 1555 | xmlFree( redirURL); | |
| 1556 | if (redir != NULL) | |
| 1557 | *redir = NULL; | |
| 1558 | } | |
| 1559 | ||
| 1560 | #ifdef DEB UG_HTTP | |
| 1561 | if (ct xt->conten tType != N ULL) | |
| 1562 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 1563 | "\nC ode %d, co ntent-type '%s'\n\n" , | |
| 1564 | ctxt- >returnVal ue, ctxt-> contentTyp e); | |
| 1565 | else | |
| 1566 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 1567 | "\nC ode %d, no content-t ype\n\n", | |
| 1568 | ctxt- >returnVal ue); | |
| 1569 | #endif | |
| 1570 | ||
| 1571 | return ((void *) ctxt); | |
| 1572 | } | |
| 1573 | ||
| 1574 | /** | |
| 1575 | * xmlNano HTTPMethod : | |
| 1576 | * @URL: The URL to load | |
| 1577 | * @method : the HTT P method t o use | |
| 1578 | * @input: the inpu t string i f any | |
| 1579 | * @conten tType: th e Content- Type infor mation IN and OUT | |
| 1580 | * @header s: the ex tra header s | |
| 1581 | * @ilen: input len gth | |
| 1582 | * | |
| 1583 | * This fu nction try to open a connectio n to the i ndicated r esource | |
| 1584 | * via HTT P using th e given @m ethod, add ing the gi ven extra headers | |
| 1585 | * and the input buf fer for th e request content. | |
| 1586 | * | |
| 1587 | * Returns NULL in c ase of fai lure, othe rwise a re quest hand ler. | |
| 1588 | * The contentTy pe, if pro vided must be freed by the cal ler | |
| 1589 | */ | |
| 1590 | ||
| 1591 | void* | |
| 1592 | xmlNanoHTT PMethod(co nst char * URL, const char *met hod, const char *inp ut, | |
| 1593 | ch ar **conte ntType, co nst char * headers, i nt ilen) { | |
| 1594 | return (xmlNanoHT TPMethodRe dir(URL, m ethod, inp ut, conten tType, | |
| 1595 | NULL, headers, i len)); | |
| 1596 | } | |
| 1597 | ||
| 1598 | /** | |
| 1599 | * xmlNano HTTPFetch: | |
| 1600 | * @URL: The URL to load | |
| 1601 | * @filena me: the f ilename wh ere the co ntent shou ld be save d | |
| 1602 | * @conten tType: if available the Conte nt-Type in formation will be | |
| 1603 | * re turned at that locat ion | |
| 1604 | * | |
| 1605 | * This fu nction try to fetch the indica ted resour ce via HTT P GET | |
| 1606 | * and sav e it's con tent in th e file. | |
| 1607 | * | |
| 1608 | * Returns -1 in cas e of failu re, 0 inca se of succ ess. The c ontentType , | |
| 1609 | * if provided m ust be fre ed by the caller | |
| 1610 | */ | |
| 1611 | int | |
| 1612 | xmlNanoHTT PFetch(con st char *U RL, const char *file name, char **content Type) { | |
| 1613 | void * ctxt = NUL L; | |
| 1614 | char * buf = NULL ; | |
| 1615 | int fd ; | |
| 1616 | int le n; | |
| 1617 | int re t = 0; | |
| 1618 | ||
| 1619 | if (fi lename == NULL) retu rn(-1); | |
| 1620 | ctxt = xmlNanoHT TPOpen(URL , contentT ype); | |
| 1621 | if (ct xt == NULL ) return(- 1); | |
| 1622 | ||
| 1623 | if (!s trcmp(file name, "-") ) | |
| 1624 | fd = 0; | |
| 1625 | else { | |
| 1626 | fd = open(fi lename, O_ CREAT | O_ WRONLY, 00 644); | |
| 1627 | if (fd < 0) { | |
| 1628 | xmlNanoH TTPClose(c txt); | |
| 1629 | if ((con tentType ! = NULL) && (*content Type != NU LL)) { | |
| 1630 | xmlF ree(*conte ntType); | |
| 1631 | *con tentType = NULL; | |
| 1632 | } | |
| 1633 | return(- 1); | |
| 1634 | } | |
| 1635 | } | |
| 1636 | ||
| 1637 | xmlNan oHTTPFetch Content( c txt, &buf, &len ); | |
| 1638 | if ( l en > 0 ) { | |
| 1639 | if (write(fd , buf, len ) == -1) { | |
| 1640 | ret = -1 ; | |
| 1641 | } | |
| 1642 | } | |
| 1643 | ||
| 1644 | xmlNan oHTTPClose (ctxt); | |
| 1645 | close( fd); | |
| 1646 | return (ret); | |
| 1647 | } | |
| 1648 | ||
| 1649 | #ifdef LIB XML_OUTPUT _ENABLED | |
| 1650 | /** | |
| 1651 | * xmlNano HTTPSave: | |
| 1652 | * @ctxt: the HTTP context | |
| 1653 | * @filena me: the f ilename wh ere the co ntent shou ld be save d | |
| 1654 | * | |
| 1655 | * This fu nction sav es the out put of the HTTP tran saction to a file | |
| 1656 | * It clos es and fre e the cont ext at the end | |
| 1657 | * | |
| 1658 | * Returns -1 in cas e of failu re, 0 inca se of succ ess. | |
| 1659 | */ | |
| 1660 | int | |
| 1661 | xmlNanoHTT PSave(void *ctxt, co nst char * filename) { | |
| 1662 | char * buf = NULL ; | |
| 1663 | int fd ; | |
| 1664 | int le n; | |
| 1665 | int re t = 0; | |
| 1666 | ||
| 1667 | if ((c txt == NUL L) || (fil ename == N ULL)) retu rn(-1); | |
| 1668 | ||
| 1669 | if (!s trcmp(file name, "-") ) | |
| 1670 | fd = 0; | |
| 1671 | else { | |
| 1672 | fd = open(fi lename, O_ CREAT | O_ WRONLY, 06 66); | |
| 1673 | if (fd < 0) { | |
| 1674 | xmlNanoH TTPClose(c txt); | |
| 1675 | return(- 1); | |
| 1676 | } | |
| 1677 | } | |
| 1678 | ||
| 1679 | xmlNan oHTTPFetch Content( c txt, &buf, &len ); | |
| 1680 | if ( l en > 0 ) { | |
| 1681 | if (write(fd , buf, len ) == -1) { | |
| 1682 | ret = -1 ; | |
| 1683 | } | |
| 1684 | } | |
| 1685 | ||
| 1686 | xmlNan oHTTPClose (ctxt); | |
| 1687 | close( fd); | |
| 1688 | return (ret); | |
| 1689 | } | |
| 1690 | #endif /* LIBXML_OUT PUT_ENABLE D */ | |
| 1691 | ||
| 1692 | /** | |
| 1693 | * xmlNano HTTPReturn Code: | |
| 1694 | * @ctx: the HTTP c ontext | |
| 1695 | * | |
| 1696 | * Get the latest HT TP return code recei ved | |
| 1697 | * | |
| 1698 | * Returns the HTTP return cod e for the request. | |
| 1699 | */ | |
| 1700 | int | |
| 1701 | xmlNanoHTT PReturnCod e(void *ct x) { | |
| 1702 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoHT TPCtxtPtr) ctx; | |
| 1703 | ||
| 1704 | if (ct xt == NULL ) return(- 1); | |
| 1705 | ||
| 1706 | return (ctxt->ret urnValue); | |
| 1707 | } | |
| 1708 | ||
| 1709 | /** | |
| 1710 | * xmlNano HTTPAuthHe ader: | |
| 1711 | * @ctx: the HTTP c ontext | |
| 1712 | * | |
| 1713 | * Get the authentic ation head er of an H TTP contex t | |
| 1714 | * | |
| 1715 | * Returns the stash ed value o f the WWW- Authentica te or Prox y-Authenti cate | |
| 1716 | * header. | |
| 1717 | */ | |
| 1718 | const char * | |
| 1719 | xmlNanoHTT PAuthHeade r(void *ct x) { | |
| 1720 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoHT TPCtxtPtr) ctx; | |
| 1721 | ||
| 1722 | if (ct xt == NULL ) return(N ULL); | |
| 1723 | ||
| 1724 | return (ctxt->aut hHeader); | |
| 1725 | } | |
| 1726 | ||
| 1727 | /** | |
| 1728 | * xmlNano HTTPConten tLength: | |
| 1729 | * @ctx: the HTTP c ontext | |
| 1730 | * | |
| 1731 | * Provide s the spec ified cont ent length from the HTTP heade r. | |
| 1732 | * | |
| 1733 | * Return the specif ied conten t length f rom the HT TP header. Note tha t | |
| 1734 | * a value of -1 ind icates tha t the cont ent length element w as not inc luded in | |
| 1735 | * the res ponse head er. | |
| 1736 | */ | |
| 1737 | int | |
| 1738 | xmlNanoHTT PContentLe ngth( void * ctx ) { | |
| 1739 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoH TTPCtxtPtr )ctx; | |
| 1740 | ||
| 1741 | return ( ( ctxt == NULL ) ? -1 : ctx t->Content Length ); | |
| 1742 | } | |
| 1743 | ||
| 1744 | /** | |
| 1745 | * xmlNano HTTPRedir: | |
| 1746 | * @ctx: the HTTP c ontext | |
| 1747 | * | |
| 1748 | * Provide s the spec ified redi rection UR L if avail able from the HTTP h eader. | |
| 1749 | * | |
| 1750 | * Return the specif ied redire ction URL or NULL if not redir ected. | |
| 1751 | */ | |
| 1752 | const char * | |
| 1753 | xmlNanoHTT PRedir( vo id * ctx ) { | |
| 1754 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoH TTPCtxtPtr )ctx; | |
| 1755 | ||
| 1756 | return ( ( ctxt == NULL ) ? NULL : c txt->locat ion ); | |
| 1757 | } | |
| 1758 | ||
| 1759 | /** | |
| 1760 | * xmlNano HTTPEncodi ng: | |
| 1761 | * @ctx: the HTTP c ontext | |
| 1762 | * | |
| 1763 | * Provide s the spec ified enco ding if sp ecified in the HTTP headers. | |
| 1764 | * | |
| 1765 | * Return the specif ied encodi ng or NULL if not av ailable | |
| 1766 | */ | |
| 1767 | const char * | |
| 1768 | xmlNanoHTT PEncoding( void * ct x ) { | |
| 1769 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoH TTPCtxtPtr )ctx; | |
| 1770 | ||
| 1771 | return ( ( ctxt == NULL ) ? NULL : c txt->encod ing ); | |
| 1772 | } | |
| 1773 | ||
| 1774 | /** | |
| 1775 | * xmlNano HTTPMimeTy pe: | |
| 1776 | * @ctx: the HTTP c ontext | |
| 1777 | * | |
| 1778 | * Provide s the spec ified Mime -Type if s pecified i n the HTTP headers. | |
| 1779 | * | |
| 1780 | * Return the specif ied Mime-T ype or NUL L if not a vailable | |
| 1781 | */ | |
| 1782 | const char * | |
| 1783 | xmlNanoHTT PMimeType( void * ct x ) { | |
| 1784 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoH TTPCtxtPtr )ctx; | |
| 1785 | ||
| 1786 | return ( ( ctxt == NULL ) ? NULL : c txt->mimeT ype ); | |
| 1787 | } | |
| 1788 | ||
| 1789 | /** | |
| 1790 | * xmlNano HTTPFetchC ontent: | |
| 1791 | * @ctx: the HTTP c ontext | |
| 1792 | * @ptr: pointer to set to th e content buffer. | |
| 1793 | * @len: integer po inter to h old the le ngth of th e content | |
| 1794 | * | |
| 1795 | * Check i f all the content wa s read | |
| 1796 | * | |
| 1797 | * Returns 0 if all the conten t was read and avail able, retu rns | |
| 1798 | * -1 if r eceived co ntent leng th was les s than spe cified or an error | |
| 1799 | * occurre d. | |
| 1800 | */ | |
| 1801 | static int | |
| 1802 | xmlNanoHTT PFetchCont ent( void * ctx, cha r ** ptr, int * len ) { | |
| 1803 | xmlNan oHTTPCtxtP tr ctxt = (xmlNanoH TTPCtxtPtr )ctx; | |
| 1804 | ||
| 1805 | int rc = 0 ; | |
| 1806 | int cur_lg th; | |
| 1807 | int rcvd_l gth; | |
| 1808 | int dummy_ int; | |
| 1809 | char * dummy_ ptr = NULL ; | |
| 1810 | ||
| 1811 | /* Du mmy up ret urn input parameters if not pr ovided */ | |
| 1812 | ||
| 1813 | if ( l en == NULL ) | |
| 1814 | le n = &dummy _int; | |
| 1815 | ||
| 1816 | if ( p tr == NULL ) | |
| 1817 | pt r = &dummy _ptr; | |
| 1818 | ||
| 1819 | /* Bu t can't wo rk without the conte xt pointer */ | |
| 1820 | ||
| 1821 | if ( ( ctxt == N ULL ) || ( ctxt->con tent == NU LL ) ) { | |
| 1822 | *l en = 0; | |
| 1823 | *p tr = NULL; | |
| 1824 | re turn ( -1 ); | |
| 1825 | } | |
| 1826 | ||
| 1827 | rcvd_l gth = ctxt ->inptr - ctxt->cont ent; | |
| 1828 | ||
| 1829 | while ( (cur_lgt h = xmlNan oHTTPRecv( ctxt )) > 0 ) { | |
| 1830 | ||
| 1831 | rc vd_lgth += cur_lgth; | |
| 1832 | if ( (ctxt-> ContentLen gth > 0) & & (rcvd_lg th >= ctxt ->ContentL ength) ) | |
| 1833 | break; | |
| 1834 | } | |
| 1835 | ||
| 1836 | *ptr = ctxt->con tent; | |
| 1837 | *len = rcvd_lgth ; | |
| 1838 | ||
| 1839 | if ( ( ctxt->Con tentLength > 0 ) && ( rcvd_lgt h < ctxt-> ContentLen gth ) ) | |
| 1840 | rc = -1; | |
| 1841 | else i f ( rcvd_l gth == 0 ) | |
| 1842 | rc = -1; | |
| 1843 | ||
| 1844 | return ( rc ); | |
| 1845 | } | |
| 1846 | ||
| 1847 | #ifdef STA NDALONE | |
| 1848 | int main(i nt argc, c har **argv ) { | |
| 1849 | char * contentTyp e = NULL; | |
| 1850 | ||
| 1851 | if (ar gv[1] != N ULL) { | |
| 1852 | if (argv[2] != NULL) | |
| 1853 | xmlNanoH TTPFetch(a rgv[1], ar gv[2], &co ntentType) ; | |
| 1854 | el se | |
| 1855 | xmlNanoH TTPFetch(a rgv[1], "- ", &conten tType); | |
| 1856 | if (contentT ype != NUL L) xmlFree (contentTy pe); | |
| 1857 | } else { | |
| 1858 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 1859 | "%s: minimal H TTP GET im plementati on\n", arg v[0]); | |
| 1860 | xm lGenericEr ror(xmlGen ericErrorC ontext, | |
| 1861 | "\tu sage %s [ URL [ file name ] ]\n ", argv[0] ); | |
| 1862 | } | |
| 1863 | xmlNan oHTTPClean up(); | |
| 1864 | xmlMem oryDump(); | |
| 1865 | return (0); | |
| 1866 | } | |
| 1867 | #endif /* STANDALONE */ | |
| 1868 | #else /* ! LIBXML_HTT P_ENABLED */ | |
| 1869 | #ifdef STA NDALONE | |
| 1870 | #include < stdio.h> | |
| 1871 | int main(i nt argc, c har **argv ) { | |
| 1872 | xmlGen ericError( xmlGeneric ErrorConte xt, | |
| 1873 | "%s : HT TP support not compi led in\n", argv[0]); | |
| 1874 | return (0); | |
| 1875 | } | |
| 1876 | #endif /* STANDALONE */ | |
| 1877 | #endif /* LIBXML_HTT P_ENABLED */ | |
| 1878 | #define bo ttom_nanoh ttp | |
| 1879 | #include " elfgcchack .h" |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.