15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * nanohttp.c: minimalist HTTP GET implementation to fetch external subsets. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * focuses on size, streamability, reentrancy and portability 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is clearly not a general purpose HTTP implementation 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If you look for one, check: 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.w3.org/Library/ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * daniel@veillard.com 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEED_SOCKETS 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXML 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_HTTP_ENABLED 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_STDLIB_H 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_UNISTD_H 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TYPES_H 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_SOCKET_H 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_NETINET_IN_H 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <netinet/in.h> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ARPA_INET_H 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <arpa/inet.h> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_NETDB_H 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <netdb.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_RESOLV_H 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ARPA_NAMESER_H 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <arpa/nameser.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <resolv.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_FCNTL_H 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ERRNO_H 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TIME_H 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_POLL_H 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_SELECT_H 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/select.h> 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <poll.h> 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_STRINGS_H 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <strings.h> 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SUPPORT_IP6 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <resolv.h> 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ZLIB_H 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <zlib.h> 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef VMS 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stropts> 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_SOCKLEN_T unsigned int 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SOCKET int 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__MINGW32__) || defined(_WIN32_WCE) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _WINSOCKAPI_ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <wsockcompat.h> 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock2.h> 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef XML_SOCKLEN_T 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_SOCKLEN_T unsigned int 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/globals.h> 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlerror.h> 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h> 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parser.h> /* for xmlStr(n)casecmp() */ 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/nanohttp.h> 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/globals.h> 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/uri.h> 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A couple portability macros 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _WINSOCKAPI_ 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(__BEOS__) || defined(__HAIKU__) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define closesocket(s) close(s) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SOCKET int 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __BEOS__ 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PF_INET 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PF_INET AF_INET 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef XML_SOCKLEN_T 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_SOCKLEN_T unsigned int 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SOCKET 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SOCKET int 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef STANDALONE 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_HTTP 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define xmlStrncasecmp(a, b, n) strncasecmp((char *)a, (char *)b, n) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define xmlStrcasecmpi(a, b) strcasecmp((char *)a, (char *)b) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_NANO_HTTP_MAX_REDIR 10 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_NANO_HTTP_CHUNK 4096 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_NANO_HTTP_CLOSED 0 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_NANO_HTTP_WRITE 1 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_NANO_HTTP_READ 2 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_NANO_HTTP_NONE 4 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct xmlNanoHTTPCtxt { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *protocol; /* the protocol name */ 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *hostname; /* the host name */ 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port; /* the port */ 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *path; /* the path within the URL */ 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *query; /* the query string */ 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SOCKET fd; /* the file descriptor for the socket */ 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int state; /* WRITE / READ / CLOSED */ 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *out; /* buffer sent (zero terminated) */ 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *outptr; /* index within the buffer sent */ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *in; /* the receiving buffer */ 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *content; /* the start of the content */ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *inptr; /* the next byte to read from network */ 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *inrptr; /* the next byte to give back to the client */ 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int inlen; /* len of the input buffer */ 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last; /* return code for last operation */ 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int returnValue; /* the protocol return value */ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int version; /* the protocol version */ 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ContentLength; /* specified content length from HTTP header */ 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *contentType; /* the MIME type for the input */ 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *location; /* the new URL in case of redirect */ 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *authHeader; /* contents of {WWW,Proxy}-Authenticate header */ 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *encoding; /* encoding extracted from the contentType */ 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *mimeType; /* Mime-Type extracted from the contentType */ 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ZLIB_H 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z_stream *strm; /* Zlib stream object */ 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int usesGzip; /* "Content-Encoding: gzip" was detected */ 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlNanoHTTPCtxt, *xmlNanoHTTPCtxtPtr; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int initialized = 0; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *proxy = NULL; /* the proxy name if any */ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int proxyPort; /* the proxy port if any */ 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned int timeout = 60;/* the select() timeout in seconds */ 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlHTTPErrMemory: 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra: extra informations 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle an out of memory condition 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlHTTPErrMemory(const char *extra) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlSimpleError(XML_FROM_HTTP, XML_ERR_NO_MEMORY, NULL, NULL, extra); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A portability function 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int socket_errno(void) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WINSOCKAPI_ 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(WSAGetLastError()); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(errno); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SUPPORT_IP6 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int have_ipv6(void) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int s; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = socket (AF_INET6, SOCK_STREAM, 0); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s != -1) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close (s); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (1); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPInit: 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initialize the HTTP protocol layer. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Currently it just checks for proxy informations 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPInit(void) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *env; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WINSOCKAPI_ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WSADATA wsaData; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialized) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WINSOCKAPI_ 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy == NULL) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxyPort = 80; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) env = getenv("no_proxy"); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env && ((env[0] == '*') && (env[1] == 0))) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto done; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) env = getenv("http_proxy"); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env != NULL) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPScanProxy(env); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto done; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) env = getenv("HTTP_PROXY"); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env != NULL) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPScanProxy(env); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto done; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done: 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized = 1; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPCleanup: 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Cleanup the HTTP protocol layer. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPCleanup(void) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy != NULL) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(proxy); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy = NULL; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WINSOCKAPI_ 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialized) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WSACleanup(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized = 0; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPScanURL: 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an HTTP context 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: The URL used to initialize the context 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (Re)Initialize an HTTP context by parsing the URL and finding 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the protocol host port and path it indicates. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlURIPtr uri; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clear any existing data from the context 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->protocol != NULL) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->protocol); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->protocol = NULL; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->hostname != NULL) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->hostname); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->hostname = NULL; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->path != NULL) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->path); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->path = NULL; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->query != NULL) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->query); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->query = NULL; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URL == NULL) return; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uri = xmlParseURIRaw(URL, 1); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri == NULL) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((uri->scheme == NULL) || (uri->server == NULL)) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeURI(uri); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->protocol = xmlMemStrdup(uri->scheme); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->hostname = xmlMemStrdup(uri->server); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri->path != NULL) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->path = xmlMemStrdup(uri->path); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->path = xmlMemStrdup("/"); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri->query != NULL) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->query = xmlMemStrdup(uri->query); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri->port != 0) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->port = uri->port; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeURI(uri); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPScanProxy: 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: The proxy URL used to initialize the proxy context 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (Re)Initialize the HTTP Proxy context by parsing the URL and finding 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the protocol host port it indicates. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Should be like http://myproxy/ or http://myproxy:3128/ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A NULL URL cleans up proxy informations. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPScanProxy(const char *URL) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlURIPtr uri; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy != NULL) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(proxy); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy = NULL; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxyPort = 0; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URL == NULL) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Removing HTTP proxy info\n"); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Using HTTP proxy %s\n", URL); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URL == NULL) return; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uri = xmlParseURIRaw(URL, 1); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((uri == NULL) || (uri->scheme == NULL) || 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (strcmp(uri->scheme, "http")) || (uri->server == NULL)) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Syntax Error\n"); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri != NULL) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeURI(uri); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy = xmlMemStrdup(uri->server); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri->port != 0) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxyPort = uri->port; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeURI(uri); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPNewCtxt: 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: The URL used to initialize the context 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate and initialize a new HTTP context. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns an HTTP context or NULL in case of error. 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlNanoHTTPCtxtPtr 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPNewCtxt(const char *URL) { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ret; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt)); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHTTPErrMemory("allocating context"); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlNanoHTTPCtxt)); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->port = 80; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->returnValue = 0; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->fd = -1; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->ContentLength = -1; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPScanURL(ret, URL); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPFreeCtxt: 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an HTTP context 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Frees the context after closing the connection. 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) return; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->hostname != NULL) xmlFree(ctxt->hostname); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->protocol != NULL) xmlFree(ctxt->protocol); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->path != NULL) xmlFree(ctxt->path); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->query != NULL) xmlFree(ctxt->query); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->out != NULL) xmlFree(ctxt->out); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->in != NULL) xmlFree(ctxt->in); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->contentType != NULL) xmlFree(ctxt->contentType); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->encoding != NULL) xmlFree(ctxt->encoding); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->mimeType != NULL) xmlFree(ctxt->mimeType); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->location != NULL) xmlFree(ctxt->location); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ZLIB_H 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->strm != NULL) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inflateEnd(ctxt->strm); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->strm); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = XML_NANO_HTTP_NONE; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->fd >= 0) closesocket(ctxt->fd); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->fd = -1; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPSend: 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an HTTP context 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Send the input needed to initiate the processing on the server side 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns number of bytes sent or -1 on error. 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char *xmt_ptr, int outlen) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_sent = 0; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_POLL_H 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pollfd p; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval tv; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd_set wfd; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL)) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (total_sent < outlen) { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nsent = send(ctxt->fd, xmt_ptr + total_sent, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outlen - total_sent, 0); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nsent > 0) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_sent += nsent; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ((nsent == -1) && 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (socket_errno() != EAGAIN) && 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (socket_errno() != EWOULDBLOCK)) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "send failed\n"); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (total_sent == 0) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_sent = -1; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * No data sent 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Since non-blocking sockets are used, wait for 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * socket to be writable or default timeout prior 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to retrying. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_POLL_H 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _WINSOCKAPI_ 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->fd > FD_SETSIZE) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv.tv_sec = timeout; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv.tv_usec = 0; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_ZERO(&wfd); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(push) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(disable: 4018) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_SET(ctxt->fd, &wfd); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(pop) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void) select(ctxt->fd + 1, NULL, &wfd, NULL, &tv); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p.fd = ctxt->fd; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p.events = POLLOUT; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void) poll(&p, 1, timeout * 1000); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !HAVE_POLL_H */ 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_sent; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPRecv: 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an HTTP context 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read information coming from the HTTP connection. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a blocking call (but it blocks in select(), not read()). 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of byte read or -1 in case of error. 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_POLL_H 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pollfd p; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd_set rfd; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval tv; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (ctxt->state & XML_NANO_HTTP_READ) { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->in == NULL) { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char)); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->in == NULL) { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHTTPErrMemory("allocating input"); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->last = -1; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inlen = 65000; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int delta = ctxt->inrptr - ctxt->in; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = ctxt->inptr - ctxt->inrptr; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memmove(ctxt->in, ctxt->inrptr, len); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inrptr -= delta; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->content -= delta; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inptr -= delta; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d_inptr = ctxt->inptr - ctxt->in; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d_content = ctxt->content - ctxt->in; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d_inrptr = ctxt->inrptr - ctxt->in; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *tmp_ptr = ctxt->in; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inlen *= 2; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->in == NULL) { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHTTPErrMemory("allocating input buffer"); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(tmp_ptr); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->last = -1; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inptr = ctxt->in + d_inptr; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->content = ctxt->in + d_content; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inrptr = ctxt->in + d_inrptr; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->last > 0) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inptr += ctxt->last; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ctxt->last); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->last == 0) { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->last == -1) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (socket_errno()) { 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EINPROGRESS: 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EWOULDBLOCK: 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EAGAIN: 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ECONNRESET: 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ESHUTDOWN: 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n"); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_POLL_H 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p.fd = ctxt->fd; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p.events = POLLIN; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((poll(&p, 1, timeout * 1000) < 1) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(EINTR) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (errno != EINTR) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !HAVE_POLL_H */ 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _WINSOCKAPI_ 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->fd > FD_SETSIZE) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv.tv_sec = timeout; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv.tv_usec = 0; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_ZERO(&rfd); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(push) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(disable: 4018) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_SET(ctxt->fd, &rfd); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(pop) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(EINTR) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (errno != EINTR) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !HAVE_POLL_H */ 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPReadLine: 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an HTTP context 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read one line in the HTTP server output, usually for extracting 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the HTTP protocol informations from the answer header. 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a newly allocated string with a copy of the line, or NULL 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * which indicate the end of the input. 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char * 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[4096]; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *bp = buf; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (bp - buf < 4095) { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->inrptr == ctxt->inptr) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( (rc = xmlNanoHTTPRecv(ctxt)) == 0) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bp == buf) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp = 0; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlMemStrdup(buf)); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ( rc == -1 ) { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( NULL ); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp = *ctxt->inrptr++; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*bp == '\n') { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp = 0; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlMemStrdup(buf)); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*bp != '\r') 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bp++; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf[4095] = 0; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlMemStrdup(buf)); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPScanAnswer: 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an HTTP context 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @line: an HTTP header line 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try to extract useful informations from the server answer. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We currently parse and process: 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - The HTTP revision/ return code 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - The Content-Type, Mime-Type and charset used 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - The Location for redirect processing. 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, the file descriptor number otherwise 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *cur = line; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (line == NULL) return; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!strncmp(line, "HTTP/", 5)) { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int version = 0; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += 5; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur >= '0') && (*cur <= '9')) { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version *= 10; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version += *cur - '0'; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur++; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*cur == '.') { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur++; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*cur >= '0') && (*cur <= '9')) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version *= 10; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version += *cur - '0'; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur++; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur >= '0') && (*cur <= '9')) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur++; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version *= 10; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*cur != ' ') && (*cur != '\t')) return; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur == ' ') || (*cur == '\t')) cur++; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*cur < '0') || (*cur > '9')) return; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur >= '0') && (*cur <= '9')) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret *= 10; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret += *cur - '0'; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur++; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->returnValue = ret; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->version = version; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *charset, *last, *mime; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += 13; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur == ' ') || (*cur == '\t')) cur++; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->contentType != NULL) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->contentType); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->contentType = xmlMemStrdup(cur); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mime = (const xmlChar *) cur; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = mime; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*last != 0) && (*last != ' ') && (*last != '\t') && 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*last != ';') && (*last != ',')) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last++; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->mimeType != NULL) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->mimeType); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->mimeType = (char *) xmlStrndup(mime, last - mime); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) charset = xmlStrstr(BAD_CAST ctxt->contentType, BAD_CAST "charset="); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (charset != NULL) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) charset += 8; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = charset; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*last != 0) && (*last != ' ') && (*last != '\t') && 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*last != ';') && (*last != ',')) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last++; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->encoding != NULL) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->encoding); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->encoding = (char *) xmlStrndup(charset, last - charset); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"ContentType:", 12)) { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *charset, *last, *mime; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += 12; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->contentType != NULL) return; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur == ' ') || (*cur == '\t')) cur++; 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->contentType = xmlMemStrdup(cur); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mime = (const xmlChar *) cur; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = mime; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*last != 0) && (*last != ' ') && (*last != '\t') && 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*last != ';') && (*last != ',')) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last++; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->mimeType != NULL) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->mimeType); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->mimeType = (char *) xmlStrndup(mime, last - mime); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) charset = xmlStrstr(BAD_CAST ctxt->contentType, BAD_CAST "charset="); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (charset != NULL) { 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) charset += 8; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = charset; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*last != 0) && (*last != ' ') && (*last != '\t') && 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*last != ';') && (*last != ',')) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last++; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->encoding != NULL) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->encoding); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->encoding = (char *) xmlStrndup(charset, last - charset); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Location:", 9)) { 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += 9; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur == ' ') || (*cur == '\t')) cur++; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->location != NULL) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->location); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*cur == '/') { 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *tmp_http = xmlStrdup(BAD_CAST "http://"); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *tmp_loc = 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlStrcat(tmp_http, (const xmlChar *) ctxt->hostname); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->location = 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (char *) xmlStrcat (tmp_loc, (const xmlChar *) cur); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->location = xmlMemStrdup(cur); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"WWW-Authenticate:", 17)) { 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += 17; 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur == ' ') || (*cur == '\t')) cur++; 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->authHeader != NULL) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->authHeader); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->authHeader = xmlMemStrdup(cur); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Proxy-Authenticate:", 19)) { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += 19; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur == ' ') || (*cur == '\t')) cur++; 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->authHeader != NULL) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt->authHeader); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->authHeader = xmlMemStrdup(cur); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ZLIB_H 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Encoding:", 17) ) { 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += 17; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((*cur == ' ') || (*cur == '\t')) cur++; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( !xmlStrncasecmp( BAD_CAST cur, BAD_CAST"gzip", 4) ) { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->usesGzip = 1; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm = xmlMalloc(sizeof(z_stream)); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->strm != NULL) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->zalloc = Z_NULL; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->zfree = Z_NULL; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->opaque = Z_NULL; 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->avail_in = 0; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->next_in = Z_NULL; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inflateInit2( ctxt->strm, 31 ); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Length:", 15) ) { 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += 15; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->ContentLength = strtol( cur, NULL, 10 ); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPConnectAttempt: 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @addr: a socket address structure 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Attempt a connection to the given IP:port endpoint. It forces 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * non-blocking semantic on the socket, and allow 60 seconds for 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the host to answer. 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, the file descriptor number otherwise 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPConnectAttempt(struct sockaddr *addr) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_POLL_H 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd_set wfd; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WINSOCKAPI_ 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd_set xfd; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval tv; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !HAVE_POLL_H */ 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pollfd p; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !HAVE_POLL_H */ 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int status; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int addrlen; 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SOCKET s; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SUPPORT_IP6 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr->sa_family == AF_INET6) { 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrlen = sizeof(struct sockaddr_in6); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrlen = sizeof(struct sockaddr_in); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s == -1) { 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("socket"); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n"); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WINSOCKAPI_ 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u_long one = 1; 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* _WINSOCKAPI_ */ 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(VMS) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int enable = 1; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = ioctl(s, FIONBIO, &enable); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* VMS */ 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__BEOS__) && !defined(__HAIKU__) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool noblock = true; 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock, 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(noblock)); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* __BEOS__ */ 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((status = fcntl(s, F_GETFL, 0)) != -1) { 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef O_NONBLOCK 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status |= O_NONBLOCK; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* O_NONBLOCK */ 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef F_NDELAY 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status |= F_NDELAY; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* F_NDELAY */ 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !O_NONBLOCK */ 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = fcntl(s, F_SETFL, status); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status < 0) { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("nonblocking"); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n"); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closesocket(s); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !__BEOS__ */ 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !VMS */ 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !_WINSOCKAPI_ */ 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connect(s, addr, addrlen) == -1) { 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (socket_errno()) { 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EINPROGRESS: 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EWOULDBLOCK: 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "error connecting to HTTP server"); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closesocket(s); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_POLL_H 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv.tv_sec = timeout; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv.tv_usec = 0; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(push) 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(disable: 4018) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _WINSOCKAPI_ 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s > FD_SETSIZE) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_ZERO(&wfd); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_SET(s, &wfd); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WINSOCKAPI_ 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_ZERO(&xfd); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_SET(s, &xfd); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (select(s + 1, NULL, &wfd, &xfd, &tv)) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (select(s + 1, NULL, &wfd, NULL, &tv)) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(pop) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !HAVE_POLL_H */ 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p.fd = s; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p.events = POLLOUT; 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (poll(&p, 1, timeout * 1000)) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !HAVE_POLL_H */ 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Time out */ 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out"); 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closesocket(s); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case -1: 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ermm.. ?? */ 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed"); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closesocket(s); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_POLL_H 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FD_ISSET(s, &wfd) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WINSOCKAPI_ 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || FD_ISSET(s, &xfd) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !HAVE_POLL_H */ 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p.revents == POLLOUT) 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !HAVE_POLL_H */ 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SOCKLEN_T len; 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = sizeof(status); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SO_ERROR 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &status, &len) < 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0) { 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Solaris error code */ 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n"); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status) { 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Error connecting to remote host"); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closesocket(s); 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errno = status; 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* pbm */ 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "select failed\n"); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closesocket(s); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (s); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPConnectHost: 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @host: the host name 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @port: the port number 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Attempt a connection to the given host:port endpoint. It tries 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the multiple IP provided by the DNS if available. 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, the file descriptor number otherwise 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPConnectHost(const char *host, int port) 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct hostent *h; 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sockaddr *addr = NULL; 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct in_addr ia; 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sockaddr_in sockin; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SUPPORT_IP6 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct in6_addr ia6; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sockaddr_in6 sockin6; 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int s; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset (&sockin, 0, sizeof(sockin)); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SUPPORT_IP6 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset (&sockin6, 0, sizeof(sockin6)); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && defined(RES_USE_INET6) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (have_ipv6 ()) 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(_res.options & RES_INIT)) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res_init(); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _res.options |= RES_USE_INET6; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (have_ipv6 ()) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_GETADDRINFO) && (defined(SUPPORT_IP6) || defined(_WIN32)) 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int status; 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct addrinfo hints, *res, *result; 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = NULL; 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset (&hints, 0,sizeof(hints)); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hints.ai_socktype = SOCK_STREAM; 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = getaddrinfo (host, NULL, &hints, &result); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status) { 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "getaddrinfo failed\n"); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (res = result; res; res = res->ai_next) { 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res->ai_family == AF_INET) { 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res->ai_addrlen > sizeof(sockin)) { 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freeaddrinfo (result); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy (&sockin, res->ai_addr, res->ai_addrlen); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockin.sin_port = htons (port); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr = (struct sockaddr *)&sockin; 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SUPPORT_IP6 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (have_ipv6 () && (res->ai_family == AF_INET6)) { 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res->ai_addrlen > sizeof(sockin6)) { 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freeaddrinfo (result); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy (&sockin6, res->ai_addr, res->ai_addrlen); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockin6.sin6_port = htons (port); 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr = (struct sockaddr *)&sockin6; 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; /* for */ 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = xmlNanoHTTPConnectAttempt (addr); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s != -1) { 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freeaddrinfo (result); 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (s); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result) 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freeaddrinfo (result); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32) 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(HAVE_GETADDRINFO) || !defined(_WIN32) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h = gethostbyname (host); 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (h == NULL) { 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Okay, I got fed up by the non-portability of this error message 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extraction code. it work on Linux, if it work on your platform 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and one want to enable it, send me the defined(foobar) needed 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux) 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *h_err_txt = ""; 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (h_errno) { 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HOST_NOT_FOUND: 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h_err_txt = "Authoritive host not found"; 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TRY_AGAIN: 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h_err_txt = 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Non-authoritive host not found or server failure."; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NO_RECOVERY: 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h_err_txt = 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Non-recoverable errors: FORMERR, REFUSED, or NOTIMP."; 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NO_ADDRESS: 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h_err_txt = 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Valid name, no data record of requested type."; 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) h_err_txt = "No error text defined."; 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, h_err_txt); 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "Failed to resolve host"); 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; h->h_addr_list[i]; i++) { 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (h->h_addrtype == AF_INET) { 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* A records (IPv4) */ 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((unsigned int) h->h_length > sizeof(ia)) { 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy (&ia, h->h_addr_list[i], h->h_length); 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockin.sin_family = h->h_addrtype; 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockin.sin_addr = ia; 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockin.sin_port = (u_short)htons ((unsigned short)port); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr = (struct sockaddr *) &sockin; 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SUPPORT_IP6 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (have_ipv6 () && (h->h_addrtype == AF_INET6)) { 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* AAAA records (IPv6) */ 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((unsigned int) h->h_length > sizeof(ia6)) { 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy (&ia6, h->h_addr_list[i], h->h_length); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockin6.sin6_family = h->h_addrtype; 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockin6.sin6_addr = ia6; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockin6.sin6_port = htons (port); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr = (struct sockaddr *) &sockin6; 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; /* for */ 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = xmlNanoHTTPConnectAttempt (addr); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s != -1) 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (s); 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xmlNanoHTTPConnectHost: unable to connect to '%s'.\n", 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host); 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPOpen: 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: The URL to load 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @contentType: if available the Content-Type information will be 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returned at that location 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function try to open a connection to the indicated resource 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * via HTTP GET. 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns NULL in case of failure, otherwise a request handler. 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contentType, if provided must be freed by the caller 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPOpen(const char *URL, char **contentType) { 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contentType != NULL) *contentType = NULL; 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlNanoHTTPMethod(URL, NULL, NULL, contentType, NULL, 0)); 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPOpenRedir: 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: The URL to load 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @contentType: if available the Content-Type information will be 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returned at that location 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @redir: if available the redirected URL will be returned 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function try to open a connection to the indicated resource 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * via HTTP GET. 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns NULL in case of failure, otherwise a request handler. 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contentType, if provided must be freed by the caller 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPOpenRedir(const char *URL, char **contentType, char **redir) { 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contentType != NULL) *contentType = NULL; 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redir != NULL) *redir = NULL; 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlNanoHTTPMethodRedir(URL, NULL, NULL, contentType, redir, NULL,0)); 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPRead: 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dest: a buffer 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the buffer length 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function tries to read @len bytes from the existing HTTP connection 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and saves them in @dest. This is a blocking call. 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of byte read. 0 is an indication of an end of connection. 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -1 indicates a parameter error. 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPRead(void *ctx, void *dest, int len) { 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ZLIB_H 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = 0; 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int orig_avail_in; 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int z_ret; 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctx == NULL) return(-1); 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dest == NULL) return(-1); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len <= 0) return(0); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ZLIB_H 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->usesGzip == 1) { 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->strm == NULL) return(0); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->next_out = dest; 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->avail_out = len; 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->avail_in = ctxt->inptr - ctxt->inrptr; 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (ctxt->strm->avail_out > 0 && 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ctxt->strm->avail_in > 0 || xmlNanoHTTPRecv(ctxt) > 0)) { 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orig_avail_in = ctxt->strm->avail_in = 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inptr - ctxt->inrptr - bytes_read; 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->strm->next_in = BAD_CAST (ctxt->inrptr + bytes_read); 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z_ret = inflate(ctxt->strm, Z_NO_FLUSH); 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read += orig_avail_in - ctxt->strm->avail_in; 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (z_ret != Z_OK) break; 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inrptr += bytes_read; 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(len - ctxt->strm->avail_out); 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (ctxt->inptr - ctxt->inrptr < len) { 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlNanoHTTPRecv(ctxt) <= 0) break; 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->inptr - ctxt->inrptr < len) 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = ctxt->inptr - ctxt->inrptr; 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(dest, ctxt->inrptr, len); 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->inrptr += len; 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(len); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPClose: 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function closes an HTTP context, it ends up the connection and 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * free all data related to it. 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPClose(void *ctx) { 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctx == NULL) return; 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFreeCtxt(ctxt); 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPMethodRedir: 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: The URL to load 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @method: the HTTP method to use 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @input: the input string if any 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @contentType: the Content-Type information IN and OUT 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @redir: the redirected URL OUT 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @headers: the extra headers 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ilen: input length 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function try to open a connection to the indicated resource 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * via HTTP using the given @method, adding the given extra headers 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and the input buffer for the request content. 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns NULL in case of failure, otherwise a request handler. 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contentType, or redir, if provided must be freed by the caller 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input, 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **contentType, char **redir, 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *headers, int ilen ) { 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt; 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *bp, *p; 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int blen, ret; 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbRedirects = 0; 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *redirURL = NULL; 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int xmt_bytes; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URL == NULL) return(NULL); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (method == NULL) method = "GET"; 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPInit(); 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)retry: 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirURL == NULL) 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt = xmlNanoHTTPNewCtxt(URL); 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt = xmlNanoHTTPNewCtxt(redirURL); 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->location = xmlMemStrdup(redirURL); 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( ctxt == NULL ) { 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( NULL ); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) { 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Not a valid HTTP URI"); 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFreeCtxt(ctxt); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirURL != NULL) xmlFree(redirURL); 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->hostname == NULL) { 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlIOErr(XML_FROM_HTTP, XML_HTTP_UNKNOWN_HOST, 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to identify host in URI"); 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFreeCtxt(ctxt); 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirURL != NULL) xmlFree(redirURL); 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy) { 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen = strlen(ctxt->hostname) * 2 + 16; 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlNanoHTTPConnectHost(proxy, proxyPort); 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen = strlen(ctxt->hostname); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret < 0) { 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFreeCtxt(ctxt); 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirURL != NULL) xmlFree(redirURL); 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->fd = ret; 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input == NULL) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ilen = 0; 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen += 36; 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers != NULL) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen += strlen(headers) + 2; 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contentType && *contentType) 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* reserve for string plus 'Content-Type: \r\n" */ 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen += strlen(*contentType) + 16; 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->query != NULL) 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1 for '?' */ 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen += strlen(ctxt->query) + 1; 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen += strlen(method) + strlen(ctxt->path) + 24; 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ZLIB_H 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* reserve for possible 'Accept-Encoding: gzip' string */ 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen += 23; 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->port != 80) { 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* reserve space for ':xxxxx', incl. potential proxy */ 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy) 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen += 12; 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen += 6; 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bp = (char*)xmlMallocAtomic(blen); 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( bp == NULL ) { 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFreeCtxt( ctxt ); 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHTTPErrMemory("allocating header buffer"); 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( NULL ); 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = bp; 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxy) { 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->port != 80) { 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf( p, blen - (p - bp), "%s http://%s:%d%s", 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method, ctxt->hostname, 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->port, ctxt->path ); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf( p, blen - (p - bp), "%s http://%s%s", method, 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->hostname, ctxt->path); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf( p, blen - (p - bp), "%s %s", method, ctxt->path); 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->query != NULL) 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf( p, blen - (p - bp), "?%s", ctxt->query); 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->port == 80) { 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s\r\n", 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->hostname); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s:%d\r\n", 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->hostname, ctxt->port); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_ZLIB_H 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf(p, blen - (p - bp), "Accept-Encoding: gzip\r\n"); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contentType != NULL && *contentType) 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf(p, blen - (p - bp), "Content-Type: %s\r\n", *contentType); 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers != NULL) 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += snprintf( p, blen - (p - bp), "%s", headers ); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input != NULL) 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(p, blen - (p - bp), "Content-Length: %d\r\n\r\n", ilen ); 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(p, blen - (p - bp), "\r\n"); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "-> %s%s", proxy? "(Proxy) " : "", bp); 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((blen -= strlen(bp)+1) < 0) 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ERROR: overflowed buffer by %d bytes\n", -blen); 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->outptr = ctxt->out = bp; 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = XML_NANO_HTTP_WRITE; 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blen = strlen( ctxt->out ); 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmt_bytes = xmlNanoHTTPSend(ctxt, ctxt->out, blen ); 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( xmt_bytes != blen ) 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError( xmlGenericErrorContext, 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n", 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmt_bytes, blen, 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bytes of HTTP headers sent to host", 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->hostname ); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPSend(ctxt, ctxt->out, blen ); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( input != NULL ) { 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmt_bytes = xmlNanoHTTPSend( ctxt, input, ilen ); 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( xmt_bytes != ilen ) 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError( xmlGenericErrorContext, 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n", 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmt_bytes, ilen, 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bytes of HTTP content sent to host", 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->hostname ); 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPSend( ctxt, input, ilen ); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = XML_NANO_HTTP_READ; 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) { 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*p == 0) { 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->content = ctxt->inrptr; 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(p); 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPScanAnswer(ctxt, p); 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, "<- %s\n", p); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(p); 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) && 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ctxt->returnValue < 400)) { 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\nRedirect to: %s\n", ctxt->location); 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ( xmlNanoHTTPRecv(ctxt) > 0 ) ; 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) { 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbRedirects++; 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirURL != NULL) 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(redirURL); 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) redirURL = xmlMemStrdup(ctxt->location); 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFreeCtxt(ctxt); 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto retry; 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFreeCtxt(ctxt); 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirURL != NULL) xmlFree(redirURL); 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xmlNanoHTTPMethodRedir: Too many redirects, aborting ...\n"); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contentType != NULL) { 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->contentType != NULL) 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contentType = xmlMemStrdup(ctxt->contentType); 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contentType = NULL; 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((redir != NULL) && (redirURL != NULL)) { 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *redir = redirURL; 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redirURL != NULL) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(redirURL); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (redir != NULL) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *redir = NULL; 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_HTTP 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->contentType != NULL) 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\nCode %d, content-type '%s'\n\n", 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->returnValue, ctxt->contentType); 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\nCode %d, no content-type\n\n", 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->returnValue); 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return((void *) ctxt); 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPMethod: 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: The URL to load 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @method: the HTTP method to use 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @input: the input string if any 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @contentType: the Content-Type information IN and OUT 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @headers: the extra headers 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ilen: input length 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function try to open a connection to the indicated resource 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * via HTTP using the given @method, adding the given extra headers 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and the input buffer for the request content. 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns NULL in case of failure, otherwise a request handler. 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contentType, if provided must be freed by the caller 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPMethod(const char *URL, const char *method, const char *input, 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **contentType, const char *headers, int ilen) { 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlNanoHTTPMethodRedir(URL, method, input, contentType, 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, headers, ilen)); 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPFetch: 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: The URL to load 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @filename: the filename where the content should be saved 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @contentType: if available the Content-Type information will be 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returned at that location 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function try to fetch the indicated resource via HTTP GET 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and save it's content in the file. 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 incase of success. The contentType, 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if provided must be freed by the caller 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPFetch(const char *URL, const char *filename, char **contentType) { 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ctxt = NULL; 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *buf = NULL; 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd; 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filename == NULL) return(-1); 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt = xmlNanoHTTPOpen(URL, contentType); 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) return(-1); 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!strcmp(filename, "-")) 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd = 0; 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd = open(filename, O_CREAT | O_WRONLY, 00644); 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fd < 0) { 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPClose(ctxt); 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((contentType != NULL) && (*contentType != NULL)) { 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(*contentType); 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contentType = NULL; 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFetchContent( ctxt, &buf, &len ); 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( len > 0 ) { 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write(fd, buf, len); 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPClose(ctxt); 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(fd); 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_OUTPUT_ENABLED 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPSave: 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the HTTP context 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @filename: the filename where the content should be saved 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function saves the output of the HTTP transaction to a file 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * It closes and free the context at the end 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 incase of success. 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPSave(void *ctxt, const char *filename) { 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *buf = NULL; 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd; 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (filename == NULL)) return(-1); 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!strcmp(filename, "-")) 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd = 0; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd = open(filename, O_CREAT | O_WRONLY, 0666); 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fd < 0) { 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPClose(ctxt); 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFetchContent( ctxt, &buf, &len ); 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( len > 0 ) { 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write(fd, buf, len); 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPClose(ctxt); 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(fd); 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_OUTPUT_ENABLED */ 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPReturnCode: 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the latest HTTP return code received 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the HTTP return code for the request. 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPReturnCode(void *ctx) { 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) return(-1); 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ctxt->returnValue); 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPAuthHeader: 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the authentication header of an HTTP context 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the stashed value of the WWW-Authenticate or Proxy-Authenticate 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * header. 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPAuthHeader(void *ctx) { 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) return(NULL); 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ctxt->authHeader); 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPContentLength: 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Provides the specified content length from the HTTP header. 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the specified content length from the HTTP header. Note that 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a value of -1 indicates that the content length element was not included in 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the response header. 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPContentLength( void * ctx ) { 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( ( ctxt == NULL ) ? -1 : ctxt->ContentLength ); 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPRedir: 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Provides the specified redirection URL if available from the HTTP header. 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the specified redirection URL or NULL if not redirected. 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPRedir( void * ctx ) { 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( ( ctxt == NULL ) ? NULL : ctxt->location ); 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPEncoding: 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Provides the specified encoding if specified in the HTTP headers. 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the specified encoding or NULL if not available 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPEncoding( void * ctx ) { 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( ( ctxt == NULL ) ? NULL : ctxt->encoding ); 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPMimeType: 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Provides the specified Mime-Type if specified in the HTTP headers. 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the specified Mime-Type or NULL if not available 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPMimeType( void * ctx ) { 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( ( ctxt == NULL ) ? NULL : ctxt->mimeType ); 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlNanoHTTPFetchContent: 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the HTTP context 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ptr: pointer to set to the content buffer. 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: integer pointer to hold the length of the content 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check if all the content was read 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 if all the content was read and available, returns 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -1 if received content length was less than specified or an error 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * occurred. 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ) { 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr)ctx; 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = 0; 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cur_lgth; 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rcvd_lgth; 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dummy_int; 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char * dummy_ptr = NULL; 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Dummy up return input parameters if not provided */ 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( len == NULL ) 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = &dummy_int; 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( ptr == NULL ) 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr = &dummy_ptr; 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* But can't work without the context pointer */ 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( ( ctxt == NULL ) || ( ctxt->content == NULL ) ) { 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *len = 0; 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ptr = NULL; 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( -1 ); 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rcvd_lgth = ctxt->inptr - ctxt->content; 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ( (cur_lgth = xmlNanoHTTPRecv( ctxt )) > 0 ) { 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rcvd_lgth += cur_lgth; 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( (ctxt->ContentLength > 0) && (rcvd_lgth >= ctxt->ContentLength) ) 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ptr = ctxt->content; 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *len = rcvd_lgth; 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( ( ctxt->ContentLength > 0 ) && ( rcvd_lgth < ctxt->ContentLength ) ) 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = -1; 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ( rcvd_lgth == 0 ) 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = -1; 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ( rc ); 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef STANDALONE 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv) { 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *contentType = NULL; 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (argv[1] != NULL) { 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (argv[2] != NULL) 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFetch(argv[1], argv[2], &contentType); 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPFetch(argv[1], "-", &contentType); 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contentType != NULL) xmlFree(contentType); 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s: minimal HTTP GET implementation\n", argv[0]); 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\tusage %s [ URL [ filename ] ]\n", argv[0]); 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNanoHTTPCleanup(); 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMemoryDump(); 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* STANDALONE */ 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !LIBXML_HTTP_ENABLED */ 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef STANDALONE 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char **argv) { 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s : HTTP support not compiled in\n", argv[0]); 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* STANDALONE */ 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_HTTP_ENABLED */ 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define bottom_nanohttp 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "elfgcchack.h" 1876