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

📄 nanohttp.c

📁 libxml,在UNIX/LINUX下非常重要的一个库,为XML相关应用提供方便.目前上载的是最新版本,若要取得最新版本,请参考里面的readme.
💻 C
📖 第 1 页 / 共 3 页
字号:
 * xmlNanoHTTPReadLine: * @ctxt:  an HTTP context * * Read one line in the HTTP server output, usually for extracting * the HTTP protocol informations from the answer header. * * Returns a newly allocated string with a copy of the line, or NULL *         which indicate the end of the input. */static char *xmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) {    char buf[4096];    char *bp = buf;    int	rc;        while (bp - buf < 4095) {	if (ctxt->inrptr == ctxt->inptr) {	    if ( (rc = xmlNanoHTTPRecv(ctxt)) == 0) {		if (bp == buf)		    return(NULL);		else		    *bp = 0;		return(xmlMemStrdup(buf));	    }	    else if ( rc == -1 ) {	        return ( NULL );	    }	}	*bp = *ctxt->inrptr++;	if (*bp == '\n') {	    *bp = 0;	    return(xmlMemStrdup(buf));	}	if (*bp != '\r')	    bp++;    }    buf[4095] = 0;    return(xmlMemStrdup(buf));}/** * xmlNanoHTTPScanAnswer: * @ctxt:  an HTTP context * @line:  an HTTP header line * * Try to extract useful informations from the server answer. * We currently parse and process: *  - The HTTP revision/ return code *  - The Content-Type, Mime-Type and charset used *  - The Location for redirect processing. * * Returns -1 in case of failure, the file descriptor number otherwise */static voidxmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) {    const char *cur = line;    if (line == NULL) return;    if (!strncmp(line, "HTTP/", 5)) {        int version = 0;	int ret = 0;	cur += 5;	while ((*cur >= '0') && (*cur <= '9')) {	    version *= 10;	    version += *cur - '0';	    cur++;	}	if (*cur == '.') {	    cur++;	    if ((*cur >= '0') && (*cur <= '9')) {		version *= 10;		version += *cur - '0';		cur++;	    }	    while ((*cur >= '0') && (*cur <= '9'))		cur++;	} else	    version *= 10;	if ((*cur != ' ') && (*cur != '\t')) return;	while ((*cur == ' ') || (*cur == '\t')) cur++;	if ((*cur < '0') || (*cur > '9')) return;	while ((*cur >= '0') && (*cur <= '9')) {	    ret *= 10;	    ret += *cur - '0';	    cur++;	}	if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return;	ctxt->returnValue = ret;    } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) {        const xmlChar *charset, *last, *mime;        cur += 13;	while ((*cur == ' ') || (*cur == '\t')) cur++;	if (ctxt->contentType != NULL)	    xmlFree(ctxt->contentType);	ctxt->contentType = xmlMemStrdup(cur);	mime = (const xmlChar *) cur;	last = mime;	while ((*last != 0) && (*last != ' ') && (*last != '\t') &&	       (*last != ';') && (*last != ','))	    last++;	if (ctxt->mimeType != NULL)	    xmlFree(ctxt->mimeType);	ctxt->mimeType = (char *) xmlStrndup(mime, last - mime);	charset = xmlStrstr(BAD_CAST ctxt->contentType, BAD_CAST "charset=");	if (charset != NULL) {	    charset += 8;	    last = charset;	    while ((*last != 0) && (*last != ' ') && (*last != '\t') &&	           (*last != ';') && (*last != ','))		last++;	    if (ctxt->encoding != NULL)	        xmlFree(ctxt->encoding);	    ctxt->encoding = (char *) xmlStrndup(charset, last - charset);	}    } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"ContentType:", 12)) {        const xmlChar *charset, *last, *mime;        cur += 12;	if (ctxt->contentType != NULL) return;	while ((*cur == ' ') || (*cur == '\t')) cur++;	ctxt->contentType = xmlMemStrdup(cur);	mime = (const xmlChar *) cur;	last = mime;	while ((*last != 0) && (*last != ' ') && (*last != '\t') &&	       (*last != ';') && (*last != ','))	    last++;	if (ctxt->mimeType != NULL)	    xmlFree(ctxt->mimeType);	ctxt->mimeType = (char *) xmlStrndup(mime, last - mime);	charset = xmlStrstr(BAD_CAST ctxt->contentType, BAD_CAST "charset=");	if (charset != NULL) {	    charset += 8;	    last = charset;	    while ((*last != 0) && (*last != ' ') && (*last != '\t') &&	           (*last != ';') && (*last != ','))		last++;	    if (ctxt->encoding != NULL)	        xmlFree(ctxt->encoding);	    ctxt->encoding = (char *) xmlStrndup(charset, last - charset);	}    } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Location:", 9)) {        cur += 9;	while ((*cur == ' ') || (*cur == '\t')) cur++;	if (ctxt->location != NULL)	    xmlFree(ctxt->location);	if (*cur == '/') {	    xmlChar *tmp_http = xmlStrdup(BAD_CAST "http://");	    xmlChar *tmp_loc = 	        xmlStrcat(tmp_http, (const xmlChar *) ctxt->hostname);	    ctxt->location = 	        (char *) xmlStrcat (tmp_loc, (const xmlChar *) cur);	} else {	    ctxt->location = xmlMemStrdup(cur);	}    } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"WWW-Authenticate:", 17)) {        cur += 17;	while ((*cur == ' ') || (*cur == '\t')) cur++;	if (ctxt->authHeader != NULL)	    xmlFree(ctxt->authHeader);	ctxt->authHeader = xmlMemStrdup(cur);    } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Proxy-Authenticate:", 19)) {        cur += 19;	while ((*cur == ' ') || (*cur == '\t')) cur++;	if (ctxt->authHeader != NULL)	    xmlFree(ctxt->authHeader);	ctxt->authHeader = xmlMemStrdup(cur);    } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Length:", 15) ) {	cur += 15;	ctxt->ContentLength = strtol( cur, NULL, 10 );    }}/** * xmlNanoHTTPConnectAttempt: * @addr:  a socket address structure * * Attempt a connection to the given IP:port endpoint. It forces * non-blocking semantic on the socket, and allow 60 seconds for * the host to answer. * * Returns -1 in case of failure, the file descriptor number otherwise */static intxmlNanoHTTPConnectAttempt(struct sockaddr *addr){    fd_set wfd;#ifdef _WINSOCKAPI_    fd_set xfd;#endif    struct timeval tv;    int status;    int addrlen;    SOCKET s;    #ifdef SUPPORT_IP6    if (addr->sa_family == AF_INET6) {	s = socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP);	addrlen = sizeof (struct sockaddr_in6);    }    else#endif    {	s = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);	addrlen = sizeof (struct sockaddr_in);    }    if (s==-1) {#ifdef DEBUG_HTTP	perror("socket");#endif	__xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n");	return(-1);    }    #ifdef _WINSOCKAPI_    {	u_long one = 1;	status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;    }#else /* _WINSOCKAPI_ */#if defined(VMS)    {	int enable = 1;	status = ioctl(s, FIONBIO, &enable);    }#else /* VMS */#if defined(__BEOS__)	{		bool noblock = true;		status = setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock, sizeof(noblock));	}#else /* __BEOS__ */    if ((status = fcntl(s, F_GETFL, 0)) != -1) {#ifdef O_NONBLOCK	status |= O_NONBLOCK;#else /* O_NONBLOCK */#ifdef F_NDELAY	status |= F_NDELAY;#endif /* F_NDELAY */#endif /* !O_NONBLOCK */	status = fcntl(s, F_SETFL, status);    }    if (status < 0) {#ifdef DEBUG_HTTP	perror("nonblocking");#endif	__xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n");	closesocket(s);	return(-1);    }#endif /* !__BEOS__ */#endif /* !VMS */#endif /* !_WINSOCKAPI_ */    if (connect (s, addr, addrlen) == -1) {	switch (socket_errno()) {	    case EINPROGRESS:	    case EWOULDBLOCK:		break;	    default:		__xmlIOErr(XML_FROM_HTTP, 0, "error connecting to HTTP server");		closesocket(s);		return(-1);	}    }	        tv.tv_sec = timeout;    tv.tv_usec = 0;        FD_ZERO(&wfd);    FD_SET(s, &wfd);#ifdef _WINSOCKAPI_        FD_ZERO(&xfd);    FD_SET(s, &xfd);        switch(select(s+1, NULL, &wfd, &xfd, &tv))#else    switch(select(s+1, NULL, &wfd, NULL, &tv))#endif    {	case 0:	    /* Time out */	    __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out");	    closesocket(s);	    return(-1);	case -1:	    /* Ermm.. ?? */	    __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed");	    closesocket(s);	    return(-1);    }    if ( FD_ISSET(s, &wfd)#ifdef _WINSOCKAPI_                           || FD_ISSET(s, &xfd)#endif                                                ) {	XML_SOCKLEN_T len;	len = sizeof(status);#ifdef SO_ERROR	if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0 ) {	    /* Solaris error code */	    __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");	    return (-1);	}#endif	if ( status ) {	    __xmlIOErr(XML_FROM_HTTP, 0, "Error connecting to remote host");	    closesocket(s);	    errno = status;	    return (-1);	}    } else {	/* pbm */	__xmlIOErr(XML_FROM_HTTP, 0, "select failed\n");	closesocket(s);	return (-1);    }        return(s);} /** * xmlNanoHTTPConnectHost: * @host:  the host name * @port:  the port number * * Attempt a connection to the given host:port endpoint. It tries * the multiple IP provided by the DNS if available. * * Returns -1 in case of failure, the file descriptor number otherwise */static intxmlNanoHTTPConnectHost(const char *host, int port){    struct hostent *h;    struct sockaddr *addr = NULL;    struct in_addr ia;    struct sockaddr_in sockin;#ifdef SUPPORT_IP6    struct in6_addr ia6;    struct sockaddr_in6 sockin6;#endif    int i;    int s;    memset (&sockin, 0, sizeof(sockin));#ifdef SUPPORT_IP6    memset (&sockin6, 0, sizeof(sockin6));    if (have_ipv6 ())#if !defined(HAVE_GETADDRINFO) && defined(RES_USE_INET6)    {	if (!(_res.options & RES_INIT))	    res_init();	_res.options |= RES_USE_INET6;    }#elif defined(HAVE_GETADDRINFO)    {	int status;	struct addrinfo hints, *res, *result;	result = NULL;	memset (&hints, 0,sizeof(hints));	hints.ai_socktype = SOCK_STREAM;	status = getaddrinfo (host, NULL, &hints, &result);	if (status) {	    __xmlIOErr(XML_FROM_HTTP, 0, "getaddrinfo failed\n");	    return (-1);	}	for (res = result; res; res = res->ai_next) {	    if (res->ai_family == AF_INET || res->ai_family == AF_INET6) {		if (res->ai_family == AF_INET6) {		    if (res->ai_addrlen > sizeof(sockin6)) {			__xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");			freeaddrinfo (result);			return (-1);		    }		    memcpy (&sockin6, res->ai_addr, res->ai_addrlen);		    sockin6.sin6_port = htons (port);		    addr = (struct sockaddr *)&sockin6;		}		else {		    if (res->ai_addrlen > sizeof(sockin)) {			__xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");			freeaddrinfo (result);			return (-1);		    }		    memcpy (&sockin, res->ai_addr, res->ai_addrlen);		    sockin.sin_port = htons (port);		    addr = (struct sockaddr *)&sockin;		}		s = xmlNanoHTTPConnectAttempt (addr);		if (s != -1) {		    freeaddrinfo (result);		    return (s);		}	    }	}	if (result)	    freeaddrinfo (result);	return (-1);    } else#endif#endif    {   	h = gethostbyname (host);	if (h == NULL) {/* * Okay, I got fed up by the non-portability of this error message * extraction code. it work on Linux, if it work on your platform * and one want to enable it, send me the defined(foobar) needed */#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux)	    const char *h_err_txt = "";	    switch (h_errno) {		case HOST_NOT_FOUND:		    h_err_txt = "Authoritive host not found";		    break;		case TRY_AGAIN:		    h_err_txt =			"Non-authoritive host not found or server failure.";		    break;		case NO_RECOVERY:		    h_err_txt =			"Non-recoverable errors:  FORMERR, REFUSED, or NOTIMP.";		    break;		case NO_ADDRESS:		    h_err_txt =			"Valid name, no data record of requested type.";		    break;		default:		    h_err_txt = "No error text defined.";		    break;	    }	    __xmlIOErr(XML_FROM_HTTP, 0, h_err_txt);#else	    __xmlIOErr(XML_FROM_HTTP, 0, "Failed to resolve host");#endif	    return (-1);	}	for (i = 0; h->h_addr_list[i]; i++) {	    if (h->h_addrtype == AF_INET) {		/* A records (IPv4) */		if ((unsigned int) h->h_length > sizeof(ia)) {		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");		    return (-1);		}		memcpy (&ia, h->h_addr_list[i], h->h_length);		sockin.sin_family = h->h_addrtype;		sockin.sin_addr = ia;		sockin.sin_port = htons (port);		addr = (struct sockaddr *) &sockin;#ifdef SUPPORT_IP6	    } else if (have_ipv6 () && (h->h_addrtype == AF_INET6)) {		/* AAAA records (IPv6) */		if ((unsigned int) h->h_length > sizeof(ia6)) {		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");		    return (-1);		}		memcpy (&ia6, h->h_addr_list[i], h->h_length);		sockin6.sin6_family = h->h_addrtype;		sockin6.sin6_addr = ia6;		sockin6.sin6_port = htons (port);		addr = (struct sockaddr *) &sockin6;#endif	    } else		break;              /* for */	    s = xmlNanoHTTPConnectAttempt (addr);	    if (s != -1)		return (s);	}    }#ifdef DEBUG_HTTP    xmlGenericError(xmlGenericErrorContext,                    "xmlNanoHTTPConnectHost:  unable to connect to '%s'.\n",                    host);#endif    return (-1);}/** * xmlNanoHTTPOpen: * @URL:  The URL to load * @contentType:  if available the Content-Type information will be *                returned at that location * * This function try to open a connection to the indicated resource * via HTTP GET. * * Returns NULL in case of failure, otherwise a request handler. *     The contentType, if provided must be freed by the caller */void*xmlNanoHTTPOpen(const char *URL, char **contentType) {    if (contentType != NULL) *contentType = NULL;    return(xmlNanoHTTPMethod(URL, NULL, NULL, contentType, NULL, 0));}/** * xmlNanoHTTPOpenRedir: * @URL:  The URL to load * @contentType:  if available the Content-Type information will be *                returned at that location * @redir: if available the redirected URL will be returned * * This function try to open a connection to the indicated resource * via HTTP GET. * * Returns NULL in case of failure, otherwise a request handler. *     The contentType, if provided must be freed by the caller */void*xmlNanoHTTPOpenRedir(const char *URL, char **contentType, char **redir) {    if (contentType != NULL) *contentType = NULL;    if (redir != NULL) *redir = NULL;    return(xmlNanoHTTPMethodRedir(URL, NULL, NULL, contentType, redir, NULL,0));}/** * xmlNanoHTTPRead: * @ctx:  the HTTP context * @dest:  a buffer * @len:  the buffer length * * This function tries to read @len bytes from the existing HTTP connection * and saves them in @dest. This is a blocking call. * * Returns the number of byte read. 0 is an indication of an end of connection. *         -1 indicates a parameter error. */intxmlNanoHTTPRead(void *ctx, void *dest, int len) {    xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;    if (ctx == NULL) return(-1);    if (dest == NULL) return(-1);    if (len <= 0) return(0);

⌨️ 快捷键说明

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