nanohttp.c revision 50f3437111a6428b4852740e83db4848b0b09a97
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 */ 133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* TODO add compression support, Send the Accept- , and decompress on the 153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fly with ZLIB if found at compile-time */ 163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17f3afa7dd4e8daacfa62f7345b7d7071e0cb33423Daniel Veillard#define NEED_SOCKETS 1870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "libxml.h" 193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_HTTP_ENABLED 213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <string.h> 223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_STDLIB_H 243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <stdlib.h> 253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_UNISTD_H 273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <unistd.h> 283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_SOCKET_H 303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/socket.h> 313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_NETINET_IN_H 333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <netinet/in.h> 343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_ARPA_INET_H 363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <arpa/inet.h> 373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_NETDB_H 393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <netdb.h> 403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_FCNTL_H 423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <fcntl.h> 433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_ERRNO_H 453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <errno.h> 463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_TIME_H 483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/time.h> 493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_SELECT_H 513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/select.h> 523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_STRINGS_H 543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <strings.h> 553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef SUPPORT_IP6 573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <resolv.h> 583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef VMS 613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <stropts> 623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SOCKLEN_T unsigned int 633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SOCKET int 643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 66f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#include <libxml/xmlerror.h> 673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h> 683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/parser.h> /* for xmlStr(n)casecmp() */ 693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/nanohttp.h> 703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A couple portability macros 733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifndef _WINSOCKAPI_ 753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define closesocket(s) close(s) 763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SOCKET int 773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 79f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef STANDALONE 813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define DEBUG_HTTP 823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define xmlStrncasecmp(a, b, n) strncasecmp((char *)a, (char *)b, n) 833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define xmlStrcasecmpi(a, b) strcasecmp((char *)a, (char *)b) 843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_MAX_REDIR 10 873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_CHUNK 4096 893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_CLOSED 0 913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_WRITE 1 923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_READ 2 933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NANO_HTTP_NONE 4 943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef struct xmlNanoHTTPCtxt { 963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *protocol; /* the protocol name */ 973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *hostname; /* the host name */ 983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int port; /* the port */ 993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *path; /* the path within the URL */ 1003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SOCKET fd; /* the file descriptor for the socket */ 1013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int state; /* WRITE / READ / CLOSED */ 1023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *out; /* buffer sent (zero terminated) */ 1033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *outptr; /* index within the buffer sent */ 1043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *in; /* the receiving buffer */ 1053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *content; /* the start of the content */ 1063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *inptr; /* the next byte to read from network */ 1073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *inrptr; /* the next byte to give back to the client */ 1083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int inlen; /* len of the input buffer */ 1093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int last; /* return code for last operation */ 1103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int returnValue; /* the protocol return value */ 111f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int ContentLength; /* specified content length from HTTP header */ 1123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *contentType; /* the MIME type for the input */ 1133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *location; /* the new URL in case of redirect */ 1143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *authHeader; /* contents of {WWW,Proxy}-Authenticate header */ 1153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} xmlNanoHTTPCtxt, *xmlNanoHTTPCtxtPtr; 1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int initialized = 0; 1183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic char *proxy = NULL; /* the proxy name if any */ 1193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int proxyPort; /* the proxy port if any */ 1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic unsigned int timeout = 60;/* the select() timeout in seconds */ 1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 122f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillardint xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ); 123f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillardint xmlNanoHTTPContentLength( void * ctx ); 124f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A portability function 1273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 12856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int socket_errno(void) { 1293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 1303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(WSAGetLastError()); 1313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else 1323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(errno); 1333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPInit: 1383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the HTTP protocol layer. 1403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Currently it just checks for proxy informations 1413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 1443473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPInit(void) { 1453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const char *env; 1463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 1473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor WSADATA wsaData; 1483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (initialized) 1513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 1523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 1543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) 1553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 1563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxy == NULL) { 1593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor proxyPort = 80; 1603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor env = getenv("no_proxy"); 1613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (env != NULL) 1623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 1633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor env = getenv("http_proxy"); 1643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (env != NULL) { 1653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPScanProxy(env); 1663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 1673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor env = getenv("HTTP_PROXY"); 1693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (env != NULL) { 1703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPScanProxy(env); 1713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 1723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordone: 1753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor initialized = 1; 1763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1795e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * xmlNanoHTTPCleanup: 1803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the HTTP protocol layer. 1823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 1853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPCleanup(void) { 1863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxy != NULL) 1873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(proxy); 1883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 1893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (initialized) 1903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor WSACleanup(); 1913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor initialized = 0; 1933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return; 1943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPScanURL: 1983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 1993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL used to initialize the context 2003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (Re)Initialize an HTTP context by parsing the URL and finding 2023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the protocol host port and path it indicates. 2033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 2043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic void 2063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) { 2073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const char *cur = URL; 2083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char buf[4096]; 20956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard int indx = 0; 2103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int port = 0; 2113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->protocol != NULL) { 2133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->protocol); 2143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->protocol = NULL; 2153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->hostname != NULL) { 2173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->hostname); 2183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->hostname = NULL; 2193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->path != NULL) { 2213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->path); 2223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->path = NULL; 2233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (URL == NULL) return; 22556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 2263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (*cur != 0) { 2273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) { 22856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 2293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->protocol = xmlMemStrdup(buf); 23056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 2313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 3; 2323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 2333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 23456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx++] = *cur++; 2353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == 0) return; 2373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 23856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 2393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (1) { 2403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur[0] == ':') { 24156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 2423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->hostname = xmlMemStrdup(buf); 24356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 2443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 1; 2453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 2463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor port *= 10; 2473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor port += *cur - '0'; 2483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 2493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (port != 0) ctxt->port = port; 2513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((cur[0] != '/') && (*cur != 0)) 2523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 2533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 2543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur == '/') || (*cur == 0)) { 25656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 2573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->hostname = xmlMemStrdup(buf); 25856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 2593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 2603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 26156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx++] = *cur++; 2623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == 0) 2643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->path = xmlMemStrdup("/"); 2653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 26656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 26756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 2683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (*cur != 0) 26956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx++] = *cur++; 27056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 2713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->path = xmlMemStrdup(buf); 2723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 2743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 2763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPScanProxy: 2773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The proxy URL used to initialize the proxy context 2783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (Re)Initialize the HTTP Proxy context by parsing the URL and finding 2803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the protocol host port it indicates. 2813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Should be like http://myproxy/ or http://myproxy:3128/ 2823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A NULL URL cleans up proxy informations. 2833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 2843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 2863473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPScanProxy(const char *URL) { 2873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const char *cur = URL; 2883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char buf[4096]; 28956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard int indx = 0; 2903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int port = 0; 2913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxy != NULL) { 2933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(proxy); 2943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor proxy = NULL; 2953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxyPort != 0) { 2973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor proxyPort = 0; 2983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 2993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 3003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (URL == NULL) 3013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 3023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Removing HTTP proxy info\n"); 3033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 3043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 3053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "Using HTTP proxy %s\n", URL); 3063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 3073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (URL == NULL) return; 30856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 3093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (*cur != 0) { 3103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) { 31156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 31256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 3133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 3; 3143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 3153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 31656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx++] = *cur++; 3173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 3183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == 0) return; 3193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 32056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 3213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (1) { 3223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (cur[0] == ':') { 32356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 3243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor proxy = xmlMemStrdup(buf); 32556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 3263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 1; 3273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 3283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor port *= 10; 3293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor port += *cur - '0'; 3303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 3313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 3323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (port != 0) proxyPort = port; 3333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((cur[0] != '/') && (*cur != 0)) 3343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 3353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 3363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 3373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur == '/') || (*cur == 0)) { 33856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx] = 0; 3393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor proxy = xmlMemStrdup(buf); 34056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 3413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 3423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 34356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard buf[indx++] = *cur++; 3443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 3453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 3463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPNewCtxt: 3493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL used to initialize the context 3503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Allocate and initialize a new HTTP context. 3523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns an HTTP context or NULL in case of error. 3543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 3553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic xmlNanoHTTPCtxtPtr 3573473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPNewCtxt(const char *URL) { 3583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ret; 3593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt)); 3613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret == NULL) return(NULL); 3623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memset(ret, 0, sizeof(xmlNanoHTTPCtxt)); 3643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->port = 80; 3653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->returnValue = 0; 3663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret->fd = -1; 367f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ret->ContentLength = -1; 3683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPScanURL(ret, URL); 3703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 3723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 3733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPFreeCtxt: 3763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 3773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Frees the context after closing the connection. 3793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 3803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic void 3823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) { 3833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return; 3843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->hostname != NULL) xmlFree(ctxt->hostname); 3853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->protocol != NULL) xmlFree(ctxt->protocol); 3863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->path != NULL) xmlFree(ctxt->path); 3873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->out != NULL) xmlFree(ctxt->out); 3883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->in != NULL) xmlFree(ctxt->in); 3893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) xmlFree(ctxt->contentType); 3903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->location != NULL) xmlFree(ctxt->location); 3913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader); 3923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->state = XML_NANO_HTTP_NONE; 3933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->fd >= 0) closesocket(ctxt->fd); 3943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->fd = -1; 3953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt); 3963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 3973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 3993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPSend: 4003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 4013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Send the input needed to initiate the processing on the server side 403f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * Returns number of bytes sent or -1 on error. 4043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 4053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 406f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillardstatic int 407f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel VeillardxmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char * xmt_ptr, int outlen) { 408f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 409f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int total_sent = 0; 410f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 411f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( (ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL ) ) { 412f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard while (total_sent < outlen) { 413f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int nsent = send(ctxt->fd, xmt_ptr + total_sent, 414f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard outlen - total_sent, 0); 4153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nsent>0) 4163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor total_sent += nsent; 417f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else if ( ( nsent == -1 ) && 418ba6db03c40b3ac223695fe08e96744ab389c6dabDaniel Veillard#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK 419f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ( socket_errno( ) != EAGAIN ) && 420ba6db03c40b3ac223695fe08e96744ab389c6dabDaniel Veillard#endif 421f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ( socket_errno( ) != EWOULDBLOCK ) ) { 422f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 423f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPSend error: %s", 424f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard strerror( socket_errno( ) ) ); 425f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 426f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( total_sent == 0 ) 427f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard total_sent = -1; 428f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 429f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 430f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else { 431f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard /* 432f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ** No data sent 433f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ** Since non-blocking sockets are used, wait for 434f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ** socket to be writable or default timeout prior 435f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ** to retrying. 436f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard */ 437f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 438f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard struct timeval tv; 439f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard fd_set wfd; 440f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 441f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard tv.tv_sec = timeout; 442f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard tv.tv_usec = 0; 443f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard FD_ZERO( &wfd ); 444f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard FD_SET( ctxt->fd, &wfd ); 445f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard (void)select( ctxt->fd + 1, NULL, &wfd, NULL, &tv ); 446f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 44756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard } 4483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 449f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 450f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return total_sent; 4513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 4523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 4543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPRecv: 4553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 4563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Read information coming from the HTTP connection. 4583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This is a blocking call (but it blocks in select(), not read()). 4593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the number of byte read or -1 in case of error. 4613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 4623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int 4643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) { 4653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd_set rfd; 4663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct timeval tv; 4673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (ctxt->state & XML_NANO_HTTP_READ) { 4703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->in == NULL) { 4713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->in = (char *) xmlMalloc(65000 * sizeof(char)); 4723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->in == NULL) { 4733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->last = -1; 474f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 475f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPRecv: Error allocating input memory." ); 4763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 4773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inlen = 65000; 4793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in; 4803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) { 4823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int delta = ctxt->inrptr - ctxt->in; 4833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len = ctxt->inptr - ctxt->inrptr; 4843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memmove(ctxt->in, ctxt->inrptr, len); 4863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inrptr -= delta; 4873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->content -= delta; 4883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inptr -= delta; 4893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 4903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) { 4913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int d_inptr = ctxt->inptr - ctxt->in; 4923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int d_content = ctxt->content - ctxt->in; 4933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int d_inrptr = ctxt->inrptr - ctxt->in; 494f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char * tmp_ptr = ctxt->in; 4953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 4963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inlen *= 2; 497f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen); 4983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->in == NULL) { 499f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 500f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPRecv: %s %d bytes.", 501f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Failed to realloc input buffer to", 502f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->inlen ); 503f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlFree( tmp_ptr ); 5043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->last = -1; 5053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 5063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inptr = ctxt->in + d_inptr; 5083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->content = ctxt->in + d_content; 5093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inrptr = ctxt->in + d_inrptr; 5103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0); 5123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->last > 0) { 5133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inptr += ctxt->last; 5143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->last); 5153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->last == 0) { 5173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 5183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->last == -1) { 5203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (socket_errno()) { 5213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case EINPROGRESS: 5223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case EWOULDBLOCK: 5233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK 5243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case EAGAIN: 5253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 5263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 527f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 528f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ECONNRESET: 529f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case ESHUTDOWN: 530f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( 0 ); 531f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 5323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 533f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 534f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPRecv: recv( ) failure - %s", 535f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard strerror( socket_errno( ) ) ); 536f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return(-1); 5373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tv.tv_sec = timeout; 5413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tv.tv_usec = 0; 5423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor FD_ZERO(&rfd); 5433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor FD_SET(ctxt->fd, &rfd); 5443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 54550f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard if ( (select(ctxt->fd+1, &rfd, NULL, NULL, &tv)<1) 54650f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard#if defined(EINTR) 54750f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard && (errno != EINTR) 54850f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard#endif 54950f3437111a6428b4852740e83db4848b0b09a97Daniel Veillard ) 5503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 5513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 5533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 5543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 5563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPReadLine: 5573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 5583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Read one line in the HTTP server output, usually for extracting 5603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the HTTP protocol informations from the answer header. 5613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns a newly allocated string with a copy of the line, or NULL 5633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * which indicate the end of the input. 5643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 5653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic char * 5673473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) { 5683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char buf[4096]; 5693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *bp = buf; 570f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int rc; 5713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (bp - buf < 4095) { 5733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->inrptr == ctxt->inptr) { 574f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( (rc = xmlNanoHTTPRecv(ctxt)) == 0) { 5753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bp == buf) 5763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 5773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 5783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *bp = 0; 5793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlMemStrdup(buf)); 5803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 581f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else if ( rc == -1 ) { 582f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( NULL ); 583f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 5843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *bp = *ctxt->inrptr++; 5863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*bp == '\n') { 5873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *bp = 0; 5883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlMemStrdup(buf)); 5893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*bp != '\r') 5913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bp++; 5923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 5933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor buf[4095] = 0; 5943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xmlMemStrdup(buf)); 5953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 5963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 5983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 5993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPScanAnswer: 6003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: an HTTP context 6013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @line: an HTTP header line 6023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Try to extract useful informations from the server answer. 6043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * We currently parse and process: 6053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - The HTTP revision/ return code 6063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - The Content-Type 6073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * - The Location for redirrect processing. 6083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, the file descriptor number otherwise 6103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 6113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic void 6133473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) { 6143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor const char *cur = line; 6153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (line == NULL) return; 6173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!strncmp(line, "HTTP/", 5)) { 6193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int version = 0; 6203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int ret = 0; 6213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 5; 6233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 6243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version *= 10; 6253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version += *cur - '0'; 6263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 6273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*cur == '.') { 6293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 6303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur >= '0') && (*cur <= '9')) { 6313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version *= 10; 6323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version += *cur - '0'; 6333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 6343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) 6363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 6373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 6383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor version *= 10; 6393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur != ' ') && (*cur != '\t')) return; 6403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 6413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur < '0') || (*cur > '9')) return; 6423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur >= '0') && (*cur <= '9')) { 6433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret *= 10; 6443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret += *cur - '0'; 6453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 6463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return; 6483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->returnValue = ret; 6493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) { 6503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 13; 6513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 6523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) 6533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->contentType); 6543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->contentType = xmlMemStrdup(cur); 6553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"ContentType:", 12)) { 6563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 12; 6573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) return; 6583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 6593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->contentType = xmlMemStrdup(cur); 6603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Location:", 9)) { 6613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 9; 6623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 6633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->location != NULL) 6643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->location); 6653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->location = xmlMemStrdup(cur); 6663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"WWW-Authenticate:", 17)) { 6673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 17; 6683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 6693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->authHeader != NULL) 6703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->authHeader); 6713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->authHeader = xmlMemStrdup(cur); 6723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Proxy-Authenticate:", 19)) { 6733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur += 19; 6743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((*cur == ' ') || (*cur == '\t')) cur++; 6753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->authHeader != NULL) 6763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(ctxt->authHeader); 6773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->authHeader = xmlMemStrdup(cur); 678f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Length:", 15) ) { 679f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard cur += 15; 680f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->ContentLength = strtol( cur, NULL, 10 ); 6813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 6823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 6853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPConnectAttempt: 68656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard * @addr: a socket adress structure 6873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Attempt a connection to the given IP:port endpoint. It forces 6893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * non-blocking semantic on the socket, and allow 60 seconds for 6903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the host to answer. 6913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, the file descriptor number otherwise 6933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 6943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int 69656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlNanoHTTPConnectAttempt(struct sockaddr *addr) 6973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{ 6983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 6993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd_set wfd; 7003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct timeval tv; 7013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int status; 7023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (s==-1) { 7043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 7053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor perror("socket"); 7063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 707f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 708f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectAttempt: %s - %s", 709f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "socket creation failure", 710f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard strerror( socket_errno( ) ) ); 7113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 7123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef _WINSOCKAPI_ 7153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 7163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor u_long one = 1; 7173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0; 7193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else /* _WINSOCKAPI_ */ 7213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(VMS) 7223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 7233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int enable = 1; 7243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor status = ioctl(s, FIONBIO, &enable); 7253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else /* VMS */ 7273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((status = fcntl(s, F_GETFL, 0)) != -1) { 7283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef O_NONBLOCK 7293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor status |= O_NONBLOCK; 7303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else /* O_NONBLOCK */ 7313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef F_NDELAY 7323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor status |= F_NDELAY; 7333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* F_NDELAY */ 7343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* !O_NONBLOCK */ 7353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor status = fcntl(s, F_SETFL, status); 7363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (status < 0) { 7383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 7393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor perror("nonblocking"); 7403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 741f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 742f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectAttempt: %s - %s", 743f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "error setting non-blocking IO", 744f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard strerror( socket_errno( ) ) ); 7453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor closesocket(s); 7463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 7473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* !VMS */ 7493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* !_WINSOCKAPI_ */ 7503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((connect(s, addr, sizeof(*addr))==-1)) { 7523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch (socket_errno()) { 7533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case EINPROGRESS: 7543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case EWOULDBLOCK: 7553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 7563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor default: 757f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 758f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectAttempt: %s - %s", 759f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "error connecting to HTTP server", 760f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard strerror( socket_errno( ) ) ); 7613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor closesocket(s); 7623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 7633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tv.tv_sec = timeout; 7673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor tv.tv_usec = 0; 7683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor FD_ZERO(&wfd); 7703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor FD_SET(s, &wfd); 7713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor switch(select(s+1, NULL, &wfd, NULL, &tv)) 7733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 7743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case 0: 7753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Time out */ 776f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 777f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectAttempt: %s", 778f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Connect attempt timed out." ); 7793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor closesocket(s); 7803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 7813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor case -1: 7823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Ermm.. ?? */ 783f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 784f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectAttempt: %s - %s", 785f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Error connecting to host", 786f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard strerror( socket_errno( ) ) ); 7873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor closesocket(s); 7883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 7893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 7903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 7913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ( FD_ISSET(s, &wfd) ) { 7923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor SOCKLEN_T len; 7933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = sizeof(status); 7943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0 ) { 7953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Solaris error code */ 796f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 797f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectAttempt: %s - %s", 798f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Error retrieving pending socket errors", 799f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard strerror( socket_errno( ) ) ); 8003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return (-1); 8013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ( status ) { 8033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor closesocket(s); 8043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor errno = status; 805f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 806f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectAttempt: %s - %s", 807f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Error connecting to remote host", 808f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard strerror( status ) ); 8093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return (-1); 8103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 8123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* pbm */ 813f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 814f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectAttempt: %s\n", 815f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Select returned, but descriptor not set for connection.\n" ); 816f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard closesocket(s); 8173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return (-1); 8183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(s); 8213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 8223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 8243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPConnectHost: 8253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @host: the host name 8263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @port: the port number 8273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Attempt a connection to the given host:port endpoint. It tries 8293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the multiple IP provided by the DNS if available. 8303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, the file descriptor number otherwise 8323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 8333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int 8353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPConnectHost(const char *host, int port) 8363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{ 8373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct hostent *h; 8383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct sockaddr *addr; 8393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct in_addr ia; 84056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard struct sockaddr_in sockin; 8413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef SUPPORT_IP6 8423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor struct in6_addr ia6; 84356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard struct sockaddr_in6 sockin6; 8443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 8453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int i; 8463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int s; 8473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(SUPPORT_IP6) && defined(RES_USE_INET6) 8493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!(_res.options & RES_INIT)) 8503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res_init(); 8513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor _res.options |= RES_USE_INET6; 8523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 8533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor h=gethostbyname(host); 8543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (h==NULL) 8553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 856f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard const char * h_err_txt = ""; 857f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard switch ( h_errno ) 858f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard { 859f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case HOST_NOT_FOUND: 860f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard h_err_txt = "Authoritive host not found"; 861f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 862f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 863f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case TRY_AGAIN: 864f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard h_err_txt = 865f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Non-authoritive host not found or server failure."; 866f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 867f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 868f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case NO_RECOVERY: 869f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard h_err_txt = 870f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Non-recoverable errors: FORMERR, REFUSED, or NOTIMP."; 871f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 872f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 873f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard case NO_ADDRESS: 874f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard h_err_txt = "Valid name, no data record of requested type."; 875f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 876f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 877f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard default: 878f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard h_err_txt = "No error text defined."; 879f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 880f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 881f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 882f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectHost: %s '%s' - %s", 883f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Failed to resolve host", host, h_err_txt ); 8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor for(i=0; h->h_addr_list[i]; i++) 8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor { 8893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (h->h_addrtype == AF_INET) { 8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* A records (IPv4) */ 8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memcpy(&ia, h->h_addr_list[i], h->h_length); 89256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard sockin.sin_family = h->h_addrtype; 89356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard sockin.sin_addr = ia; 89456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard sockin.sin_port = htons(port); 89556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard addr = (struct sockaddr *)&sockin; 8963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef SUPPORT_IP6 8973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if (h->h_addrtype == AF_INET6) { 8983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* AAAA records (IPv6) */ 8993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memcpy(&ia6, h->h_addr_list[i], h->h_length); 90056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard sockin6.sin_family = h->h_addrtype; 90156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard sockin6.sin_addr = ia6; 90256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard sockin6.sin_port = htons(port); 90356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard addr = (struct sockaddr *)&sockin6; 9043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 9053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else 9063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; /* for */ 9073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 90856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard s = xmlNanoHTTPConnectAttempt(addr); 9093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (s != -1) 9103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(s); 9113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 9143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 915f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPConnectHost: unable to connect to '%s'.\n", host); 9163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 9173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 9183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 9193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 9223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPOpen: 9233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL to load 9243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @contentType: if available the Content-Type information will be 9253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned at that location 9263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function try to open a connection to the indicated resource 9283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * via HTTP GET. 9293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns NULL in case of failure, otherwise a request handler. 9313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contentType, if provided must be freed by the caller 9323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 9333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid* 9353473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPOpen(const char *URL, char **contentType) { 9363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (contentType != NULL) *contentType = NULL; 937f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return(xmlNanoHTTPMethod(URL, NULL, NULL, contentType, NULL, 0)); 9389403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard} 9399403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 9409403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard/** 9419403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * xmlNanoHTTPOpenRedir: 9429403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @URL: The URL to load 9439403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @contentType: if available the Content-Type information will be 9449403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * returned at that location 9459403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @redir: if availble the redirected URL will be returned 9469403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * 9479403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * This function try to open a connection to the indicated resource 9489403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * via HTTP GET. 9499403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * 9509403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * Returns NULL in case of failure, otherwise a request handler. 9519403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * The contentType, if provided must be freed by the caller 9529403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard */ 9539403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 9549403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillardvoid* 9559403a0495dcbdfa430b669b4e3d689d8e208c687Daniel VeillardxmlNanoHTTPOpenRedir(const char *URL, char **contentType, char **redir) { 9569403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (contentType != NULL) *contentType = NULL; 9579403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redir != NULL) *redir = NULL; 958f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return(xmlNanoHTTPMethodRedir(URL, NULL, NULL, contentType, redir, NULL,0)); 9593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 9603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 9623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPRead: 9633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the HTTP context 9643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @dest: a buffer 9653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @len: the buffer length 9663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function tries to read @len bytes from the existing HTTP connection 9683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and saves them in @dest. This is a blocking call. 9693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the number of byte read. 0 is an indication of an end of connection. 9713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * -1 indicates a parameter error. 9723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 9733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 9743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPRead(void *ctx, void *dest, int len) { 9753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 9763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctx == NULL) return(-1); 9783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (dest == NULL) return(-1); 9793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (len <= 0) return(0); 9803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (ctxt->inptr - ctxt->inrptr < len) { 982f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (xmlNanoHTTPRecv(ctxt) <= 0) break; 9833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->inptr - ctxt->inrptr < len) 9853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = ctxt->inptr - ctxt->inrptr; 9863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor memcpy(dest, ctxt->inrptr, len); 9873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->inrptr += len; 9883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(len); 9893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 9903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 9923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPClose: 9933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the HTTP context 9943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 9953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function closes an HTTP context, it ends up the connection and 9963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * free all data related to it. 9973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 9983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 9993473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPClose(void *ctx) { 10003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 10013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctx == NULL) return; 10033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 10053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 10063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 10089403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * xmlNanoHTTPMethodRedir: 10093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL to load 10103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @method: the HTTP method to use 10113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @input: the input string if any 10123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @contentType: the Content-Type information IN and OUT 10139403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @redir: the redirected URL OUT 10143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @headers: the extra headers 10153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function try to open a connection to the indicated resource 10173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * via HTTP using the given @method, adding the given extra headers 10183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and the input buffer for the request content. 10193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 10203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns NULL in case of failure, otherwise a request handler. 10219403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * The contentType, or redir, if provided must be freed by the caller 10223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 10233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid* 10259403a0495dcbdfa430b669b4e3d689d8e208c687Daniel VeillardxmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input, 1026f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char **contentType, char **redir, 1027f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard const char *headers, int ilen ) { 10283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt; 10293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *bp, *p; 1030f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int blen, ret; 10313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int head; 1032f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int xmt_bytes; 10333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int nbRedirects = 0; 10343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *redirURL = NULL; 10353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (URL == NULL) return(NULL); 10373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (method == NULL) method = "GET"; 10383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPInit(); 10393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 10403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorretry: 10413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (redirURL == NULL) 10423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlNanoHTTPNewCtxt(URL); 10433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 10443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlNanoHTTPNewCtxt(redirURL); 10453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 10463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1047f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( ctxt == NULL ) { 1048f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 1049f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: %s %s.", 1050f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Unable to allocate HTTP context to URI", 1051f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ( ( redirURL == NULL ) ? URL : redirURL ) ); 1052f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( NULL ); 1053f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1054f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 10553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) { 1056f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 1057f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: %s - %s.", 1058f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Not a valid HTTP URI", 1059f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ( ( redirURL == NULL ) ? URL : redirURL ) ); 10603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 10613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (redirURL != NULL) xmlFree(redirURL); 10623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 10633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 10643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->hostname == NULL) { 1065f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 1066f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: %s - %s", 1067f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Failed to identify host in URI", 1068f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ( ( redirURL == NULL ) ? URL : redirURL ) ); 10693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 10709403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) xmlFree(redirURL); 10713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 10723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 10733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxy) { 10743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blen = strlen(ctxt->hostname) * 2 + 16; 10753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlNanoHTTPConnectHost(proxy, proxyPort); 10763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 10773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 10783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blen = strlen(ctxt->hostname); 10793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port); 10803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 10813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret < 0) { 10823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 10839403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) xmlFree(redirURL); 10843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 10853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 10863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->fd = ret; 10873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1088f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (input == NULL) 10893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ilen = 0; 1090f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else 1091f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard blen += 36; 1092f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 10933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (headers != NULL) 1094f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard blen += strlen(headers) + 2; 10953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (contentType && *contentType) 10963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor blen += strlen(*contentType) + 16; 1097f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard blen += strlen(method) + strlen(ctxt->path) + 24; 10983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bp = xmlMalloc(blen); 1099f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( bp == NULL ) { 1100f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlNanoHTTPFreeCtxt( ctxt ); 1101f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 1102f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: %s", 1103f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "Error allocating HTTP header buffer." ); 1104f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( NULL ); 1105f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1106f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1107f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard p = bp; 1108f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 11093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (proxy) { 11103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->port != 80) { 1111f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard p += sprintf( p, "%s http://%s:%d%s", method, ctxt->hostname, 1112f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->port, ctxt->path ); 11133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 11143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 1115f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard p += sprintf( p, "%s http://%s%s", method, 1116f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->hostname, ctxt->path); 11173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 11183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 1119f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard p += sprintf( p, "%s %s", method, ctxt->path); 1120f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1121f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard p += sprintf(p, " HTTP/1.0\r\nHost: %s\r\n", ctxt->hostname); 1122f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1123f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (contentType != NULL && *contentType) 1124f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard p += sprintf(p, "Content-Type: %s\r\n", *contentType); 1125f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1126f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if (headers != NULL) 1127f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard p += sprintf( p, "%s", headers ); 1128f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 11293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (input != NULL) 1130f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard sprintf(p, "Content-Length: %d\r\n\r\n", ilen ); 11313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 11323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor strcpy(p, "\r\n"); 1133f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 11343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 11353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 11363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "-> %s%s", proxy? "(Proxy) " : "", bp); 11373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((blen -= strlen(bp)+1) < 0) 11383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 11393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "ERROR: overflowed buffer by %d bytes\n", -blen); 11403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 11413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->outptr = ctxt->out = bp; 11423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->state = XML_NANO_HTTP_WRITE; 1143f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard blen = strlen( ctxt->out ); 1144f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmt_bytes = xmlNanoHTTPSend(ctxt, ctxt->out, blen ); 1145f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#ifdef DEBUG_HTTP 1146f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( xmt_bytes != blen ) 1147f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 1148f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n", 1149f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmt_bytes, blen, 1150f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "bytes of HTTP headers sent to host", 1151f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->hostname ); 1152f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#endif 1153f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1154f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( input != NULL ) { 1155f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmt_bytes = xmlNanoHTTPSend( ctxt, input, ilen ); 1156f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1157f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#ifdef DEBUG_HTTP 1158f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( xmt_bytes != ilen ) 1159f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlGenericError( xmlGenericErrorContext, 1160f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n", 1161f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmt_bytes, ilen, 1162f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "bytes of HTTP content sent to host", 1163f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ctxt->hostname ); 1164f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard#endif 1165f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1166f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 11673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->state = XML_NANO_HTTP_READ; 11683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor head = 1; 11693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) { 11713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (head && (*p == 0)) { 11723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor head = 0; 11733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->content = ctxt->inrptr; 11743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(p); 11753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 11763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 11773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPScanAnswer(ctxt, p); 11783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 11803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, "<- %s\n", p); 11813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 11823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(p); 11833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 11843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 11853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) && 11863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (ctxt->returnValue < 400)) { 11873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 11883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 11893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "\nRedirect to: %s\n", ctxt->location); 11903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 1191f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard while ( xmlNanoHTTPRecv(ctxt) > 0 ) ; 11923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) { 11933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor nbRedirects++; 11949403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) 11959403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard xmlFree(redirURL); 11963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor redirURL = xmlMemStrdup(ctxt->location); 11973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 11983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto retry; 11993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFreeCtxt(ctxt); 12019403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) xmlFree(redirURL); 12023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 12033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 1204f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard "xmlNanoHTTPMethodRedir: Too many redirects, aborting ...\n"); 12053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 12063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 12073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (contentType != NULL) { 12103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) 12113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *contentType = xmlMemStrdup(ctxt->contentType); 12123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 12133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *contentType = NULL; 12143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12169403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if ((redir != NULL) && (redirURL != NULL)) { 12179403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard *redir = redirURL; 12189403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard } else { 12199403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redirURL != NULL) 12209403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard xmlFree(redirURL); 12219403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard if (redir != NULL) 12229403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard *redir = NULL; 12239403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard } 12249403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 12253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_HTTP 12263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt->contentType != NULL) 12273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 12283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "\nCode %d, content-type '%s'\n\n", 12293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->returnValue, ctxt->contentType); 12303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 12313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 12323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "\nCode %d, no content-type\n\n", 12333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt->returnValue); 12343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 12353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return((void *) ctxt); 12373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 12383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 12409403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * xmlNanoHTTPMethod: 12419403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @URL: The URL to load 12429403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @method: the HTTP method to use 12439403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @input: the input string if any 12449403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @contentType: the Content-Type information IN and OUT 12459403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * @headers: the extra headers 12469403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * 12479403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * This function try to open a connection to the indicated resource 12489403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * via HTTP using the given @method, adding the given extra headers 12499403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * and the input buffer for the request content. 12509403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * 12519403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * Returns NULL in case of failure, otherwise a request handler. 12529403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard * The contentType, if provided must be freed by the caller 12539403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard */ 12549403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 12559403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillardvoid* 12569403a0495dcbdfa430b669b4e3d689d8e208c687Daniel VeillardxmlNanoHTTPMethod(const char *URL, const char *method, const char *input, 1257f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char **contentType, const char *headers, int ilen) { 12589403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard return(xmlNanoHTTPMethodRedir(URL, method, input, contentType, 1259f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard NULL, headers, ilen)); 12609403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard} 12619403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard 12629403a0495dcbdfa430b669b4e3d689d8e208c687Daniel Veillard/** 12633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPFetch: 12643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URL: The URL to load 12653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @filename: the filename where the content should be saved 12663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @contentType: if available the Content-Type information will be 12673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned at that location 12683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 12693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function try to fetch the indicated resource via HTTP GET 12703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and save it's content in the file. 12713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 12723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, 0 incase of success. The contentType, 12733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if provided must be freed by the caller 12743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 12753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 12763473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPFetch(const char *URL, const char *filename, char **contentType) { 1277f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard void *ctxt = NULL; 1278f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char *buf = NULL; 12793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int fd; 12803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len; 12813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ctxt = xmlNanoHTTPOpen(URL, contentType); 12833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return(-1); 12843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 12853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!strcmp(filename, "-")) 12863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd = 0; 12873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 12883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd = open(filename, O_CREAT | O_WRONLY, 00644); 12893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (fd < 0) { 12903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPClose(ctxt); 12913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((contentType != NULL) && (*contentType != NULL)) { 12923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(*contentType); 12933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *contentType = NULL; 12943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 12963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1299f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlNanoHTTPFetchContent( ctxt, &buf, &len ); 1300f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( len > 0 ) { 13013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor write(fd, buf, len); 13023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPClose(ctxt); 13053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor close(fd); 13063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 13073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 13103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPSave: 13113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt: the HTTP context 13123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @filename: the filename where the content should be saved 13133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This function saves the output of the HTTP transaction to a file 13153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * It closes and free the context at the end 13163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -1 in case of failure, 0 incase of success. 13183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 13203473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPSave(void *ctxt, const char *filename) { 1321e392497e4c4313382c3c20903d09a69f0948f721Daniel Veillard char *buf = NULL; 13223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int fd; 13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor int len; 13243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return(-1); 13263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (!strcmp(filename, "-")) 13283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd = 0; 13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 13303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor fd = open(filename, O_CREAT | O_WRONLY); 13313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (fd < 0) { 13323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPClose(ctxt); 13333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 13343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1337f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlNanoHTTPFetchContent( ctxt, &buf, &len ); 1338f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( len > 0 ) { 13393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor write(fd, buf, len); 13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPClose(ctxt); 13433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPReturnCode: 13483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the HTTP context 13493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13505e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Get the latest HTTP return code received 13515e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 13523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the HTTP return code for the request. 13533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint 13553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPReturnCode(void *ctx) { 13563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 13573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return(-1); 13593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->returnValue); 13613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 13643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlNanoHTTPAuthHeader: 13653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx: the HTTP context 13663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 13675e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * Get the authentication header of an HTTP context 13685e2dace1ca6fbb023d1ce848d4e98deefbbfec31Daniel Veillard * 13693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the stashed value of the WWW-Authenticate or Proxy-Authenticate 13703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * header. 13713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 13723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst char * 13733473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNanoHTTPAuthHeader(void *ctx) { 13743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 13753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ctxt == NULL) return(NULL); 13773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ctxt->authHeader); 13793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1381f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard/** 1382f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * xmlNanoHTTPContentLength 1383f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * @ctx: the HTTP context 1384f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * 1385f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * Return the specified content length from the HTTP header. Note that 1386f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * a value of -1 indicates that the content length element was not included in 1387f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * the response header. 1388f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard */ 1389f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillardint 1390f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel VeillardxmlNanoHTTPContentLength( void * ctx ) { 1391f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlNanoHTTPCtxtPtr ctxt = ctx; 1392f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1393f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( ( ctxt == NULL ) ? -1 : ctxt->ContentLength ); 1394f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 1395f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1396f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard/** 1397f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * xmlNanoHTTPFetchContent 1398f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * @ctx: the HTTP context 1399f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * @ptr: pointer to set to the content buffer. 1400f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * @len: integer pointer to hold the length of the content 1401f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * 1402f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * Returns 0 if all the content was read and available, returns 1403f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * -1 if received content length was less than specified or an error 1404f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard * occurred. 1405f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard */ 1406f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillardint 1407f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel VeillardxmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ) { 1408f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard xmlNanoHTTPCtxtPtr ctxt = ctx; 1409f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1410f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int rc = 0; 1411f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int cur_lgth; 1412f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int rcvd_lgth; 1413f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard int dummy_int; 1414f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard char * dummy_ptr = NULL; 1415f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1416f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard /* Dummy up return input parameters if not provided */ 1417f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1418f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( len == NULL ) 1419f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard len = &dummy_int; 1420f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1421f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( ptr == NULL ) 1422f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard ptr = &dummy_ptr; 1423f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1424f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard /* But can't work without the context pointer */ 1425f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1426f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( ( ctxt == NULL ) || ( ctxt->content == NULL ) ) { 1427f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard *len = 0; 1428f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard *ptr = NULL; 1429f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( -1 ); 1430f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1431f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1432f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard rcvd_lgth = ctxt->inptr - ctxt->content; 1433f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1434f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard while ( (cur_lgth = xmlNanoHTTPRecv( ctxt )) > 0 ) { 1435f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1436f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard rcvd_lgth += cur_lgth; 1437f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( (ctxt->ContentLength > 0) && (rcvd_lgth >= ctxt->ContentLength) ) 1438f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard break; 1439f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard } 1440f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1441f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard *ptr = ctxt->content; 1442f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard *len = rcvd_lgth; 1443f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1444f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard if ( ( ctxt->ContentLength > 0 ) && ( rcvd_lgth < ctxt->ContentLength ) ) 1445f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard rc = -1; 1446f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard else if ( rcvd_lgth == 0 ) 1447f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard rc = -1; 1448f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 1449f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard return ( rc ); 1450f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard} 1451f012a64d13d85d53eac0d4d6625508109e7c9e9dDaniel Veillard 14523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef STANDALONE 14533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint main(int argc, char **argv) { 14543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor char *contentType = NULL; 14553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 14563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (argv[1] != NULL) { 14573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (argv[2] != NULL) 14583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFetch(argv[1], argv[2], &contentType); 14593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 14603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPFetch(argv[1], "-", &contentType); 14613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (contentType != NULL) xmlFree(contentType); 14623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 14633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 14643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s: minimal HTTP GET implementation\n", argv[0]); 14653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 14663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "\tusage %s [ URL [ filename ] ]\n", argv[0]); 14673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNanoHTTPCleanup(); 14693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlMemoryDump(); 14703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 14713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 14723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* STANDALONE */ 14733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else /* !LIBXML_HTTP_ENABLED */ 14743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef STANDALONE 14753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <stdio.h> 14763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint main(int argc, char **argv) { 14773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlGenericError(xmlGenericErrorContext, 14783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor "%s : HTTP support not compiled in\n", argv[0]); 14793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 14803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 14813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* STANDALONE */ 14823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_HTTP_ENABLED */ 1483