13473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 23473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * nanohttp.c: minimalist HTTP GET implementation to fetch external subsets. 33473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * focuses on size, streamability, reentrancy and portability 43473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This is clearly not a general purpose HTTP implementation 63473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If you look for one, check: 73473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * http://www.w3.org/Library/ 83473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 93473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * See Copyright for the status of this software. 103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 11c5d64345cf19bfd72418eb0a837869b0462e9130Daniel Veillard * daniel@veillard.com 123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 14f3afa7dd4e8daacfa62f7345b7d7071e0cb33423Daniel Veillard#define NEED_SOCKETS 1534ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#define IN_LIBXML 1670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "libxml.h" 173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_HTTP_ENABLED 193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <string.h> 203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_STDLIB_H 223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <stdlib.h> 233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_UNISTD_H 253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <unistd.h> 263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 2775eb1adc04eb72a061d5b37bc0c73f4d92400d57Daniel Veillard#ifdef HAVE_SYS_TYPES_H 2875eb1adc04eb72a061d5b37bc0c73f4d92400d57Daniel Veillard#include <sys/types.h> 2975eb1adc04eb72a061d5b37bc0c73f4d92400d57Daniel Veillard#endif 303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_SOCKET_H 313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/socket.h> 323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_NETINET_IN_H 343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <netinet/in.h> 353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_ARPA_INET_H 373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <arpa/inet.h> 383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_NETDB_H 403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <netdb.h> 413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 42d85f4f437c9d54a658b229a77426e693bd328787Daniel Veillard#ifdef HAVE_RESOLV_H 439b731d709ee99b59b815d51ad80ebba409f0f20dDaniel Veillard#ifdef HAVE_ARPA_NAMESER_H 449b731d709ee99b59b815d51ad80ebba409f0f20dDaniel Veillard#include <arpa/nameser.h> 459b731d709ee99b59b815d51ad80ebba409f0f20dDaniel Veillard#endif 46d85f4f437c9d54a658b229a77426e693bd328787Daniel Veillard#include <resolv.h> 47d85f4f437c9d54a658b229a77426e693bd328787Daniel Veillard#endif 483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_FCNTL_H 49f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#include <fcntl.h> 503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_ERRNO_H 523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <errno.h> 533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_TIME_H 553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/time.h> 563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 5748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifndef HAVE_POLL_H 583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_SELECT_H 593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/select.h> 603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 6148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#else 6248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#include <poll.h> 6348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif 643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_STRINGS_H 653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <strings.h> 663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 679a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#ifdef HAVE_ZLIB_H 689a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#include <zlib.h> 699a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#endif 709a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef VMS 733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <stropts> 74c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard#define XML_SOCKLEN_T unsigned int 753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7759d3ed8fe0ae9e8f453501d0993f2bc2f3f34ae8Daniel Veillard#if defined(__MINGW32__) || defined(_WIN32_WCE) 78f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer#ifndef _WINSOCKAPI_ 791638a47a884b089825e26459081e137483b7d454Daniel Veillard#define _WINSOCKAPI_ 80f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer#endif 811638a47a884b089825e26459081e137483b7d454Daniel Veillard#include <wsockcompat.h> 821638a47a884b089825e26459081e137483b7d454Daniel Veillard#include <winsock2.h> 83c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard#undef XML_SOCKLEN_T 84c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard#define XML_SOCKLEN_T unsigned int 851638a47a884b089825e26459081e137483b7d454Daniel Veillard#endif 861638a47a884b089825e26459081e137483b7d454Daniel Veillard 87d0463560300f1d8b3e41d70c3728ed84fdc8dd30Daniel Veillard#include <libxml/globals.h> 88f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#include <libxml/xmlerror.h> 893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h> 903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/parser.h> /* for xmlStr(n)casecmp() */ 913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/nanohttp.h> 923c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#include <libxml/globals.h> 938efff671578465d3bf122cc0a6811bc3763ee519Daniel Veillard#include <libxml/uri.h> 943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A couple portability macros 973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifndef _WINSOCKAPI_ 99cba68396ac4351a5c4451c483c3343a800d71bebDaniel Veillard#if !defined(__BEOS__) || defined(__HAIKU__) 1003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define closesocket(s) close(s) 101a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif 1023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SOCKET int 103f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer#define INVALID_SOCKET (-1) 1043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10689f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard#ifdef __BEOS__ 10789f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard#ifndef PF_INET 10889f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard#define PF_INET AF_INET 10989f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard#endif 11089f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard#endif 11189f7f27a9b06d1cf8b72557296350b47691493acDaniel Veillard 112c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard#ifndef XML_SOCKLEN_T 113c284c64ff9bb42be244193f959210154a0cfa518Daniel Veillard#define XML_SOCKLEN_T unsigned int 11475be0130855fe02d238bbbf19a04d3c5eb45f494Daniel Veillard#endif 115f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef STANDALONE 1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define DEBUG_HTTP 1183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define xmlStrncasecmp(a, b, n) strncasecmp((char *)a, (char *)b, n) 1193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define xmlStrcasecmpi(a, b) strcasecmp((char *)a, (char *)b) 1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_MAX_REDIR 10 1233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_CHUNK 4096 1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_CLOSED 0 1273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_WRITE 1 1283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_READ 2 1293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_NONE 4 1303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef struct xmlNanoHTTPCtxt { 1323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *protocol; /* the protocol name */ 1333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *hostname; /* the host name */ 1343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int port; /* the port */ 1353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *path; /* the path within the URL */ 136351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard char *query; /* the query string */ 1373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SOCKET fd; /* the file descriptor for the socket */ 1383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int state; /* WRITE / READ / CLOSED */ 1393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *out; /* buffer sent (zero terminated) */ 1403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *outptr; /* index within the buffer sent */ 1413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *in; /* the receiving buffer */ 1423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *content; /* the start of the content */ 1433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *inptr; /* the next byte to read from network */ 1443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *inrptr; /* the next byte to give back to the client */ 1453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int inlen; /* len of the input buffer */ 1463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int last; /* return code for last operation */ 1473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int returnValue; /* the protocol return value */ 14813cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard int version; /* the protocol version */ 149f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int ContentLength; /* specified content length from HTTP header */ 1503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *contentType; /* the MIME type for the input */ 1513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *location; /* the new URL in case of redirect */ 1523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *authHeader; /* contents of {WWW,Proxy}-Authenticate header */ 153847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard char *encoding; /* encoding extracted from the contentType */ 154a840b69261c44760d45370bef989c77f84727406Daniel Veillard char *mimeType; /* Mime-Type extracted from the contentType */ 1559a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#ifdef HAVE_ZLIB_H 1569a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard z_stream *strm; /* Zlib stream object */ 1579a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard int usesGzip; /* "Content-Encoding: gzip" was detected */ 1589a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#endif 1593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} xmlNanoHTTPCtxt, *xmlNanoHTTPCtxtPtr; 1603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int initialized = 0; 1623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic char *proxy = NULL; /* the proxy name if any */ 1633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int proxyPort; /* the proxy port if any */ 1643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic unsigned int timeout = 60;/* the select() timeout in seconds */ 1653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 166a2351322c89608d09ce1a99e5eccd62d00c79890Daniel Veillardstatic int xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ); 167f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1692b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard * xmlHTTPErrMemory: 1702b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard * @extra: extra informations 1712b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard * 1722b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard * Handle an out of memory condition 1732b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard */ 1742b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillardstatic void 1752b0f8799086f2a54444c618ab3ed01a8177491f2Daniel VeillardxmlHTTPErrMemory(const char *extra) 1762b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard{ 1772b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard __xmlSimpleError(XML_FROM_HTTP, XML_ERR_NO_MEMORY, NULL, NULL, extra); 1782b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard} 1792b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard 1802b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard/** 1813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A portability function 1823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 18356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int socket_errno(void) { 1843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 1853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(WSAGetLastError()); 1863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else 1873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(errno); 1883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 191de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard#ifdef SUPPORT_IP6 1922db8c125be777d642fc1143f23a77d8cf0aa4de1Daniel Veillardstatic 1932db8c125be777d642fc1143f23a77d8cf0aa4de1Daniel Veillardint have_ipv6(void) { 194f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer SOCKET s; 195de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 196de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard s = socket (AF_INET6, SOCK_STREAM, 0); 197f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer if (s != INVALID_SOCKET) { 198de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard close (s); 199de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard return (1); 200de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 201de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard return (0); 202de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard} 203de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard#endif 204de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 2053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPInit: 2073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the HTTP protocol layer. 2093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Currently it just checks for proxy informations 2103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 2113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 2133473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPInit(void) { 2143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const char *env; 2153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 216f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard WSADATA wsaData; 2173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 2183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (initialized) 2203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 2213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 2233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) 2243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 2253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 2263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxy == NULL) { 2283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor proxyPort = 80; 2293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor env = getenv("no_proxy"); 23029b1748205897f727696b62fdba333efc9671440Daniel Veillard if (env && ((env[0] == '*') && (env[1] == 0))) 2313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 2323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor env = getenv("http_proxy"); 2333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (env != NULL) { 2343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPScanProxy(env); 2353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 2363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor env = getenv("HTTP_PROXY"); 2383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (env != NULL) { 2393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPScanProxy(env); 2403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 2413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordone: 2443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor initialized = 1; 2453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 2463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2485e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlNanoHTTPCleanup: 2493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the HTTP protocol layer. 2513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 2523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 2543473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPCleanup(void) { 255744acfffe537ed3922c57d28d8ea304ee9403942Daniel Veillard if (proxy != NULL) { 2563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(proxy); 257744acfffe537ed3922c57d28d8ea304ee9403942Daniel Veillard proxy = NULL; 258744acfffe537ed3922c57d28d8ea304ee9403942Daniel Veillard } 2593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 2603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (initialized) 2613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor WSACleanup(); 2623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 2633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor initialized = 0; 2643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 2653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 2663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPScanURL: 2693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 2703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL used to initialize the context 2713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (Re)Initialize an HTTP context by parsing the URL and finding 2733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the protocol host port and path it indicates. 2743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 2753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic void 2773473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) { 278015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack xmlURIPtr uri; 27919d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf int len; 28019d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf 281015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack /* 282015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack * Clear any existing data from the context 283015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack */ 284f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt->protocol != NULL) { 2853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->protocol); 2863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->protocol = NULL; 2873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 288f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt->hostname != NULL) { 2893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->hostname); 2903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->hostname = NULL; 2913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 292f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt->path != NULL) { 2933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->path); 2943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->path = NULL; 2953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 296f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt->query != NULL) { 297351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard xmlFree(ctxt->query); 298351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard ctxt->query = NULL; 299351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard } 3003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (URL == NULL) return; 301de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 302336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard uri = xmlParseURIRaw(URL, 1); 303015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if (uri == NULL) 304015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack return; 305de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 306015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if ((uri->scheme == NULL) || (uri->server == NULL)) { 307015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack xmlFreeURI(uri); 308015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack return; 3093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 310f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 311015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack ctxt->protocol = xmlMemStrdup(uri->scheme); 31219d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf /* special case of IPv6 addresses, the [] need to be removed */ 31319d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf if ((uri->server != NULL) && (*uri->server == '[')) { 31419d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf len = strlen(uri->server); 31519d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf if ((len > 2) && (uri->server[len - 1] == ']')) { 31619d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf ctxt->hostname = (char *) xmlCharStrndup(uri->server + 1, len -2); 31719d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf } else 31819d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf ctxt->hostname = xmlMemStrdup(uri->server); 31919d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf } else 32019d785b5c76fcd9d7bc2c8d678b05ed83b02f91dSteve Wolf ctxt->hostname = xmlMemStrdup(uri->server); 321015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if (uri->path != NULL) 322015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack ctxt->path = xmlMemStrdup(uri->path); 323015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack else 324015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack ctxt->path = xmlMemStrdup("/"); 325351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard if (uri->query != NULL) 326351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard ctxt->query = xmlMemStrdup(uri->query); 327015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if (uri->port != 0) 328015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack ctxt->port = uri->port; 329015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack 330015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack xmlFreeURI(uri); 3313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 3323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPScanProxy: 3353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The proxy URL used to initialize the proxy context 3363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (Re)Initialize the HTTP Proxy context by parsing the URL and finding 3383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the protocol host port it indicates. 3393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Should be like http://myproxy/ or http://myproxy:3128/ 3403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A NULL URL cleans up proxy informations. 3413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 3423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 3443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPScanProxy(const char *URL) { 345015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack xmlURIPtr uri; 3463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 347f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (proxy != NULL) { 3483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(proxy); 3493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor proxy = NULL; 3503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 351015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack proxyPort = 0; 352015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack 3533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 3543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (URL == NULL) 3553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 3563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Removing HTTP proxy info\n"); 3573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 3583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 3593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Using HTTP proxy %s\n", URL); 3603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 3613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (URL == NULL) return; 362de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 363336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard uri = xmlParseURIRaw(URL, 1); 364015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if ((uri == NULL) || (uri->scheme == NULL) || 365015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack (strcmp(uri->scheme, "http")) || (uri->server == NULL)) { 366015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Syntax Error\n"); 367015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if (uri != NULL) 368015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack xmlFreeURI(uri); 369015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack return; 3703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 371f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 372015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack proxy = xmlMemStrdup(uri->server); 373015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if (uri->port != 0) 374015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack proxyPort = uri->port; 375015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack 376015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack xmlFreeURI(uri); 3773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 3783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPNewCtxt: 3813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL used to initialize the context 3823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Allocate and initialize a new HTTP context. 3843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns an HTTP context or NULL in case of error. 3863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 3873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic xmlNanoHTTPCtxtPtr 3893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPNewCtxt(const char *URL) { 3903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ret; 3913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt)); 3932b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard if (ret == NULL) { 3942b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard xmlHTTPErrMemory("allocating context"); 3952b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard return(NULL); 3962b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard } 3973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0, sizeof(xmlNanoHTTPCtxt)); 3993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->port = 80; 4003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->returnValue = 0; 401f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer ret->fd = INVALID_SOCKET; 402f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ret->ContentLength = -1; 4033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 404cacbe5d110d469463edb0dd8e11e493daaf3dbc4Daniel Veillard xmlNanoHTTPScanURL(ret, URL); 4053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 4073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 4083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 4103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPFreeCtxt: 4113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 4123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Frees the context after closing the connection. 4143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 4153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic void 4173473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) { 4183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return; 4193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->hostname != NULL) xmlFree(ctxt->hostname); 4203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->protocol != NULL) xmlFree(ctxt->protocol); 4213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->path != NULL) xmlFree(ctxt->path); 422351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard if (ctxt->query != NULL) xmlFree(ctxt->query); 4233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->out != NULL) xmlFree(ctxt->out); 4243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->in != NULL) xmlFree(ctxt->in); 4253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) xmlFree(ctxt->contentType); 426847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard if (ctxt->encoding != NULL) xmlFree(ctxt->encoding); 427a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (ctxt->mimeType != NULL) xmlFree(ctxt->mimeType); 4283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->location != NULL) xmlFree(ctxt->location); 4293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader); 4309a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#ifdef HAVE_ZLIB_H 4319a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard if (ctxt->strm != NULL) { 4329a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard inflateEnd(ctxt->strm); 4339a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard xmlFree(ctxt->strm); 4349a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard } 4359a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#endif 4369a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 4373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->state = XML_NANO_HTTP_NONE; 438f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer if (ctxt->fd != INVALID_SOCKET) closesocket(ctxt->fd); 439f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer ctxt->fd = INVALID_SOCKET; 4403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 4413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 4423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 4443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPSend: 4453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 4463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Send the input needed to initiate the processing on the server side 448f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * Returns number of bytes sent or -1 on error. 4493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 4503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 451f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillardstatic int 45248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael PrevostxmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char *xmt_ptr, int outlen) 45348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost{ 45448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost int total_sent = 0; 45548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifdef HAVE_POLL_H 45648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost struct pollfd p; 45748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#else 45848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost struct timeval tv; 45948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost fd_set wfd; 46048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif 461f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 46248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if ((ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL)) { 463f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard while (total_sent < outlen) { 464437f4f5977f023bbaa7e2da781ca233d5c108954Patrick Monnerat int nsent = send(ctxt->fd, SEND_ARG2_CAST (xmt_ptr + total_sent), 46548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost outlen - total_sent, 0); 46648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 46748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (nsent > 0) 4683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor total_sent += nsent; 46948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost else if ((nsent == -1) && 470ba6db03c40b3ac223695fe08e96744ab389c6dabDaniel Veillard#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK 47148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost (socket_errno() != EAGAIN) && 472ba6db03c40b3ac223695fe08e96744ab389c6dabDaniel Veillard#endif 47348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost (socket_errno() != EWOULDBLOCK)) { 47448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, "send failed\n"); 47548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (total_sent == 0) 47648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost total_sent = -1; 47748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost break; 47848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } else { 47948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost /* 48048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost * No data sent 48148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost * Since non-blocking sockets are used, wait for 48248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost * socket to be writable or default timeout prior 48348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost * to retrying. 48448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost */ 48548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifndef HAVE_POLL_H 486d29a5c8a5c42753653762763955510577c2c955dspadix#ifndef _WINSOCKAPI_ 48748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->fd > FD_SETSIZE) 48848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return -1; 489d29a5c8a5c42753653762763955510577c2c955dspadix#endif 49048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 49148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost tv.tv_sec = timeout; 49248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost tv.tv_usec = 0; 49348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost FD_ZERO(&wfd); 4949e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#ifdef _MSC_VER 4959e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(push) 4969e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(disable: 4018) 4979e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#endif 49848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost FD_SET(ctxt->fd, &wfd); 4999e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#ifdef _MSC_VER 5009e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(pop) 5019e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#endif 50248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost (void) select(ctxt->fd + 1, NULL, &wfd, NULL, &tv); 50348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#else 50448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost p.fd = ctxt->fd; 50548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost p.events = POLLOUT; 50648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost (void) poll(&p, 1, timeout * 1000); 50748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif /* !HAVE_POLL_H */ 50848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 50948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 5103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 511f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 512f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return total_sent; 5133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 5143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 5163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPRecv: 5173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 5183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Read information coming from the HTTP connection. 5203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This is a blocking call (but it blocks in select(), not read()). 5213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the number of byte read or -1 in case of error. 5233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 5243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int 52648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael PrevostxmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) 52748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost{ 52848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifdef HAVE_POLL_H 52948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost struct pollfd p; 53048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#else 5313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd_set rfd; 5323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct timeval tv; 53348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif 5343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (ctxt->state & XML_NANO_HTTP_READ) { 53748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->in == NULL) { 53848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char)); 53948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->in == NULL) { 54048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost xmlHTTPErrMemory("allocating input"); 54148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->last = -1; 54248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (-1); 54348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 54448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->inlen = 65000; 54548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in; 54648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 54748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) { 54848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost int delta = ctxt->inrptr - ctxt->in; 54948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost int len = ctxt->inptr - ctxt->inrptr; 55048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 55148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost memmove(ctxt->in, ctxt->inrptr, len); 55248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->inrptr -= delta; 55348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->content -= delta; 55448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->inptr -= delta; 55548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 5563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) { 55748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost int d_inptr = ctxt->inptr - ctxt->in; 55848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost int d_content = ctxt->content - ctxt->in; 55948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost int d_inrptr = ctxt->inrptr - ctxt->in; 56048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost char *tmp_ptr = ctxt->in; 5613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 56248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->inlen *= 2; 563f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen); 56448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->in == NULL) { 56548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost xmlHTTPErrMemory("allocating input buffer"); 56648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost xmlFree(tmp_ptr); 56748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->last = -1; 56848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (-1); 56948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 5703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inptr = ctxt->in + d_inptr; 5713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->content = ctxt->in + d_content; 5723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inrptr = ctxt->in + d_inrptr; 57348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 57448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0); 57548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->last > 0) { 57648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ctxt->inptr += ctxt->last; 57748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (ctxt->last); 57848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 57948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->last == 0) { 58048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (0); 58148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 58248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->last == -1) { 58348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost switch (socket_errno()) { 58448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case EINPROGRESS: 58548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case EWOULDBLOCK: 5863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK 58748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case EAGAIN: 5883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 58948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost break; 59048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 59148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case ECONNRESET: 59248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case ESHUTDOWN: 59348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (0); 59448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 59548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost default: 59648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n"); 59748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (-1); 59848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 59948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 60048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifdef HAVE_POLL_H 60148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost p.fd = ctxt->fd; 60248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost p.events = POLLIN; 60348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if ((poll(&p, 1, timeout * 1000) < 1) 60448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#if defined(EINTR) 60548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost && (errno != EINTR) 60648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif 60748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ) 60848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (0); 60948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#else /* !HAVE_POLL_H */ 610d29a5c8a5c42753653762763955510577c2c955dspadix#ifndef _WINSOCKAPI_ 61148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (ctxt->fd > FD_SETSIZE) 61248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return 0; 613d29a5c8a5c42753653762763955510577c2c955dspadix#endif 614f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 61548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost tv.tv_sec = timeout; 61648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost tv.tv_usec = 0; 61748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost FD_ZERO(&rfd); 618f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 6199e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#ifdef _MSC_VER 6209e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(push) 6219e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(disable: 4018) 6229e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#endif 62348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 62448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost FD_SET(ctxt->fd, &rfd); 62548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 6269e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#ifdef _MSC_VER 6279e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(pop) 6289e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#endif 62948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 63048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1) 63150f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard#if defined(EINTR) 63248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost && (errno != EINTR) 63350f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard#endif 63448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ) 63548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (0); 63648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif /* !HAVE_POLL_H */ 6373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 63848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (0); 6393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPReadLine: 6433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 6443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Read one line in the HTTP server output, usually for extracting 6463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the HTTP protocol informations from the answer header. 6473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns a newly allocated string with a copy of the line, or NULL 6493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which indicate the end of the input. 6503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 6513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic char * 6533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) { 6543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char buf[4096]; 6553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *bp = buf; 656f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int rc; 657f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 6583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (bp - buf < 4095) { 6593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->inrptr == ctxt->inptr) { 660f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( (rc = xmlNanoHTTPRecv(ctxt)) == 0) { 6613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bp == buf) 6623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 6633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 6643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *bp = 0; 6653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlMemStrdup(buf)); 6663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 667f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else if ( rc == -1 ) { 668f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( NULL ); 669f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 6703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *bp = *ctxt->inrptr++; 6723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*bp == '\n') { 6733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *bp = 0; 6743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlMemStrdup(buf)); 6753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*bp != '\r') 6773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bp++; 6783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor buf[4095] = 0; 6803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlMemStrdup(buf)); 6813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPScanAnswer: 6863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 6873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @line: an HTTP header line 6883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Try to extract useful informations from the server answer. 6903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * We currently parse and process: 6913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - The HTTP revision/ return code 692a840b69261c44760d45370bef989c77f84727406Daniel Veillard * - The Content-Type, Mime-Type and charset used 693cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * - The Location for redirect processing. 6943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, the file descriptor number otherwise 6963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 6973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic void 6993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) { 7003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const char *cur = line; 7013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (line == NULL) return; 7033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!strncmp(line, "HTTP/", 5)) { 7053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int version = 0; 7063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 7073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 5; 7093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 7103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version *= 10; 7113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version += *cur - '0'; 7123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 7133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '.') { 7153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 7163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur >= '0') && (*cur <= '9')) { 7173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version *= 10; 7183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version += *cur - '0'; 7193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 7203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) 7223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 7233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 7243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version *= 10; 7253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur != ' ') && (*cur != '\t')) return; 7263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 7273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur < '0') || (*cur > '9')) return; 7283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 7293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret *= 10; 7303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret += *cur - '0'; 7313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 7323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return; 7343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->returnValue = ret; 73513cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard ctxt->version = version; 7363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) { 737a840b69261c44760d45370bef989c77f84727406Daniel Veillard const xmlChar *charset, *last, *mime; 7383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 13; 7393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 7403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) 7413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->contentType); 7423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->contentType = xmlMemStrdup(cur); 743a840b69261c44760d45370bef989c77f84727406Daniel Veillard mime = (const xmlChar *) cur; 744a840b69261c44760d45370bef989c77f84727406Daniel Veillard last = mime; 745a840b69261c44760d45370bef989c77f84727406Daniel Veillard while ((*last != 0) && (*last != ' ') && (*last != '\t') && 746a840b69261c44760d45370bef989c77f84727406Daniel Veillard (*last != ';') && (*last != ',')) 747a840b69261c44760d45370bef989c77f84727406Daniel Veillard last++; 748a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (ctxt->mimeType != NULL) 749a840b69261c44760d45370bef989c77f84727406Daniel Veillard xmlFree(ctxt->mimeType); 750a840b69261c44760d45370bef989c77f84727406Daniel Veillard ctxt->mimeType = (char *) xmlStrndup(mime, last - mime); 751a840b69261c44760d45370bef989c77f84727406Daniel Veillard charset = xmlStrstr(BAD_CAST ctxt->contentType, BAD_CAST "charset="); 752a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (charset != NULL) { 753a840b69261c44760d45370bef989c77f84727406Daniel Veillard charset += 8; 754a840b69261c44760d45370bef989c77f84727406Daniel Veillard last = charset; 755a840b69261c44760d45370bef989c77f84727406Daniel Veillard while ((*last != 0) && (*last != ' ') && (*last != '\t') && 756a840b69261c44760d45370bef989c77f84727406Daniel Veillard (*last != ';') && (*last != ',')) 757a840b69261c44760d45370bef989c77f84727406Daniel Veillard last++; 758a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (ctxt->encoding != NULL) 759a840b69261c44760d45370bef989c77f84727406Daniel Veillard xmlFree(ctxt->encoding); 760a840b69261c44760d45370bef989c77f84727406Daniel Veillard ctxt->encoding = (char *) xmlStrndup(charset, last - charset); 761a840b69261c44760d45370bef989c77f84727406Daniel Veillard } 7623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"ContentType:", 12)) { 763a840b69261c44760d45370bef989c77f84727406Daniel Veillard const xmlChar *charset, *last, *mime; 7643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 12; 7653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) return; 7663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 7673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->contentType = xmlMemStrdup(cur); 768a840b69261c44760d45370bef989c77f84727406Daniel Veillard mime = (const xmlChar *) cur; 769a840b69261c44760d45370bef989c77f84727406Daniel Veillard last = mime; 770a840b69261c44760d45370bef989c77f84727406Daniel Veillard while ((*last != 0) && (*last != ' ') && (*last != '\t') && 771a840b69261c44760d45370bef989c77f84727406Daniel Veillard (*last != ';') && (*last != ',')) 772a840b69261c44760d45370bef989c77f84727406Daniel Veillard last++; 773a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (ctxt->mimeType != NULL) 774a840b69261c44760d45370bef989c77f84727406Daniel Veillard xmlFree(ctxt->mimeType); 775a840b69261c44760d45370bef989c77f84727406Daniel Veillard ctxt->mimeType = (char *) xmlStrndup(mime, last - mime); 776a840b69261c44760d45370bef989c77f84727406Daniel Veillard charset = xmlStrstr(BAD_CAST ctxt->contentType, BAD_CAST "charset="); 777a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (charset != NULL) { 778a840b69261c44760d45370bef989c77f84727406Daniel Veillard charset += 8; 779a840b69261c44760d45370bef989c77f84727406Daniel Veillard last = charset; 780a840b69261c44760d45370bef989c77f84727406Daniel Veillard while ((*last != 0) && (*last != ' ') && (*last != '\t') && 781a840b69261c44760d45370bef989c77f84727406Daniel Veillard (*last != ';') && (*last != ',')) 782a840b69261c44760d45370bef989c77f84727406Daniel Veillard last++; 783a840b69261c44760d45370bef989c77f84727406Daniel Veillard if (ctxt->encoding != NULL) 784a840b69261c44760d45370bef989c77f84727406Daniel Veillard xmlFree(ctxt->encoding); 785a840b69261c44760d45370bef989c77f84727406Daniel Veillard ctxt->encoding = (char *) xmlStrndup(charset, last - charset); 786a840b69261c44760d45370bef989c77f84727406Daniel Veillard } 7873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Location:", 9)) { 7883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 9; 7893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 7903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->location != NULL) 7913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->location); 7927e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack if (*cur == '/') { 7937e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack xmlChar *tmp_http = xmlStrdup(BAD_CAST "http://"); 794f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlChar *tmp_loc = 7957e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack xmlStrcat(tmp_http, (const xmlChar *) ctxt->hostname); 796f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ctxt->location = 7977e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack (char *) xmlStrcat (tmp_loc, (const xmlChar *) cur); 7987e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack } else { 7997e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack ctxt->location = xmlMemStrdup(cur); 8007e29c0a457f90fad66d8d421dfc2647944024f09William M. Brack } 8013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"WWW-Authenticate:", 17)) { 8023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 17; 8033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 8043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->authHeader != NULL) 8053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->authHeader); 8063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->authHeader = xmlMemStrdup(cur); 8073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Proxy-Authenticate:", 19)) { 8083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 19; 8093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 8103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->authHeader != NULL) 8113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->authHeader); 8123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->authHeader = xmlMemStrdup(cur); 8139a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#ifdef HAVE_ZLIB_H 8149a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Encoding:", 17) ) { 8159a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard cur += 17; 8169a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard while ((*cur == ' ') || (*cur == '\t')) cur++; 8179a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard if ( !xmlStrncasecmp( BAD_CAST cur, BAD_CAST"gzip", 4) ) { 8189a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->usesGzip = 1; 8199a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 8209a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm = xmlMalloc(sizeof(z_stream)); 8219a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 8229a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard if (ctxt->strm != NULL) { 8239a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm->zalloc = Z_NULL; 8249a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm->zfree = Z_NULL; 8259a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm->opaque = Z_NULL; 8269a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm->avail_in = 0; 8279a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm->next_in = Z_NULL; 8289a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 8299a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard inflateInit2( ctxt->strm, 31 ); 8309a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard } 8319a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard } 8329a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#endif 833f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Length:", 15) ) { 834f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard cur += 15; 835f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->ContentLength = strtol( cur, NULL, 10 ); 8363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 8383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPConnectAttempt: 841cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @addr: a socket address structure 8423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Attempt a connection to the given IP:port endpoint. It forces 8443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * non-blocking semantic on the socket, and allow 60 seconds for 8453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the host to answer. 8463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, the file descriptor number otherwise 8483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 850f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezerstatic SOCKET 85156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlNanoHTTPConnectAttempt(struct sockaddr *addr) 8523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{ 85348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifndef HAVE_POLL_H 8543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd_set wfd; 8555bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#ifdef _WINSOCKAPI_ 8565bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard fd_set xfd; 8575bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#endif 8583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct timeval tv; 85948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#else /* !HAVE_POLL_H */ 86048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost struct pollfd p; 86148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif /* !HAVE_POLL_H */ 8623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int status; 86348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 864de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard int addrlen; 86548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 866de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard SOCKET s; 86748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 868de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard#ifdef SUPPORT_IP6 869de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (addr->sa_family == AF_INET6) { 87048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); 87148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost addrlen = sizeof(struct sockaddr_in6); 87248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } else 873de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard#endif 874de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard { 87548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 87648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost addrlen = sizeof(struct sockaddr_in); 877de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 878f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer if (s == INVALID_SOCKET) { 8793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 88048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost perror("socket"); 8813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 88248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n"); 883f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 88748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost u_long one = 1; 8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 88948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0; 8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else /* _WINSOCKAPI_ */ 8923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(VMS) 8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 89448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost int enable = 1; 89548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 89648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost status = ioctl(s, FIONBIO, &enable); 8973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else /* VMS */ 899cba68396ac4351a5c4451c483c3343a800d71bebDaniel Veillard#if defined(__BEOS__) && !defined(__HAIKU__) 90048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost { 90148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost bool noblock = true; 90248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 90348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost status = 90448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock, 90548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost sizeof(noblock)); 90648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 907254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard#else /* __BEOS__ */ 9083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((status = fcntl(s, F_GETFL, 0)) != -1) { 9093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef O_NONBLOCK 91048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost status |= O_NONBLOCK; 9113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else /* O_NONBLOCK */ 9123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef F_NDELAY 91348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost status |= F_NDELAY; 9143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* F_NDELAY */ 9153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* !O_NONBLOCK */ 91648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost status = fcntl(s, F_SETFL, status); 9173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (status < 0) { 9193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 92048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost perror("nonblocking"); 9213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 92248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n"); 92348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost closesocket(s); 924f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 9253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 926254b12607d427687ae5c1bd75fabaf2ca530b65eDaniel Veillard#endif /* !__BEOS__ */ 9273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* !VMS */ 9283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* !_WINSOCKAPI_ */ 9293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 93048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (connect(s, addr, addrlen) == -1) { 93148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost switch (socket_errno()) { 93248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case EINPROGRESS: 93348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case EWOULDBLOCK: 93448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost break; 93548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost default: 93648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, 93748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost "error connecting to HTTP server"); 93848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost closesocket(s); 939f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 94048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 94148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 94248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifndef HAVE_POLL_H 9433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tv.tv_sec = timeout; 9443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tv.tv_usec = 0; 9459e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard 9469e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#ifdef _MSC_VER 9479e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(push) 9489e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(disable: 4018) 9499e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#endif 950d29a5c8a5c42753653762763955510577c2c955dspadix#ifndef _WINSOCKAPI_ 95148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (s > FD_SETSIZE) 952f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 953d29a5c8a5c42753653762763955510577c2c955dspadix#endif 9543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor FD_ZERO(&wfd); 9553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor FD_SET(s, &wfd); 9565bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard 95748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifdef _WINSOCKAPI_ 9585bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard FD_ZERO(&xfd); 9595bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard FD_SET(s, &xfd); 96048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 96148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost switch (select(s + 1, NULL, &wfd, &xfd, &tv)) 9625bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#else 96348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost switch (select(s + 1, NULL, &wfd, NULL, &tv)) 9645bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#endif 9659e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#ifdef _MSC_VER 9669e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#pragma warning(pop) 9679e2110bbff362d12466bfa38cde2842b2a6297ffDaniel Veillard#endif 96848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 96948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#else /* !HAVE_POLL_H */ 97048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost p.fd = s; 97148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost p.events = POLLOUT; 97248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost switch (poll(&p, 1, timeout * 1000)) 97348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif /* !HAVE_POLL_H */ 97448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 9753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 97648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case 0: 97748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost /* Time out */ 97848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out"); 97948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost closesocket(s); 980f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 98148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost case -1: 98248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost /* Ermm.. ?? */ 98348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed"); 98448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost closesocket(s); 985f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 9863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 98848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#ifndef HAVE_POLL_H 98948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (FD_ISSET(s, &wfd) 9905bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#ifdef _WINSOCKAPI_ 99148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost || FD_ISSET(s, &xfd) 9925bb9ccd56a812b65e94e71477389be7826203649Daniel Veillard#endif 99348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost ) 99448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#else /* !HAVE_POLL_H */ 99548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (p.revents == POLLOUT) 99648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost#endif /* !HAVE_POLL_H */ 99748b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost { 99848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost XML_SOCKLEN_T len; 99948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 100048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost len = sizeof(status); 1001a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef SO_ERROR 100248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &status, &len) < 100348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 0) { 100448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost /* Solaris error code */ 100548b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n"); 1006283c83e0d3bca73b61c1d116c05fe4ccaa96ec04Denis Pauk closesocket(s); 1007f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 100848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 1009a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif 101048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost if (status) { 101148b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, 101248b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost "Error connecting to remote host"); 101348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost closesocket(s); 101448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost errno = status; 1015f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 101648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost } 10173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 101848b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost /* pbm */ 101948b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost __xmlIOErr(XML_FROM_HTTP, 0, "select failed\n"); 102048b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost closesocket(s); 1021f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 10223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 102348b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 102448b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost return (s); 10253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 102648b60c3c4d94a2aeb93ae9ff2181ad76b79eddd9Raphael Prevost 10273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 10283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPConnectHost: 10293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @host: the host name 10303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @port: the port number 10313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Attempt a connection to the given host:port endpoint. It tries 10333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the multiple IP provided by the DNS if available. 10343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, the file descriptor number otherwise 10363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 10373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1038f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezerstatic SOCKET 10393473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPConnectHost(const char *host, int port) 10403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{ 10413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct hostent *h; 10422db8c125be777d642fc1143f23a77d8cf0aa4de1Daniel Veillard struct sockaddr *addr = NULL; 10433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct in_addr ia; 104456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard struct sockaddr_in sockin; 10455c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard 10463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef SUPPORT_IP6 10473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct in6_addr ia6; 104856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard struct sockaddr_in6 sockin6; 10493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 10503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 1051f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer SOCKET s; 10525c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard 1053de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard memset (&sockin, 0, sizeof(sockin)); 1054de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard#ifdef SUPPORT_IP6 1055de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard memset (&sockin6, 0, sizeof(sockin6)); 1056cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#endif 1057cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards 1058cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#if !defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && defined(RES_USE_INET6) 1059de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (have_ipv6 ()) 1060560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard { 1061de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (!(_res.options & RES_INIT)) 1062de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard res_init(); 1063de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard _res.options |= RES_USE_INET6; 1064de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1065cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#endif 1066cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards 1067cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32) 1068cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards if (have_ipv6 ()) 1069cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#endif 1070cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#if defined(HAVE_GETADDRINFO) && (defined(SUPPORT_IP6) || defined(_WIN32)) 1071560c2a441bf27f5b9d55252a70f3d5952d9ae351Daniel Veillard { 1072de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard int status; 1073de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard struct addrinfo hints, *res, *result; 1074de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1075de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard result = NULL; 1076de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard memset (&hints, 0,sizeof(hints)); 1077de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard hints.ai_socktype = SOCK_STREAM; 1078de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1079de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard status = getaddrinfo (host, NULL, &hints, &result); 1080de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (status) { 10812b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard __xmlIOErr(XML_FROM_HTTP, 0, "getaddrinfo failed\n"); 1082f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 1083de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1084de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1085de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard for (res = result; res; res = res->ai_next) { 1086cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards if (res->ai_family == AF_INET) { 1087cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards if (res->ai_addrlen > sizeof(sockin)) { 1088cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); 1089cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards freeaddrinfo (result); 1090f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 1091de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1092cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards memcpy (&sockin, res->ai_addr, res->ai_addrlen); 1093cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards sockin.sin_port = htons (port); 1094cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards addr = (struct sockaddr *)&sockin; 1095cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#ifdef SUPPORT_IP6 1096cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards } else if (have_ipv6 () && (res->ai_family == AF_INET6)) { 1097cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards if (res->ai_addrlen > sizeof(sockin6)) { 1098cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); 1099de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard freeaddrinfo (result); 1100f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 1101de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1102cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards memcpy (&sockin6, res->ai_addr, res->ai_addrlen); 1103cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards sockin6.sin6_port = htons (port); 1104cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards addr = (struct sockaddr *)&sockin6; 1105cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#endif 1106cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards } else 1107cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards continue; /* for */ 1108cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards 1109cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards s = xmlNanoHTTPConnectAttempt (addr); 1110f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer if (s != INVALID_SOCKET) { 1111cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards freeaddrinfo (result); 1112cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards return (s); 1113de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1114de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1115cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards 11163dc93a42432cbf6e40d4ac3a4e61152d86a9f7ddDaniel Veillard if (result) 11173dc93a42432cbf6e40d4ac3a4e61152d86a9f7ddDaniel Veillard freeaddrinfo (result); 1118cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards } 11193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1120cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32) 1121cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards else 1122de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard#endif 1123cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#if !defined(HAVE_GETADDRINFO) || !defined(_WIN32) 1124cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards { 1125437f4f5977f023bbaa7e2da781ca233d5c108954Patrick Monnerat h = gethostbyname (GETHOSTBYNAME_ARG_CAST host); 1126de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (h == NULL) { 112756b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard 112856b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard/* 112956b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard * Okay, I got fed up by the non-portability of this error message 113056b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard * extraction code. it work on Linux, if it work on your platform 113156b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard * and one want to enable it, send me the defined(foobar) needed 113256b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard */ 113356b2db7478a1b24516825b74634e6ce45138f4fbDaniel Veillard#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux) 1134de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard const char *h_err_txt = ""; 1135de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1136de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard switch (h_errno) { 1137de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard case HOST_NOT_FOUND: 1138de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard h_err_txt = "Authoritive host not found"; 1139de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard break; 1140de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1141de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard case TRY_AGAIN: 1142de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard h_err_txt = 1143de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard "Non-authoritive host not found or server failure."; 1144de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard break; 1145de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1146de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard case NO_RECOVERY: 1147de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard h_err_txt = 1148de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard "Non-recoverable errors: FORMERR, REFUSED, or NOTIMP."; 1149de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard break; 1150de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1151d95b689fd9cb994b072e9a874b98ea62be8cc6c6Daniel Veillard#ifdef NO_ADDRESS 1152de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard case NO_ADDRESS: 1153de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard h_err_txt = 1154de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard "Valid name, no data record of requested type."; 1155de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard break; 1156d95b689fd9cb994b072e9a874b98ea62be8cc6c6Daniel Veillard#endif 1157de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard 1158de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard default: 1159de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard h_err_txt = "No error text defined."; 1160de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard break; 1161de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 11622b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard __xmlIOErr(XML_FROM_HTTP, 0, h_err_txt); 11635c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard#else 11642b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard __xmlIOErr(XML_FROM_HTTP, 0, "Failed to resolve host"); 11655c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard#endif 1166f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 1167de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 11685c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard 1169de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard for (i = 0; h->h_addr_list[i]; i++) { 1170de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard if (h->h_addrtype == AF_INET) { 1171de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard /* A records (IPv4) */ 11728e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard if ((unsigned int) h->h_length > sizeof(ia)) { 11738e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); 1174f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 11758e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard } 1176de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard memcpy (&ia, h->h_addr_list[i], h->h_length); 1177de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard sockin.sin_family = h->h_addrtype; 1178de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard sockin.sin_addr = ia; 1179ac17e5939c032e547cf5a6325223ff5eb08e04b1Daniel Veillard sockin.sin_port = (unsigned short)htons ((unsigned short)port); 1180de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard addr = (struct sockaddr *) &sockin; 11813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef SUPPORT_IP6 1182de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } else if (have_ipv6 () && (h->h_addrtype == AF_INET6)) { 1183de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard /* AAAA records (IPv6) */ 11848e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard if ((unsigned int) h->h_length > sizeof(ia6)) { 11858e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); 1186f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 11878e2c9792e923c95a4d353cbc0bb1146413b60168Daniel Veillard } 1188de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard memcpy (&ia6, h->h_addr_list[i], h->h_length); 1189de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard sockin6.sin6_family = h->h_addrtype; 1190de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard sockin6.sin6_addr = ia6; 1191de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard sockin6.sin6_port = htons (port); 1192de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard addr = (struct sockaddr *) &sockin6; 1193de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard#endif 1194de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } else 1195de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard break; /* for */ 11963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1197de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard s = xmlNanoHTTPConnectAttempt (addr); 1198f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer if (s != INVALID_SOCKET) 1199de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard return (s); 1200de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1201de2a67b430ddc59690b707ac0119cb26366631d4Daniel Veillard } 1202cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards#endif 1203cb418de04da834d6ba23a715d3eaf8c9297e9029Rob Richards 12043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 12053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 12065c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard "xmlNanoHTTPConnectHost: unable to connect to '%s'.\n", 12075c39654822daf2e4d06a63d78930f22b2f122d99Daniel Veillard host); 12083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1209f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer return INVALID_SOCKET; 12103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 12113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 12143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPOpen: 12153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL to load 12163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @contentType: if available the Content-Type information will be 12173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned at that location 12183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 12193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function try to open a connection to the indicated resource 12203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * via HTTP GET. 12213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 12223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns NULL in case of failure, otherwise a request handler. 12233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contentType, if provided must be freed by the caller 12243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 12253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid* 12273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPOpen(const char *URL, char **contentType) { 12283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (contentType != NULL) *contentType = NULL; 1229f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return(xmlNanoHTTPMethod(URL, NULL, NULL, contentType, NULL, 0)); 12309403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard} 12319403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 12329403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard/** 12339403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * xmlNanoHTTPOpenRedir: 12349403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @URL: The URL to load 12359403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @contentType: if available the Content-Type information will be 12369403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * returned at that location 1237cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @redir: if available the redirected URL will be returned 12389403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * 12399403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * This function try to open a connection to the indicated resource 12409403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * via HTTP GET. 12419403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * 12429403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * Returns NULL in case of failure, otherwise a request handler. 12439403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * The contentType, if provided must be freed by the caller 12449403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard */ 12459403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 12469403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillardvoid* 12479403a0495dcbdfa430b669b4e3d689d8e208c687Daniel VeillardxmlNanoHTTPOpenRedir(const char *URL, char **contentType, char **redir) { 12489403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (contentType != NULL) *contentType = NULL; 12499403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redir != NULL) *redir = NULL; 1250f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return(xmlNanoHTTPMethodRedir(URL, NULL, NULL, contentType, redir, NULL,0)); 12513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 12523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 12543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPRead: 12553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the HTTP context 12563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @dest: a buffer 12573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @len: the buffer length 12583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 12593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function tries to read @len bytes from the existing HTTP connection 12603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and saves them in @dest. This is a blocking call. 12613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 12623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the number of byte read. 0 is an indication of an end of connection. 12633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * -1 indicates a parameter error. 12643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 12653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 12663473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPRead(void *ctx, void *dest, int len) { 12673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 12689a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#ifdef HAVE_ZLIB_H 12699a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard int bytes_read = 0; 12709a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard int orig_avail_in; 12719a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard int z_ret; 12729a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#endif 12733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctx == NULL) return(-1); 12753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (dest == NULL) return(-1); 12763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (len <= 0) return(0); 12773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12789a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#ifdef HAVE_ZLIB_H 12799a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard if (ctxt->usesGzip == 1) { 12809a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard if (ctxt->strm == NULL) return(0); 1281f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 12829a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm->next_out = dest; 12839a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm->avail_out = len; 1284e882765aa4e1fdcf7958357c3add39b505cb2e13William M. Brack ctxt->strm->avail_in = ctxt->inptr - ctxt->inrptr; 12859a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 1286e882765aa4e1fdcf7958357c3add39b505cb2e13William M. Brack while (ctxt->strm->avail_out > 0 && 1287e882765aa4e1fdcf7958357c3add39b505cb2e13William M. Brack (ctxt->strm->avail_in > 0 || xmlNanoHTTPRecv(ctxt) > 0)) { 1288d2f682a495d2668342395bc72f69500a5de6b072William M. Brack orig_avail_in = ctxt->strm->avail_in = 1289d2f682a495d2668342395bc72f69500a5de6b072William M. Brack ctxt->inptr - ctxt->inrptr - bytes_read; 12909a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->strm->next_in = BAD_CAST (ctxt->inrptr + bytes_read); 12919a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 12929a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard z_ret = inflate(ctxt->strm, Z_NO_FLUSH); 12939a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard bytes_read += orig_avail_in - ctxt->strm->avail_in; 12949a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 12959a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard if (z_ret != Z_OK) break; 1296d2f682a495d2668342395bc72f69500a5de6b072William M. Brack } 12979a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 12989a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard ctxt->inrptr += bytes_read; 12999a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard return(len - ctxt->strm->avail_out); 13009a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard } 13019a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#endif 13029a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 13033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (ctxt->inptr - ctxt->inrptr < len) { 1304f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (xmlNanoHTTPRecv(ctxt) <= 0) break; 13053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->inptr - ctxt->inrptr < len) 13073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = ctxt->inptr - ctxt->inrptr; 13083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memcpy(dest, ctxt->inrptr, len); 13093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inrptr += len; 13103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(len); 13113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 13143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPClose: 13153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the HTTP context 13163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function closes an HTTP context, it ends up the connection and 13183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * free all data related to it. 13193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 13213473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPClose(void *ctx) { 13223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctx == NULL) return; 13253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 13273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 13309403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * xmlNanoHTTPMethodRedir: 13313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL to load 13323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @method: the HTTP method to use 13333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @input: the input string if any 13343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @contentType: the Content-Type information IN and OUT 13359403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @redir: the redirected URL OUT 13363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @headers: the extra headers 1337cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @ilen: input length 13383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function try to open a connection to the indicated resource 13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * via HTTP using the given @method, adding the given extra headers 13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and the input buffer for the request content. 13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns NULL in case of failure, otherwise a request handler. 13449403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * The contentType, or redir, if provided must be freed by the caller 13453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid* 13489403a0495dcbdfa430b669b4e3d689d8e208c687Daniel VeillardxmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input, 1349f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char **contentType, char **redir, 1350f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard const char *headers, int ilen ) { 13513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt; 13523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *bp, *p; 1353f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer int blen; 1354f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer SOCKET ret; 13553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int nbRedirects = 0; 13563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *redirURL = NULL; 135778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack#ifdef DEBUG_HTTP 135878637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack int xmt_bytes; 135978637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack#endif 1360f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 13613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (URL == NULL) return(NULL); 13623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (method == NULL) method = "GET"; 13633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPInit(); 13643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorretry: 13661811add768cabe36f763c960a40698418c5cbe47Gaurav Gupta if (redirURL == NULL) { 13673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlNanoHTTPNewCtxt(URL); 13681811add768cabe36f763c960a40698418c5cbe47Gaurav Gupta if (ctxt == NULL) 13691811add768cabe36f763c960a40698418c5cbe47Gaurav Gupta return(NULL); 13701811add768cabe36f763c960a40698418c5cbe47Gaurav Gupta } else { 13713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlNanoHTTPNewCtxt(redirURL); 13721811add768cabe36f763c960a40698418c5cbe47Gaurav Gupta if (ctxt == NULL) 13731811add768cabe36f763c960a40698418c5cbe47Gaurav Gupta return(NULL); 1374a840b69261c44760d45370bef989c77f84727406Daniel Veillard ctxt->location = xmlMemStrdup(redirURL); 13753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) { 13782b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Not a valid HTTP URI"); 13793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 13803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (redirURL != NULL) xmlFree(redirURL); 13813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 13823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->hostname == NULL) { 13842b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard __xmlIOErr(XML_FROM_HTTP, XML_HTTP_UNKNOWN_HOST, 13852b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard "Failed to identify host in URI"); 13863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 13879403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) xmlFree(redirURL); 13883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 13893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxy) { 13913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blen = strlen(ctxt->hostname) * 2 + 16; 13923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlNanoHTTPConnectHost(proxy, proxyPort); 13933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 13953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blen = strlen(ctxt->hostname); 13963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port); 13973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1398f99d222316e1219aa8b95220f6918e6c7018e174Ozkan Sezer if (ret == INVALID_SOCKET) { 13993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 14009403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) xmlFree(redirURL); 14013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 14023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->fd = ret; 14043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1405f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (input == NULL) 14063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ilen = 0; 1407f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else 1408f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard blen += 36; 1409f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 14103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (headers != NULL) 1411f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard blen += strlen(headers) + 2; 14123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (contentType && *contentType) 1413ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack /* reserve for string plus 'Content-Type: \r\n" */ 14143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blen += strlen(*contentType) + 16; 1415351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard if (ctxt->query != NULL) 1416ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack /* 1 for '?' */ 1417351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard blen += strlen(ctxt->query) + 1; 1418f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard blen += strlen(method) + strlen(ctxt->path) + 24; 14199a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#ifdef HAVE_ZLIB_H 1420ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack /* reserve for possible 'Accept-Encoding: gzip' string */ 14219a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard blen += 23; 14229a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#endif 1423ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack if (ctxt->port != 80) { 1424ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack /* reserve space for ':xxxxx', incl. potential proxy */ 1425ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack if (proxy) 1426ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack blen += 12; 1427ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack else 1428ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack blen += 6; 1429ead3583b47ab9bef267bbc0c9ee11e0ea6077340William M. Brack } 143082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard bp = (char*)xmlMallocAtomic(blen); 1431f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( bp == NULL ) { 1432f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlNanoHTTPFreeCtxt( ctxt ); 14332b0f8799086f2a54444c618ab3ed01a8177491f2Daniel Veillard xmlHTTPErrMemory("allocating header buffer"); 1434f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( NULL ); 1435f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1436f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1437f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard p = bp; 1438f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 14393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxy) { 14403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->port != 80) { 1441f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard p += snprintf( p, blen - (p - bp), "%s http://%s:%d%s", 144249cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin method, ctxt->hostname, 1443f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ctxt->port, ctxt->path ); 14443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1445f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard else 144649cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin p += snprintf( p, blen - (p - bp), "%s http://%s%s", method, 1447f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ctxt->hostname, ctxt->path); 14483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 145049cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin p += snprintf( p, blen - (p - bp), "%s %s", method, ctxt->path); 1451f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1452351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard if (ctxt->query != NULL) 1453351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard p += snprintf( p, blen - (p - bp), "?%s", ctxt->query); 1454351f2d6e1ae97775a2458b86cdb110d00332834aDaniel Veillard 1455ec72008ba71615131235222fd3d8765b95e46e4fWilliam M. Brack if (ctxt->port == 80) { 1456f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s\r\n", 145749cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin ctxt->hostname); 1458ec72008ba71615131235222fd3d8765b95e46e4fWilliam M. Brack } else { 1459ec72008ba71615131235222fd3d8765b95e46e4fWilliam M. Brack p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s:%d\r\n", 1460ec72008ba71615131235222fd3d8765b95e46e4fWilliam M. Brack ctxt->hostname, ctxt->port); 1461ec72008ba71615131235222fd3d8765b95e46e4fWilliam M. Brack } 1462f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 14639a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#ifdef HAVE_ZLIB_H 14649a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard p += snprintf(p, blen - (p - bp), "Accept-Encoding: gzip\r\n"); 14659a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard#endif 14669a2724d847b9f1d241d32546be779736209e0a00Daniel Veillard 1467f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (contentType != NULL && *contentType) 146849cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin p += snprintf(p, blen - (p - bp), "Content-Type: %s\r\n", *contentType); 1469f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1470f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (headers != NULL) 147149cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin p += snprintf( p, blen - (p - bp), "%s", headers ); 1472f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 14733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (input != NULL) 147449cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(p, blen - (p - bp), "Content-Length: %d\r\n\r\n", ilen ); 14753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 147649cc97565fbe2928388a1e437c44429097a504aeAleksey Sanin snprintf(p, blen - (p - bp), "\r\n"); 1477f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 14783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 14793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 14803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "-> %s%s", proxy? "(Proxy) " : "", bp); 14813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((blen -= strlen(bp)+1) < 0) 14823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 14833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "ERROR: overflowed buffer by %d bytes\n", -blen); 14843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 14853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->outptr = ctxt->out = bp; 14863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->state = XML_NANO_HTTP_WRITE; 1487f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard blen = strlen( ctxt->out ); 1488f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#ifdef DEBUG_HTTP 148978637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmt_bytes = xmlNanoHTTPSend(ctxt, ctxt->out, blen ); 1490f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( xmt_bytes != blen ) 1491f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 1492f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n", 1493f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmt_bytes, blen, 1494f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "bytes of HTTP headers sent to host", 1495f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->hostname ); 149678637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack#else 149778637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlNanoHTTPSend(ctxt, ctxt->out, blen ); 1498f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#endif 1499f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1500f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( input != NULL ) { 150178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack#ifdef DEBUG_HTTP 1502f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmt_bytes = xmlNanoHTTPSend( ctxt, input, ilen ); 1503f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1504f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( xmt_bytes != ilen ) 1505f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 1506f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n", 1507f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmt_bytes, ilen, 1508f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "bytes of HTTP content sent to host", 1509f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->hostname ); 151078637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack#else 151178637da0ea1c833dfdfad87a9aa5bea14510d08aWilliam M. Brack xmlNanoHTTPSend( ctxt, input, ilen ); 1512f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#endif 1513f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1514f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 15153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->state = XML_NANO_HTTP_READ; 15163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) { 1518594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard if (*p == 0) { 15193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->content = ctxt->inrptr; 15203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(p); 15213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 15223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPScanAnswer(ctxt, p); 15243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 15263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "<- %s\n", p); 15273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 15283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(p); 15293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) && 15323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->returnValue < 400)) { 15333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 15343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 15353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "\nRedirect to: %s\n", ctxt->location); 15363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1537f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard while ( xmlNanoHTTPRecv(ctxt) > 0 ) ; 15383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) { 15393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nbRedirects++; 15409403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) 15419403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard xmlFree(redirURL); 15423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor redirURL = xmlMemStrdup(ctxt->location); 15433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 15443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto retry; 15453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 15479403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) xmlFree(redirURL); 15483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 15493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 1550f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: Too many redirects, aborting ...\n"); 15513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 15523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 15533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (contentType != NULL) { 15563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) 15573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *contentType = xmlMemStrdup(ctxt->contentType); 15583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 15593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *contentType = NULL; 15603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15629403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if ((redir != NULL) && (redirURL != NULL)) { 15639403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard *redir = redirURL; 15649403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard } else { 15659403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) 15669403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard xmlFree(redirURL); 15679403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redir != NULL) 15689403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard *redir = NULL; 15699403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard } 15709403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 15713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 15723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) 15733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 15743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "\nCode %d, content-type '%s'\n\n", 15753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->returnValue, ctxt->contentType); 15763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 15773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 15783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "\nCode %d, no content-type\n\n", 15793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->returnValue); 15803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 15813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((void *) ctxt); 15833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 15869403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * xmlNanoHTTPMethod: 15879403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @URL: The URL to load 15889403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @method: the HTTP method to use 15899403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @input: the input string if any 15909403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @contentType: the Content-Type information IN and OUT 15919403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @headers: the extra headers 1592cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @ilen: input length 15939403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * 15949403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * This function try to open a connection to the indicated resource 15959403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * via HTTP using the given @method, adding the given extra headers 15969403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * and the input buffer for the request content. 15979403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * 15989403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * Returns NULL in case of failure, otherwise a request handler. 15999403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * The contentType, if provided must be freed by the caller 16009403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard */ 16019403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 16029403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillardvoid* 16039403a0495dcbdfa430b669b4e3d689d8e208c687Daniel VeillardxmlNanoHTTPMethod(const char *URL, const char *method, const char *input, 1604f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char **contentType, const char *headers, int ilen) { 16059403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard return(xmlNanoHTTPMethodRedir(URL, method, input, contentType, 1606f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard NULL, headers, ilen)); 16079403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard} 16089403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 16099403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard/** 16103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPFetch: 16113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL to load 16123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @filename: the filename where the content should be saved 16133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @contentType: if available the Content-Type information will be 16143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned at that location 16153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 16163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function try to fetch the indicated resource via HTTP GET 16173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and save it's content in the file. 16183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 16193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, 0 incase of success. The contentType, 16203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if provided must be freed by the caller 16213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 16233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPFetch(const char *URL, const char *filename, char **contentType) { 1624f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard void *ctxt = NULL; 1625f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char *buf = NULL; 16263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int fd; 16273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len; 1628dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost int ret = 0; 1629dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost 1630015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if (filename == NULL) return(-1); 16313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlNanoHTTPOpen(URL, contentType); 16323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return(-1); 16333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1634f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (!strcmp(filename, "-")) 16353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd = 0; 16363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 16373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd = open(filename, O_CREAT | O_WRONLY, 00644); 16383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (fd < 0) { 16393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPClose(ctxt); 16403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((contentType != NULL) && (*contentType != NULL)) { 16413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(*contentType); 16423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *contentType = NULL; 16433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 16453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1648f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlNanoHTTPFetchContent( ctxt, &buf, &len ); 1649f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( len > 0 ) { 1650dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost if (write(fd, buf, len) == -1) { 1651dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost ret = -1; 1652dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost } 16533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPClose(ctxt); 16563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor close(fd); 1657dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost return(ret); 16583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 16593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1660a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED 16613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 16623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPSave: 16633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the HTTP context 16643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @filename: the filename where the content should be saved 16653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 16663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function saves the output of the HTTP transaction to a file 16673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * It closes and free the context at the end 16683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 16693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, 0 incase of success. 16703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 16713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 16723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPSave(void *ctxt, const char *filename) { 1673e392497e4c4313382c3c20903d09a69f0948f721Daniel Veillard char *buf = NULL; 16743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int fd; 16753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len; 1676dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost int ret = 0; 1677dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost 1678015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack if ((ctxt == NULL) || (filename == NULL)) return(-1); 16793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1680f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (!strcmp(filename, "-")) 16813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd = 0; 16823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 1683cd2ebab7d9535f3a380fde15fc85aca1820e0a3eDaniel Veillard fd = open(filename, O_CREAT | O_WRONLY, 0666); 16843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (fd < 0) { 16853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPClose(ctxt); 16863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 16873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1690f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlNanoHTTPFetchContent( ctxt, &buf, &len ); 1691f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( len > 0 ) { 1692dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost if (write(fd, buf, len) == -1) { 1693dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost ret = -1; 1694dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost } 16953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPClose(ctxt); 169820d823614e9826406cb0f1dbd4dd7fc812694bc3William M. Brack close(fd); 1699dff8d0f726cecc2cc9265bc7148333bcf6d8ac0cStefan Kost return(ret); 17003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1701a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */ 17023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 17043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPReturnCode: 17053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the HTTP context 17063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 17075e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Get the latest HTTP return code received 17085e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 17093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the HTTP return code for the request. 17103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 17123473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPReturnCode(void *ctx) { 17133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 17143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return(-1); 17163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->returnValue); 17183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 17193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 17213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPAuthHeader: 17223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the HTTP context 17233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 17245e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Get the authentication header of an HTTP context 17255e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 17263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the stashed value of the WWW-Authenticate or Proxy-Authenticate 17273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * header. 17283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 17293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst char * 17303473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPAuthHeader(void *ctx) { 17313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 17323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return(NULL); 17343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->authHeader); 17363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 17373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1738f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard/** 173901c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlNanoHTTPContentLength: 1740f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * @ctx: the HTTP context 1741f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * 1742a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * Provides the specified content length from the HTTP header. 1743a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * 1744f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * Return the specified content length from the HTTP header. Note that 1745f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * a value of -1 indicates that the content length element was not included in 1746f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * the response header. 1747f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard */ 1748f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillardint 1749f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel VeillardxmlNanoHTTPContentLength( void * ctx ) { 175082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 1751f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1752f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( ( ctxt == NULL ) ? -1 : ctxt->ContentLength ); 1753f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 1754f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1755f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard/** 1756847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * xmlNanoHTTPRedir: 1757847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * @ctx: the HTTP context 1758847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * 1759847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * Provides the specified redirection URL if available from the HTTP header. 1760847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * 1761847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * Return the specified redirection URL or NULL if not redirected. 1762847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard */ 1763847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillardconst char * 1764847332a0da596e84f00acc9d692e0e582b8b12eaDaniel VeillardxmlNanoHTTPRedir( void * ctx ) { 176582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 1766847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard 1767847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard return ( ( ctxt == NULL ) ? NULL : ctxt->location ); 1768847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard} 1769847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard 1770847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard/** 1771847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * xmlNanoHTTPEncoding: 1772847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * @ctx: the HTTP context 1773847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * 1774847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * Provides the specified encoding if specified in the HTTP headers. 1775847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * 1776847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard * Return the specified encoding or NULL if not available 1777847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard */ 1778847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillardconst char * 1779847332a0da596e84f00acc9d692e0e582b8b12eaDaniel VeillardxmlNanoHTTPEncoding( void * ctx ) { 178082cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 1781847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard 1782847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard return ( ( ctxt == NULL ) ? NULL : ctxt->encoding ); 1783847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard} 1784847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard 1785847332a0da596e84f00acc9d692e0e582b8b12eaDaniel Veillard/** 1786a840b69261c44760d45370bef989c77f84727406Daniel Veillard * xmlNanoHTTPMimeType: 1787a840b69261c44760d45370bef989c77f84727406Daniel Veillard * @ctx: the HTTP context 1788a840b69261c44760d45370bef989c77f84727406Daniel Veillard * 1789a840b69261c44760d45370bef989c77f84727406Daniel Veillard * Provides the specified Mime-Type if specified in the HTTP headers. 1790a840b69261c44760d45370bef989c77f84727406Daniel Veillard * 1791a840b69261c44760d45370bef989c77f84727406Daniel Veillard * Return the specified Mime-Type or NULL if not available 1792a840b69261c44760d45370bef989c77f84727406Daniel Veillard */ 1793a840b69261c44760d45370bef989c77f84727406Daniel Veillardconst char * 1794a840b69261c44760d45370bef989c77f84727406Daniel VeillardxmlNanoHTTPMimeType( void * ctx ) { 179582cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 1796a840b69261c44760d45370bef989c77f84727406Daniel Veillard 1797a840b69261c44760d45370bef989c77f84727406Daniel Veillard return ( ( ctxt == NULL ) ? NULL : ctxt->mimeType ); 1798a840b69261c44760d45370bef989c77f84727406Daniel Veillard} 1799a840b69261c44760d45370bef989c77f84727406Daniel Veillard 1800a840b69261c44760d45370bef989c77f84727406Daniel Veillard/** 180101c13b5be2d249ef66d86585adee87901bb8efa2Daniel Veillard * xmlNanoHTTPFetchContent: 1802f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * @ctx: the HTTP context 1803f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * @ptr: pointer to set to the content buffer. 1804f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * @len: integer pointer to hold the length of the content 1805f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * 1806a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * Check if all the content was read 1807a9b66d00b5fbae2381f59c0be4d8c7b8e3c16cf7Daniel Veillard * 1808f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * Returns 0 if all the content was read and available, returns 1809f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * -1 if received content length was less than specified or an error 1810f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * occurred. 1811f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard */ 1812a2351322c89608d09ce1a99e5eccd62d00c79890Daniel Veillardstatic int 1813f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel VeillardxmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ) { 181482cb31994f93a6f73f77c05e4e3d45c4ef750d3aDaniel Veillard xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 1815f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1816f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int rc = 0; 1817f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int cur_lgth; 1818f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int rcvd_lgth; 1819f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int dummy_int; 1820f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char * dummy_ptr = NULL; 1821f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1822f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard /* Dummy up return input parameters if not provided */ 1823f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1824f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( len == NULL ) 1825f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard len = &dummy_int; 1826f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1827f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( ptr == NULL ) 1828f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ptr = &dummy_ptr; 1829f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1830f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard /* But can't work without the context pointer */ 1831f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1832f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( ( ctxt == NULL ) || ( ctxt->content == NULL ) ) { 1833f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard *len = 0; 1834f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard *ptr = NULL; 1835f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( -1 ); 1836f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1837f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1838f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard rcvd_lgth = ctxt->inptr - ctxt->content; 1839f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1840f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard while ( (cur_lgth = xmlNanoHTTPRecv( ctxt )) > 0 ) { 1841f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1842f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard rcvd_lgth += cur_lgth; 1843f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( (ctxt->ContentLength > 0) && (rcvd_lgth >= ctxt->ContentLength) ) 1844f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 1845f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1846f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1847f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard *ptr = ctxt->content; 1848f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard *len = rcvd_lgth; 1849f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1850f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( ( ctxt->ContentLength > 0 ) && ( rcvd_lgth < ctxt->ContentLength ) ) 1851f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard rc = -1; 1852f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else if ( rcvd_lgth == 0 ) 1853f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard rc = -1; 1854f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1855f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( rc ); 1856f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 1857f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 18583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef STANDALONE 18593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint main(int argc, char **argv) { 18603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *contentType = NULL; 18613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (argv[1] != NULL) { 1863f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (argv[2] != NULL) 18643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFetch(argv[1], argv[2], &contentType); 18653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 18663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFetch(argv[1], "-", &contentType); 18673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (contentType != NULL) xmlFree(contentType); 18683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 18693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 18703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s: minimal HTTP GET implementation\n", argv[0]); 18713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 18723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "\tusage %s [ URL [ filename ] ]\n", argv[0]); 18733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 18743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCleanup(); 18753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlMemoryDump(); 18763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 18773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 18783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* STANDALONE */ 18793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else /* !LIBXML_HTTP_ENABLED */ 18803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef STANDALONE 18813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <stdio.h> 18823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint main(int argc, char **argv) { 18833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 18843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s : HTTP support not compiled in\n", argv[0]); 18853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 18863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 18873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* STANDALONE */ 18883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_HTTP_ENABLED */ 18895d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_nanohttp 18905d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 1891