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