⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nanohttp.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* * nanohttp.c: minimalist HTTP GET implementation to fetch external subsets. *             focuses on size, streamability, reentrancy and portability * * This is clearly not a general purpose HTTP implementation * If you look for one, check: *         http://www.w3.org/Library/ * * See Copyright for the status of this software. * * daniel@veillard.com */ /* TODO add compression support, Send the Accept- , and decompress on the        fly with ZLIB if found at compile-time */#define NEED_SOCKETS#define IN_LIBXML#include "libxml.h"#ifdef LIBXML_HTTP_ENABLED#include <string.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#ifdef HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#ifdef HAVE_NETDB_H#include <netdb.h>#endif#ifdef HAVE_RESOLV_H#ifdef HAVE_ARPA_NAMESER_H#include <arpa/nameser.h>#endif#include <resolv.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h> #endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#ifdef SUPPORT_IP6#include <resolv.h>#endif#ifdef VMS#include <stropts>#define SOCKLEN_T unsigned int#define SOCKET int#endif#ifdef __MINGW32__#define _WINSOCKAPI_#include <wsockcompat.h>#include <winsock2.h>#undef SOCKLEN_T#define SOCKLEN_T unsigned int#endif#include <libxml/globals.h>#include <libxml/xmlerror.h>#include <libxml/xmlmemory.h>#include <libxml/parser.h> /* for xmlStr(n)casecmp() */#include <libxml/nanohttp.h>#include <libxml/globals.h>#include <libxml/uri.h>/** * A couple portability macros */#ifndef _WINSOCKAPI_#ifndef __BEOS__#define closesocket(s) close(s)#endif#define SOCKET int#endif#ifdef __BEOS__#ifndef PF_INET#define PF_INET AF_INET#endif#endif#ifndef SOCKLEN_T#define SOCKLEN_T unsigned int#endif#ifndef SOCKET#define SOCKET int#endif#ifdef STANDALONE#define DEBUG_HTTP#define xmlStrncasecmp(a, b, n) strncasecmp((char *)a, (char *)b, n)#define xmlStrcasecmpi(a, b) strcasecmp((char *)a, (char *)b)#endif#define XML_NANO_HTTP_MAX_REDIR	10#define XML_NANO_HTTP_CHUNK	4096#define XML_NANO_HTTP_CLOSED	0#define XML_NANO_HTTP_WRITE	1#define XML_NANO_HTTP_READ	2#define XML_NANO_HTTP_NONE	4typedef struct xmlNanoHTTPCtxt {    char *protocol;	/* the protocol name */    char *hostname;	/* the host name */    int port;		/* the port */    char *path;		/* the path within the URL */    SOCKET fd;		/* the file descriptor for the socket */    int state;		/* WRITE / READ / CLOSED */    char *out;		/* buffer sent (zero terminated) */    char *outptr;	/* index within the buffer sent */    char *in;		/* the receiving buffer */    char *content;	/* the start of the content */    char *inptr;	/* the next byte to read from network */    char *inrptr;	/* the next byte to give back to the client */    int inlen;		/* len of the input buffer */    int last;		/* return code for last operation */    int returnValue;	/* the protocol return value */    int ContentLength;  /* specified content length from HTTP header */    char *contentType;	/* the MIME type for the input */    char *location;	/* the new URL in case of redirect */    char *authHeader;	/* contents of {WWW,Proxy}-Authenticate header */    char *encoding;	/* encoding extracted from the contentType */    char *mimeType;	/* Mime-Type extracted from the contentType */} xmlNanoHTTPCtxt, *xmlNanoHTTPCtxtPtr;static int initialized = 0;static char *proxy = NULL;	 /* the proxy name if any */static int proxyPort;	/* the proxy port if any */static unsigned int timeout = 60;/* the select() timeout in seconds */int xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len );int xmlNanoHTTPContentLength( void * ctx );/** * xmlHTTPErrMemory: * @extra:  extra informations * * Handle an out of memory condition */static voidxmlHTTPErrMemory(const char *extra){    __xmlSimpleError(XML_FROM_HTTP, XML_ERR_NO_MEMORY, NULL, NULL, extra);}/** * A portability function */static int socket_errno(void) {#ifdef _WINSOCKAPI_    return(WSAGetLastError());#else    return(errno);#endif}#ifdef SUPPORT_IP6staticint have_ipv6(void) {    int s;    s = socket (AF_INET6, SOCK_STREAM, 0);    if (s != -1) {	close (s);	return (1);    }    return (0);}#endif/** * xmlNanoHTTPInit: * * Initialize the HTTP protocol layer. * Currently it just checks for proxy informations */voidxmlNanoHTTPInit(void) {    const char *env;#ifdef _WINSOCKAPI_    WSADATA wsaData;    #endif    if (initialized)	return;#ifdef _WINSOCKAPI_    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)	return;#endif    if (proxy == NULL) {	proxyPort = 80;	env = getenv("no_proxy");	if (env != NULL)	    goto done;	env = getenv("http_proxy");	if (env != NULL) {	    xmlNanoHTTPScanProxy(env);	    goto done;	}	env = getenv("HTTP_PROXY");	if (env != NULL) {	    xmlNanoHTTPScanProxy(env);	    goto done;	}    }done:    initialized = 1;}/** * xmlNanoHTTPCleanup: * * Cleanup the HTTP protocol layer. */voidxmlNanoHTTPCleanup(void) {    if (proxy != NULL)	xmlFree(proxy);#ifdef _WINSOCKAPI_    if (initialized)	WSACleanup();#endif    initialized = 0;    return;}/** * xmlNanoHTTPScanURL: * @ctxt:  an HTTP context * @URL:  The URL used to initialize the context * * (Re)Initialize an HTTP context by parsing the URL and finding * the protocol host port and path it indicates. */static voidxmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) {    const char *cur = URL;    char buf[4096];    int indx = 0;    const int indxMax = 4096 - 1;    int port = 0;    if (ctxt->protocol != NULL) {         xmlFree(ctxt->protocol);	ctxt->protocol = NULL;    }    if (ctxt->hostname != NULL) {         xmlFree(ctxt->hostname);	ctxt->hostname = NULL;    }    if (ctxt->path != NULL) {         xmlFree(ctxt->path);	ctxt->path = NULL;    }    if (URL == NULL) return;    buf[indx] = 0;    while ((*cur != 0) && (indx < indxMax)) {        if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {	    buf[indx] = 0;	    ctxt->protocol = xmlMemStrdup(buf);	    indx = 0;            cur += 3;	    break;	}	buf[indx++] = *cur++;    }    if (*cur == 0) return;    buf[indx] = 0;    while (indx < indxMax) {	if ((strchr (cur, '[') && !strchr (cur, ']')) ||		(!strchr (cur, '[') && strchr (cur, ']'))) {	    __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, 	               "Syntax Error\n");	    return;	}	if (cur[0] == '[') {	    cur++;	    while ((cur[0] != ']') && (indx < indxMax))		buf[indx++] = *cur++;    	    if (!strchr (buf, ':')) {		__xmlIOErr(XML_FROM_HTTP, XML_HTTP_USE_IP,			"Use [IPv6]/IPv4 format\n");		return;	    }	    buf[indx] = 0;	    ctxt->hostname = xmlMemStrdup (buf);	    indx = 0;	    cur += 1;	    if (cur[0] == ':') {		cur++;		while (*cur >= '0' && *cur <= '9') {		    port *= 10;		    port += *cur - '0';		    cur++;		}		if (port != 0) ctxt->port = port;		while ((cur[0] != '/') && (*cur != 0))		    cur++;	    }	    break;        }	else {	    if (cur[0] == ':') {		buf[indx] = 0;		ctxt->hostname = xmlMemStrdup (buf);		indx = 0;		cur += 1;		while ((*cur >= '0') && (*cur <= '9')) {		    port *= 10;		    port += *cur - '0';		    cur++;		}		if (port != 0) ctxt->port = port;		while ((cur[0] != '/') && (*cur != 0)) 		    cur++;		break;	    }	    if ((*cur == '/') || (*cur == 0)) {		buf[indx] = 0;		ctxt->hostname = xmlMemStrdup (buf);		indx = 0;		break;	    }	}	buf[indx++] = *cur++;    }    if (*cur == 0)         ctxt->path = xmlMemStrdup("/");    else {        indx = 0;        buf[indx] = 0;	while ((*cur != 0) && (indx < indxMax))	    buf[indx++] = *cur++;	buf[indx] = 0;	ctxt->path = xmlMemStrdup(buf);    }	}/** * xmlNanoHTTPScanProxy: * @URL:  The proxy URL used to initialize the proxy context * * (Re)Initialize the HTTP Proxy context by parsing the URL and finding * the protocol host port it indicates. * Should be like http://myproxy/ or http://myproxy:3128/ * A NULL URL cleans up proxy informations. */voidxmlNanoHTTPScanProxy(const char *URL) {    const char *cur = URL;    char buf[4096];    int indx = 0;    const int indxMax = 4096 - 1;    int port = 0;    if (proxy != NULL) {         xmlFree(proxy);	proxy = NULL;    }    if (proxyPort != 0) { 	proxyPort = 0;    }#ifdef DEBUG_HTTP    if (URL == NULL)	xmlGenericError(xmlGenericErrorContext,		"Removing HTTP proxy info\n");    else	xmlGenericError(xmlGenericErrorContext,		"Using HTTP proxy %s\n", URL);#endif    if (URL == NULL) return;    buf[indx] = 0;    while ((*cur != 0) && (indx < indxMax)) {        if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {	    buf[indx] = 0;	    indx = 0;            cur += 3;	    break;	}	buf[indx++] = *cur++;    }    if (*cur == 0) return;    buf[indx] = 0;    while (indx < indxMax) {	if ((strchr (cur, '[') && !strchr (cur, ']')) ||		(!strchr (cur, '[') && strchr (cur, ']'))) {	    __xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Syntax Error\n");	    return;	}	if (cur[0] == '[') {	    cur++;	    while ((cur[0] != ']') && (indx < indxMax))		buf[indx++] = *cur++;	    if (!strchr (buf, ':')) {		__xmlIOErr(XML_FROM_HTTP, XML_HTTP_USE_IP,			"Use [IPv6]/IPv4 format\n");		return;	    }	    buf[indx] = 0;	    proxy = xmlMemStrdup (buf);	    indx = 0;	    cur += 1;	    if (cur[0] == ':') {	        cur++;		while (*cur >= '0' && *cur <= '9') {		    port *= 10;		    port += *cur - '0';		    cur++;		}		if (port != 0) proxyPort = port;		while ((cur[0] != '/') && (*cur != 0))		    cur ++;	    }	    break;	}	else {	    if (cur[0] == ':') {		buf[indx] = 0;		proxy = xmlMemStrdup (buf);		indx = 0;		cur += 1;		while ((*cur >= '0') && (*cur <= '9')) {		    port *= 10;		    port += *cur - '0';		    cur++;		}		if (port != 0) proxyPort = port;		while ((cur[0] != '/') && (*cur != 0)) 		    cur++;		break;	    }	    if ((*cur == '/') || (*cur == 0)) {		buf[indx] = 0;		proxy = xmlMemStrdup (buf);		indx = 0;		break;	    }	}	buf[indx++] = *cur++;    }}/** * xmlNanoHTTPNewCtxt: * @URL:  The URL used to initialize the context * * Allocate and initialize a new HTTP context. * * Returns an HTTP context or NULL in case of error. */static xmlNanoHTTPCtxtPtrxmlNanoHTTPNewCtxt(const char *URL) {    xmlNanoHTTPCtxtPtr ret;    ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt));    if (ret == NULL) {        xmlHTTPErrMemory("allocating context");        return(NULL);    }    memset(ret, 0, sizeof(xmlNanoHTTPCtxt));    ret->port = 80;    ret->returnValue = 0;    ret->fd = -1;    ret->ContentLength = -1;    xmlNanoHTTPScanURL(ret, URL);    return(ret);}/** * xmlNanoHTTPFreeCtxt: * @ctxt:  an HTTP context * * Frees the context after closing the connection. */static voidxmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) {    if (ctxt == NULL) return;    if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);    if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);    if (ctxt->path != NULL) xmlFree(ctxt->path);    if (ctxt->out != NULL) xmlFree(ctxt->out);    if (ctxt->in != NULL) xmlFree(ctxt->in);    if (ctxt->contentType != NULL) xmlFree(ctxt->contentType);    if (ctxt->encoding != NULL) xmlFree(ctxt->encoding);    if (ctxt->mimeType != NULL) xmlFree(ctxt->mimeType);    if (ctxt->location != NULL) xmlFree(ctxt->location);    if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader);    ctxt->state = XML_NANO_HTTP_NONE;    if (ctxt->fd >= 0) closesocket(ctxt->fd);    ctxt->fd = -1;    xmlFree(ctxt);}/** * xmlNanoHTTPSend: * @ctxt:  an HTTP context * * Send the input needed to initiate the processing on the server side * Returns number of bytes sent or -1 on error. */static intxmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char * xmt_ptr, int outlen) {    int 	total_sent = 0;    if ( (ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL ) ) {        while (total_sent < outlen) {            int nsent = send(ctxt->fd, xmt_ptr + total_sent,                                      outlen - total_sent, 0);            if (nsent>0)                total_sent += nsent;	    else if ( ( nsent == -1 ) && #if defined(EAGAIN) && EAGAIN != EWOULDBLOCK	    	      ( socket_errno( ) != EAGAIN ) &&#endif		        ( socket_errno( ) != EWOULDBLOCK ) ) {		__xmlIOErr(XML_FROM_HTTP, 0, "send failed\n");		if ( total_sent == 0 )		    total_sent = -1;		break;	    }	    else {	        /*		**  No data sent		**  Since non-blocking sockets are used, wait for 		**  socket to be writable or default timeout prior		**  to retrying.		*/		struct timeval	tv;		fd_set		wfd;		tv.tv_sec = timeout;		tv.tv_usec = 0;		FD_ZERO( &wfd );		FD_SET( ctxt->fd, &wfd );		(void)select( ctxt->fd + 1, NULL, &wfd, NULL, &tv );	    }	}    }    return total_sent;}/**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -