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

📄 webs.c

📁 一个典型的用于嵌入式Linux环境的Webserver
💻 C
📖 第 1 页 / 共 5 页
字号:
		done += len;	}	bfree(B_L, asciiBuf);	return done;}/******************************************************************************//* *	Write a block of data of length "nChars" to the user's browser. Same as *	websWriteBlock except that it expects straight ASCII or binary and does no *	unicode conversion before writing the data.  If the socket cannot hold all *	the data, it will return the number of bytes flushed to the socket before *	it would have blocked.  This returns the number of chars processed or -1 *	if socketWrite fails. */int websWriteDataNonBlock(webs_t wp, char *buf, int nChars){	int r;	a_assert(wp);	a_assert(websValid(wp));	a_assert(buf);	a_assert(nChars >= 0);#ifdef WEBS_SSL_SUPPORT	if (wp->flags & WEBS_SECURE) {		r = websSSLWrite(wp->wsp, buf, nChars);		websSSLFlush(wp->wsp);	} else {		r = socketWrite(wp->sid, buf, nChars);		socketFlush(wp->sid);	}#else	r = socketWrite(wp->sid, buf, nChars);	socketFlush(wp->sid);#endif	return r;}/******************************************************************************//* *	Decode a URL (or part thereof). Allows insitu decoding. */void websDecodeUrl(char_t *decoded, char_t *token, int len){	char_t	*ip,  *op;	int		num, i, c;		a_assert(decoded);	a_assert(token);	op = decoded;	for (ip = token; *ip && len > 0; ip++, op++) {		if (*ip == '+') {			*op = ' ';		} else if (*ip == '%' && gisxdigit(ip[1]) && gisxdigit(ip[2])) {/* *			Convert %nn to a single character */			ip++;			for (i = 0, num = 0; i < 2; i++, ip++) {				c = tolower(*ip);				if (c >= 'a' && c <= 'f') {					num = (num * 16) + 10 + c - 'a';				} else {					num = (num * 16) + c - '0';				}			}			*op = (char_t) num;			ip--;		} else {			*op = *ip;		}		len--;	}	*op = '\0';}/******************************************************************************/#ifdef WEBS_LOG_SUPPORT/* *	Output a log message */static void websLog(webs_t wp, int code){	char_t	*buf;	char	*abuf;	int		len;#define qAnlLog 1#if (defined(qAnlLog) && !defined(CE))   time_t timer;   char_t* newLine = NULL;   char_t* timeStr = NULL;#endif	a_assert(websValid(wp));	buf = NULL;#if (defined(qAnlLog) && !defined(CE))   time(&timer);   timeStr = ctime(&timer);   newLine = gstrchr(timeStr, '\n');   if (newLine)   {      *newLine = '\0';   }   fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%s\t%s\t%s\tcode = %d\n"),       timeStr, wp->ipaddr, wp->url, code);#else	fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%d %s %d %d\n"), time(0), 		wp->url, code, wp->written);#endif	len = gstrlen(buf);	abuf = ballocUniToAsc(buf, len+1);	write(websLogFd, abuf, len);	bfreeSafe(B_L, buf);	bfreeSafe(B_L, abuf);}#endif /* WEBS_LOG_SUPPORT *//******************************************************************************//* *	Request timeout. The timeout triggers if we have not read any data from *	the users browser in the last WEBS_TIMEOUT period. If we have heard from *	the browser, simply re-issue the timeout. */void websTimeout(void *arg, int id){	webs_t		wp;	int			delay, tm;	wp = (webs_t) arg;	a_assert(websValid(wp));	tm = websGetTimeSinceMark(wp) * 1000;	if (tm >= WEBS_TIMEOUT) {		websStats.timeouts++;		emfUnschedCallback(id);/* *		Clear the timeout id */		wp->timeout = -1;		websDone(wp, 404);	} else {		delay = WEBS_TIMEOUT - tm;		a_assert(delay > 0);		emfReschedCallback(id, delay);	}}/******************************************************************************//* *	Called when the request is done. */void websDone(webs_t wp, int code){	a_assert(websValid(wp));/* * 	Disable socket handler in case keep alive set. */	socketDeleteHandler(wp->sid);	if (code != 200) {		wp->flags &= ~WEBS_KEEP_ALIVE;	}#ifdef WEBS_PROXY_SUPPORT	if (! (wp->flags & WEBS_LOCAL_PAGE)) {		websStats.activeNetRequests--;	}#endif#ifdef WEBS_LOG_SUPPORT	if (! (wp->flags & WEBS_REQUEST_DONE)) {		websLog(wp, code);	}#endif/* *	Close any opened document by a handler */	websPageClose(wp);/* *	Exit if secure. */#ifdef WEBS_SSL_SUPPORT	if (wp->flags & WEBS_SECURE) {		websTimeoutCancel(wp);		websSSLFlush(wp->wsp);		socketCloseConnection(wp->sid);		websFree(wp);		return;	}#endif/* *	If using Keep Alive (HTTP/1.1) we keep the socket open for a period *	while waiting for another request on the socket.  */	if (wp->flags & WEBS_KEEP_ALIVE) {		if (socketFlush(wp->sid) == 0) {			wp->state = WEBS_BEGIN;			wp->flags |= WEBS_REQUEST_DONE;			if (wp->header.buf) {				ringqFlush(&wp->header);			}			socketCreateHandler(wp->sid, SOCKET_READABLE, websSocketEvent, 				(int) wp);			websTimeoutCancel(wp);			wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout,				(void *) wp);			return;		}	} else {		websTimeoutCancel(wp);		socketSetBlock(wp->sid, 1);		socketFlush(wp->sid);		socketCloseConnection(wp->sid);	}	websFree(wp);}/******************************************************************************//* *	Allocate a new webs structure */int websAlloc(int sid){	webs_t		wp;	int			wid;/* *	Allocate a new handle for this connection */	if ((wid = hAllocEntry((void***) &webs, &websMax,			sizeof(struct websRec))) < 0) {		return -1;	}	wp = webs[wid];	wp->wid = wid;	wp->sid = sid;	wp->state = WEBS_BEGIN;	wp->docfd = -1;	wp->timeout = -1;	wp->dir = NULL;	wp->authType = NULL;	wp->protocol = NULL;	wp->protoVersion = NULL;	wp->password = NULL;	wp->userName = NULL;#ifdef DIGEST_ACCESS_SUPPORT	wp->realm = NULL;	wp->nonce = NULL;	wp->digest = NULL;	wp->uri = NULL;	wp->opaque = NULL;	wp->nc = NULL;	wp->cnonce = NULL;	wp->qop = NULL;#endif#ifdef WEBS_SSL_SUPPORT	wp->wsp = NULL;#endif	ringqOpen(&wp->header, WEBS_HEADER_BUFINC, WEBS_MAX_HEADER);/* *	Create storage for the CGI variables. We supply the symbol tables for *	both the CGI variables and for the global functions. The function table *	is common to all webs instances (ie. all browsers) */	wp->cgiVars = symOpen(WEBS_SYM_INIT);	return wid;}/******************************************************************************//* *	Free a webs structure */void websFree(webs_t wp){	a_assert(websValid(wp));	if (wp->path)		bfree(B_L, wp->path);	if (wp->url)		bfree(B_L, wp->url);	if (wp->host)		bfree(B_L, wp->host);	if (wp->lpath)		bfree(B_L, wp->lpath);	if (wp->query)		bfree(B_L, wp->query);	if (wp->decodedQuery)		bfree(B_L, wp->decodedQuery);	if (wp->authType)		bfree(B_L, wp->authType);	if (wp->password)		bfree(B_L, wp->password);	if (wp->userName)		bfree(B_L, wp->userName);	if (wp->cookie)		bfree(B_L, wp->cookie);	if (wp->userAgent)		bfree(B_L, wp->userAgent);	if (wp->dir)		bfree(B_L, wp->dir);	if (wp->protocol)		bfree(B_L, wp->protocol);	if (wp->protoVersion)		bfree(B_L, wp->protoVersion);	if (wp->cgiStdin)		bfree(B_L, wp->cgiStdin);#ifdef DIGEST_ACCESS_SUPPORT	if (wp->realm)		bfree(B_L, wp->realm);	if (wp->uri)		bfree(B_L, wp->uri);	if (wp->digest)		bfree(B_L, wp->digest);	if (wp->opaque)		bfree(B_L, wp->opaque);	if (wp->nonce)		bfree(B_L, wp->nonce);	if (wp->nc)		bfree(B_L, wp->nc);	if (wp->cnonce)		bfree(B_L, wp->cnonce);	if (wp->qop)		bfree(B_L, wp->qop);#endif#ifdef WEBS_SSL_SUPPORT	websSSLFree(wp->wsp);#endif	symClose(wp->cgiVars);	if (wp->header.buf) {		ringqClose(&wp->header);	}	websMax = hFree((void***) &webs, wp->wid);	bfree(B_L, wp);	a_assert(websMax >= 0);}/******************************************************************************//* *	Return the server address */char_t *websGetHost(){	return websHost;}/******************************************************************************//* *	Return the the url to access the server. (ip address) */char_t *websGetIpaddrUrl(){	return websIpaddrUrl;}/******************************************************************************//* *	Return the server address */char_t *websGetHostUrl(){	return websHostUrl;}/******************************************************************************//* *	Return the listen port */int websGetPort(){	return websPort;}/******************************************************************************//* *	Get the number of bytes to write */int websGetRequestBytes(webs_t wp){	a_assert(websValid(wp));	return wp->numbytes;}/******************************************************************************//* *	Get the directory for this request */char_t *websGetRequestDir(webs_t wp){	a_assert(websValid(wp));	if (wp->dir == NULL) {		return T("");	}	return wp->dir;}/******************************************************************************//* *	Get the flags for this request */int websGetRequestFlags(webs_t wp){	a_assert(websValid(wp));	return wp->flags;}/******************************************************************************//* *	Return the IP address */char_t *websGetRequestIpaddr(webs_t wp){	a_assert(websValid(wp));	return wp->ipaddr;}/******************************************************************************//* *	Set the local path for the request */char_t *websGetRequestLpath(webs_t wp){	a_assert(websValid(wp));#ifdef WEBS_PAGE_ROM	return wp->path;#else	return wp->lpath;#endif}/******************************************************************************//* *	Get the path for this request */char_t *websGetRequestPath(webs_t wp){	a_assert(websValid(wp));	if (wp->path == NULL) {		return T("");	}	return wp->path;}/******************************************************************************//* *	Return the password */char_t *websGetRequestPassword(webs_t wp){	a_assert(websValid(wp));	return wp->password;}/******************************************************************************//* *	Return the request type */char_t *websGetRequestType(webs_t wp){	a_assert(websValid(wp));	return wp->type;}/******************************************************************************//* *	Return the username */char_t *websGetRequestUserName(webs_t wp){	a_assert(websValid(wp));	return wp->userName;}/******************************************************************************//* *	Get the number of bytes written */int websGetRequestWritten(webs_t wp){	a_assert(websValid(wp));	return wp->written;}/******************************************************************************//* *	Set the hostname */void websSetHost(char_t *host){	gstrncpy(websHost, host, TSZ(websHost));}/******************************************************************************//* *	Set the host URL */void websSetHostUrl(char_t *url){	a_assert(url && *url);	bfreeSafe(B_L, websHostUrl);	websHostUrl = gstrdup(B_L, url);}/******************************************************************************//* *	Set the IP address */void websSetIpaddr(char_t *ipaddr){	a_assert(ipaddr && *ipaddr);	gstrncpy(websIpaddr, ipaddr, TSZ(websIpaddr));}/******************************************************************************//* *	Set the number of bytes to write */void websSetRequestBytes(webs_t wp, int bytes)

⌨️ 快捷键说明

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