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

📄 fetch.c

📁 Dag Erling http library source code
💻 C
字号:
/*- * Copyright (c) 1998-2004 Dag-Erling Co飀an Sm鴕grav * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer *    in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <sys/cdefs.h>#include <sys/param.h>#include <sys/errno.h>#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "../include/rmlibhttp.h"#include "common.h"RMint32	 fetchLastErrCode;RMascii	 fetchLastErrString[MAXERRSTRING];RMint32	 fetchTimeout = 5;  /* 5 seconds timeout */RMint32	 fetchRestartCalls = 1;/*** Local data **************************************************************//* * Error messages for parser errors */#define URL_MALFORMED		1#define URL_BAD_SCHEME		2#define URL_BAD_PORT		3static struct fetcherr _url_errlist[] = {	{ URL_MALFORMED,	FETCH_URL,	"Malformed URL" },	{ URL_BAD_SCHEME,	FETCH_URL,	"Invalid URL scheme" },	{ URL_BAD_PORT,		FETCH_URL,	"Invalid server port" },	{ -1,			FETCH_UNKNOWN,	"Unknown parser error" }};/*** Public API **************************************************************//* * Make a URL */struct url *fetchMakeURL(const RMascii *scheme, const RMascii *host, RMint32 port, const RMascii *doc,    const RMascii *user, const RMascii *pwd){	struct url *u;	if (!scheme || (!host && !doc)) {		_url_seterr(URL_MALFORMED);		return (NULL);	}	if (port < 0 || port > 65535) {		_url_seterr(URL_BAD_PORT);		return (NULL);	}	/* allocate struct url */	if ((u = RMCalloc(1, sizeof(*u))) == NULL) {		_fetch_syserr();		return (NULL);	}	if ((u->doc = RMMallocAndDuplicateAscii(doc ? doc : "/")) == NULL) {		_fetch_syserr();		RMFree(u);		return (NULL);	}#define seturl(x) snprintf(u->x, sizeof(u->x), "%s", x)	seturl(scheme);	seturl(host);	seturl(user);	seturl(pwd);#undef seturl	u->port = port;	return (u);}/* * Split an URL into components. URL syntax is: * [method:/][/[user[:pwd]@]host[:port]/][document] * This almost, but not quite, RFC1738 URL syntax. */struct url *fetchParseURL(const RMascii *URL){	RMascii *doc;	const RMascii *p, *q;	struct url *u;	RMint32 i;	/* allocate struct url */	if ((u = RMCalloc(1, sizeof(*u))) == NULL) {		_fetch_syserr();		return (NULL);	}	/* scheme name */	if ((p = strstr(URL, ":/"))) {		snprintf(u->scheme, URL_SCHEMELEN+1,		    "%.*s", (RMint8)(p - URL), URL);		URL = ++p;		/*		 * Only one slash: no host, leave slash as part of document		 * Two slashes: host follows, strip slashes		 */		if (URL[1] == '/')			URL = (p += 2);	} else {		p = URL;	}	if (!*URL || *URL == '/' || *URL == '.' ||	    (u->scheme[0] == '\0' &&		strchr(URL, '/') == NULL && strchr(URL, ':') == NULL))		goto nohost;	p = strpbrk(URL, "/@");	if (p && *p == '@') {		/* username */		for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++)			if (i < URL_USERLEN)				u->user[i++] = *q;		/* password */		if (*q == ':')			for (q++, i = 0; (*q != ':') && (*q != '@'); q++)				if (i < URL_PWDLEN)					u->pwd[i++] = *q;		p++;	} else {		p = URL;	}	/* hostname */#ifdef INET6	if (*p == '[' && (q = strchr(p + 1, ']')) != NULL &&	    (*++q == '\0' || *q == '/' || *q == ':')) {		if ((i = q - p - 2) > MAXHOSTNAMELEN)			i = MAXHOSTNAMELEN;		strncpy(u->host, ++p, i);		p = q;	} else#endif		for (i = 0; *p && (*p != '/') && (*p != ':'); p++)			if (i < MAXHOSTNAMELEN)				u->host[i++] = *p;	/* port */	if (*p == ':') {		for (q = ++p; *q && (*q != '/'); q++)			if (isdigit(*q))				u->port = u->port * 10 + (*q - '0');			else {				/* invalid port */				_url_seterr(URL_BAD_PORT);				goto ouch;			}		p = q;	}nohost:	/* document */	if (!*p)		p = "/";	if (strcasecmp(u->scheme, SCHEME_HTTP) == 0 ||	    strcasecmp(u->scheme, SCHEME_HTTPS) == 0) {		const RMascii hexnums[] = "0123456789abcdef";		/* percent-escape whitespace. */		if ((doc = RMMalloc(strlen(p) * 3 + 1)) == NULL) {			_fetch_syserr();			goto ouch;		}		u->doc = doc;		while (*p != '\0') {			if (!isspace(*p)) {				*doc++ = *p++;			} else {				*doc++ = '%';				*doc++ = hexnums[((RMuint32)*p) >> 4];				*doc++ = hexnums[((RMuint32)*p) & 0xf];				p++;			}		}		*doc = '\0';	} else if ((u->doc = RMMallocAndDuplicateAscii(p)) == NULL) {		_fetch_syserr();		goto ouch;	}	RMDBGLOG((HTTPDEBUG,		  "scheme:   [%s]\n"		  "user:     [%s]\n"		  "password: [%s]\n"		  "host:     [%s]\n"		  "port:     [%ld]\n"		  "document: [%s]\n",		  u->scheme, u->user, u->pwd,		  u->host, u->port, u->doc));	return (u);ouch:	RMFree(u);	return (NULL);}/* * Free a URL */voidfetchFreeURL(struct url *u){	RMFree(u->doc);	RMFree(u);}

⌨️ 快捷键说明

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