亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? webs.c

?? 嵌入式Linux系統用的web server,開源代碼,非常好用
?? C
?? 第 1 頁 / 共 5 頁
字號:
/*
 * webs.c -- GoAhead Embedded HTTP webs server
 *
 * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
 *
 * See the file "license.txt" for usage and redistribution license requirements
 *
 * $Id: webs.c,v 1.16 2003/04/11 18:02:02 bporter Exp $
 */

/******************************** Description *********************************/

/*
 *	This module implements an embedded HTTP/1.1 web server. It supports
 *	loadable URL handlers that define the nature of URL processing performed.
 */

/********************************* Includes ***********************************/

#include	"wsIntrn.h"
#ifdef DIGEST_ACCESS_SUPPORT
	#include	"websda.h"
#endif

/******************************** Global Data *********************************/

websStatsType	websStats;				/* Web access stats */
webs_t			*webs;					/* Open connection list head */
sym_fd_t		websMime;				/* Set of mime types */
int				websMax;				/* List size */
int				websPort;				/* Listen port for server */
char_t			websHost[64];			/* Host name for the server */
char_t			websIpaddr[64];			/* IP address for the server */
char_t			*websHostUrl = NULL;	/* URL to access server */
char_t			*websIpaddrUrl = NULL;	/* URL to access server */

/*********************************** Locals ***********************************/
/*
 *	Standard HTTP error codes
 */

websErrorType websErrors[] = {
	{ 200, T("Data follows") },
	{ 204, T("No Content") },
	{ 301, T("Redirect") },
	{ 302, T("Redirect") },
	{ 304, T("Use local copy") },
	{ 400, T("Page not found") },
	{ 401, T("Unauthorized") },
	{ 403, T("Forbidden") },
	{ 404, T("Site or Page Not Found") },
	{ 405, T("Access Denied") },
	{ 500, T("Web Error") },
	{ 501, T("Not Implemented") },
	{ 503, T("Site Temporarily Unavailable. Try again.") },
	{ 0, NULL }
};

#ifdef WEBS_LOG_SUPPORT
static char_t	websLogname[64] = T("log.txt");	/* Log filename */
static int 		websLogFd;						/* Log file handle */
#endif

static int		websListenSock;					/* Listen socket */
static char_t	websRealm[64] = T("GoAhead");	/* Realm name */

static int		websOpenCount = 0;		/* count of apps using this module */

/**************************** Forward Declarations ****************************/


/*static char_t 	*websErrorMsg(int code);*/
static int 		websGetInput(webs_t wp, char_t **ptext, int *nbytes);
static int 		websParseFirst(webs_t wp, char_t *text);
static void 	websParseRequest(webs_t wp);
static void		websSocketEvent(int sid, int mask, int data);
static int		websGetTimeSinceMark(webs_t wp);

#ifdef WEBS_LOG_SUPPORT
static void 	websLog(webs_t wp, int code);
#endif
#ifdef WEBS_IF_MODIFIED_SUPPORT
static time_t	dateParse(time_t tip, char_t *cmd);
#endif

/*********************************** Code *************************************/
/*
 *	Open the GoAhead WebServer
 */

int websOpenServer(int port, int retries)
{
	websMimeType	*mt;

	if (++websOpenCount != 1) {
		return websPort;
	}

	a_assert(port > 0);
	a_assert(retries >= 0);

#ifdef WEBS_PAGE_ROM
	websRomOpen();
#endif

	webs = NULL;
	websMax = 0;
/*
 *	Create a mime type lookup table for quickly determining the content type
 */
	websMime = symOpen(WEBS_SYM_INIT * 4);
	a_assert(websMime >= 0);
	for (mt = websMimeList; mt->type; mt++) {
		symEnter(websMime, mt->ext, valueString(mt->type, 0), 0);
	}

/*
 *	Open the URL handler module. The caller should create the required
 *	URL handlers after calling this function.
 */
	if (websUrlHandlerOpen() < 0) {
		return -1;
	}
	websFormOpen();

#ifdef WEBS_LOG_SUPPORT
/*
 *	Optional request log support
 */
	websLogFd = gopen(websLogname, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY, 
		0666);
	a_assert(websLogFd >= 0);
#endif
	
	return websOpenListen(port, retries);
}

/******************************************************************************/
/*
 *	Close the GoAhead WebServer
 */

void websCloseServer()
{
	webs_t	wp;
	int		wid;

	if (--websOpenCount > 0) {
		return;
	}

/*
 *	Close the listen handle first then all open connections.
 */
	websCloseListen();

/* 
 *	Close each open browser connection and free all resources
 */
	for (wid = websMax; webs && wid >= 0; wid--) {
		if ((wp = webs[wid]) == NULL) {
			continue;
		}
		socketCloseConnection(wp->sid);
		websFree(wp);
	}

#ifdef WEBS_LOG_SUPPORT
	if (websLogFd >= 0) {
		close(websLogFd);
		websLogFd = -1;
	}
#endif

#ifdef WEBS_PAGE_ROM
	websRomClose();
#endif
	symClose(websMime);
	websFormClose();
	websUrlHandlerClose();
}

/******************************************************************************/
/*
 *	Open the GoAhead WebServer listen port
 */

int websOpenListen(int port, int retries)
{
	int		i, orig;

	a_assert(port > 0);
	a_assert(retries >= 0);

	orig = port;
/*
 *	Open the webs webs listen port. If we fail, try the next port.
 */
	for (i = 0; i <= retries; i++) {
		websListenSock = socketOpenConnection(NULL, port, websAccept, 0);
		if (websListenSock >= 0) {
			break;
		}
		port++;
	}
	if (i > retries) {
		error(E_L, E_USER, T("Couldn't open a socket on ports %d - %d"),
			orig, port - 1);
		return -1;
	} 

/*
 *	Determine the full URL address to access the home page for this web server
 */
	websPort = port;
	bfreeSafe(B_L, websHostUrl);
	bfreeSafe(B_L, websIpaddrUrl);
	websIpaddrUrl = websHostUrl = NULL;

	if (port == 80) {
		websHostUrl = bstrdup(B_L, websHost);
		websIpaddrUrl = bstrdup(B_L, websIpaddr);
	} else {
		fmtAlloc(&websHostUrl, WEBS_MAX_URL + 80, T("%s:%d"), websHost, port);
		fmtAlloc(&websIpaddrUrl, WEBS_MAX_URL + 80, T("%s:%d"), 
			websIpaddr, port);
	}
	trace(0, T("webs: Listening for HTTP requests at address %s\n"),
		websIpaddrUrl);

	return port;
}

/******************************************************************************/
/*
 *	Close webs listen port
 */

void websCloseListen()
{
	if (websListenSock >= 0) {
		socketCloseConnection(websListenSock);
		websListenSock = -1;
	}
	bfreeSafe(B_L, websHostUrl);
	bfreeSafe(B_L, websIpaddrUrl);
	websIpaddrUrl = websHostUrl = NULL;
}

/******************************************************************************/
/*
 *	Accept a connection
 */

int websAccept(int sid, char *ipaddr, int port, int listenSid)
{
	webs_t	wp;
	int		wid;

	a_assert(ipaddr && *ipaddr);
	a_assert(sid >= 0);
	a_assert(port >= 0);

/*
 *	Allocate a new handle for this accepted connection. This will allocate
 *	a webs_t structure in the webs[] list
 */
	if ((wid = websAlloc(sid)) < 0) {
		return -1;
	}
	wp = webs[wid];
	a_assert(wp);
	wp->listenSid = listenSid;

	ascToUni(wp->ipaddr, ipaddr, min(sizeof(wp->ipaddr), strlen(ipaddr) + 1));

/*
 *	Check if this is a request from a browser on this system. This is useful
 *	to know for permitting administrative operations only for local access
 */
	if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 || 
			gstrcmp(wp->ipaddr, websIpaddr) == 0 || 
			gstrcmp(wp->ipaddr, websHost) == 0) {
		wp->flags |= WEBS_LOCAL_REQUEST;
	}

/*
 *	Arrange for websSocketEvent to be called when read data is available
 */
	socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, (int) wp);

/*
 *	Arrange for a timeout to kill hung requests
 */
	wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp);
	trace(8, T("webs: accept request\n"));
	return 0;
}

/******************************************************************************/
/*
 *	The webs socket handler.  Called in response to I/O. We just pass control
 *	to the relevant read or write handler. A pointer to the webs structure
 *	is passed as an (int) in iwp.
 */

static void websSocketEvent(int sid, int mask, int iwp)
{
	webs_t	wp;

	wp = (webs_t) iwp;
	a_assert(wp);

	if (! websValid(wp)) {
		return;
	}

	if (mask & SOCKET_READABLE) {
		websReadEvent(wp);
	} 
	if (mask & SOCKET_WRITABLE) {
		if (websValid(wp) && wp->writeSocket) {
			(*wp->writeSocket)(wp);
		}
	} 
}

/******************************************************************************/
/*
 *	The webs read handler. This is the primary read event loop. It uses a
 *	state machine to track progress while parsing the HTTP request. 
 *	Note: we never block as the socket is always in non-blocking mode.
 */

void websReadEvent(webs_t wp)
{
	char_t 	*text;
	int		rc, nbytes, len, done, fd;

	a_assert(wp);
	a_assert(websValid(wp));

	websSetTimeMark(wp);

/*
 *	Read as many lines as possible. socketGets is called to read the header
 *	and socketRead is called to read posted data.
 */
	text = NULL;
	fd = -1;
	for (done = 0; !done; ) {
		if (text) {
			bfree(B_L, text);
			text = NULL;
		}

/*
 *		Get more input into "text". Returns 0, if more data is needed
 *		to continue, -1 if finished with the request, or 1 if all 
 *		required data is available for current state.
 */
		while ((rc = websGetInput(wp, &text, &nbytes)) == 0) {
			;
		}

/*
 *		websGetInput returns -1 if it finishes with the request
 */
		if (rc < 0) {
			break;
		}

/*
 *		This is the state machine for the web server. 
 */
		switch(wp->state) {
		case WEBS_BEGIN:
/*
 *			Parse the first line of the Http header
 */
			if (websParseFirst(wp, text) < 0) {
				done++;
				break;
			}
			wp->state = WEBS_HEADER;
			break;
		
		case WEBS_HEADER:
/*
 *			Store more of the HTTP header. As we are doing line reads, we
 *			need to separate the lines with '\n'
 */
			if (ringqLen(&wp->header) > 0) {
				ringqPutStr(&wp->header, T("\n"));
			}
			ringqPutStr(&wp->header, text);
			break;

		case WEBS_POST_CLEN:
/*
 *			POST request with content specified by a content length.
 *			If this is a CGI request, write the data to the cgi stdin.
 *			socketGets was used to get the data and it strips \n's so
 *			add them back in here.
 */
#ifndef __NO_CGI_BIN
			if (wp->flags & WEBS_CGI_REQUEST) {
				if (fd == -1) {
					fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY,
						0666);
				}
				gwrite(fd, text, gstrlen(text));
            /*
             * NOTE that the above comment is wrong -- if the content length
             * is set, websGetInput() does NOT use socketGets(), it uses
             * socketRead(), so the line below that adds an additional newline
             * is destructive.
             */
				/*gwrite(fd, T("\n"), sizeof(char_t));*/
/*
 *				Line removed as per BUG02488
 *
				nbytes += 1;
 */
			} else 
#endif
			if (wp->query) {
				if (wp->query[0] && !(wp->flags & WEBS_POST_DATA)) {
/*
 *					Special case where the POST request also had query data 
 *					specified in the URL, ie. url?query_data. In this case
 *					the URL query data is separated by a '&' from the posted
 *					query data.
 */
					len = gstrlen(wp->query);
					wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) +
						2) * sizeof(char_t));
					wp->query[len++] = '&';
					gstrcpy(&wp->query[len], text);

				} else {
/*
 *					The existing query data came from the POST request so just
 *					append it.
 */
               if (text != NULL)
               {
                  len = gstrlen(wp->query);
                  wp->query = brealloc(B_L, wp->query, (len +	gstrlen(text) +
                     1) * sizeof(char_t));
                  if (wp->query) {
                     gstrcpy(&wp->query[len], text);
                  }
               }
				}

			} else {
				wp->query = bstrdup(B_L, text);
			}
/*
 *			Calculate how much more post data is to be read.
 */
			wp->flags |= WEBS_POST_DATA;
			wp->clen -= nbytes;
			if (wp->clen > 0) {
				if (nbytes > 0) {
					break;
				}
				done++;
				break;
			}
/*
 *			No more data so process the request, (but be sure to close
 *			the input file first!).
 */
			if (fd != -1) {
				gclose (fd);
				fd = -1;
			}
			websUrlHandlerRequest(wp);
			done++;
			break;

		case WEBS_POST:
/*
 *			POST without content-length specification
 *			If this is a CGI request, write the data to the cgi stdin.
 *			socketGets was used to get the data and it strips \n's so
 *			add them back in here.
 */

#ifndef __NO_CGI_BIN
			if (wp->flags & WEBS_CGI_REQUEST) {
				if (fd == -1) {
					fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY,
						0666);
				}
				gwrite(fd, text, gstrlen(text));
				gwrite(fd, T("\n"), sizeof(char_t));
			} else
#endif
			if (wp->query && *wp->query && !(wp->flags & WEBS_POST_DATA)) {
				len = gstrlen(wp->query);
				wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) +
					2) * sizeof(char_t));
				if (wp->query) {
					wp->query[len++] = '&';
					gstrcpy(&wp->query[len], text);
				}

			} else {
				wp->query = bstrdup(B_L, text);
			}
			wp->flags |= WEBS_POST_DATA;
			done++;
			break;

		default:
			websError(wp, 404, T("Bad state"));
			done++;
			break;
		}
	}

	if (fd != -1) {
		fd = gclose (fd);
	}

	if (text) {
		bfree(B_L, text);
	}
}

/******************************************************************************/
/*
 *	Get input from the browser. Return TRUE (!0) if the request has been 
 *	handled. Return -1 on errors or if the request has been processed, 
 *	1 if input read, and 0 to instruct the caller to call again for more input.
 *
 *	Note: socketRead will Return the number of bytes read if successful. This
 *	may be less than the requested "bufsize" and may be zero. It returns -1 for
 *	errors. It returns 0 for EOF. Otherwise it returns the number of bytes 
 *	read. Since this may be zero, callers should use socketEof() to 
 *	distinguish between this and EOF.
 */

static int websGetInput(webs_t wp, char_t **ptext, int *pnbytes) 
{
	char_t	*text;
	char	buf[WEBS_SOCKET_BUFSIZ+1];
	int		nbytes, len, clen;

	a_assert(websValid(wp));

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美电影免费观看高清完整版在| 蜜桃av噜噜一区二区三区小说| 亚洲成av人片在线观看无码| 麻豆中文一区二区| 91啪九色porn原创视频在线观看| 日韩天堂在线观看| 夜夜操天天操亚洲| 成人精品视频一区二区三区| 欧美大片在线观看一区| 亚洲主播在线观看| 91看片淫黄大片一级在线观看| 欧美精品一区二区三区蜜臀| 午夜国产不卡在线观看视频| 99精品久久99久久久久| 国产亚洲欧美一区在线观看| 久久精品久久综合| 欧美欧美午夜aⅴ在线观看| 亚洲你懂的在线视频| 国产盗摄一区二区三区| 欧美精品一区二区三区在线| 蜜臀av一区二区在线观看| 欧美日韩国产色站一区二区三区| 成人免费一区二区三区在线观看| 国产成人在线网站| 国产日产亚洲精品系列| 国产一区二区影院| 精品国产一区二区三区久久久蜜月| 图片区小说区国产精品视频| 欧美日韩一二区| 亚洲综合免费观看高清完整版在线 | 色8久久精品久久久久久蜜| 久久久不卡影院| 国产黄色精品网站| 中文字幕电影一区| www.一区二区| 亚洲欧美电影院| 色综合久久六月婷婷中文字幕| 国产精品久久看| 在线日韩av片| 天堂久久久久va久久久久| 欧美一区二区日韩一区二区| 奇米影视一区二区三区| 欧美大片在线观看一区| 国产福利不卡视频| 亚洲男人的天堂在线aⅴ视频| 91女人视频在线观看| 亚洲一级不卡视频| 91精品国产综合久久婷婷香蕉| 日本不卡在线视频| 久久精品男人的天堂| 99久久精品国产导航| 亚洲一区二区三区四区五区中文| 欧美日韩精品电影| 国产麻豆一精品一av一免费 | 久久亚洲综合色一区二区三区| 韩国精品在线观看| 国产精品毛片高清在线完整版| 91精彩视频在线观看| 日韩精品欧美精品| 国产亚洲一区二区在线观看| 97se亚洲国产综合自在线不卡| 亚洲超碰97人人做人人爱| 精品国产99国产精品| a级精品国产片在线观看| 亚洲成a人片在线观看中文| 精品国产成人系列| 在线一区二区观看| 韩国三级在线一区| 亚洲精品乱码久久久久久日本蜜臀| 欧美日韩日日摸| 国产成人av福利| 亚洲444eee在线观看| 中文av一区二区| 欧美一区二区三区在线观看 | 欧美日韩不卡视频| 成人免费视频免费观看| 日韩精品成人一区二区三区| 国产精品美日韩| 日韩午夜激情视频| 欧美视频在线不卡| 国产麻豆91精品| 日日摸夜夜添夜夜添国产精品| 国产精品少妇自拍| 精品久久国产老人久久综合| 日本二三区不卡| 粉嫩一区二区三区性色av| 日韩av一级电影| 亚洲福利一区二区三区| 欧美国产精品v| 久久这里只精品最新地址| 欧美日韩精品一区二区三区 | 成人h精品动漫一区二区三区| 日本不卡不码高清免费观看| 国产精品久久久久久户外露出 | 日韩你懂的在线观看| 欧美三级一区二区| 99re免费视频精品全部| 国产69精品久久久久777| 久久精品国产久精国产| 五月激情丁香一区二区三区| 亚洲电影中文字幕在线观看| 亚洲狠狠丁香婷婷综合久久久| 国产视频亚洲色图| 国产亚洲视频系列| 久久精品无码一区二区三区 | 欧美日韩亚洲丝袜制服| 91丨九色丨黑人外教| 成人精品电影在线观看| 高清不卡一区二区| 成人免费毛片app| 粉嫩欧美一区二区三区高清影视 | 欧美挠脚心视频网站| 在线观看免费亚洲| 欧美日韩在线电影| 欧美日韩成人综合在线一区二区| 在线观看三级视频欧美| 欧美日韩和欧美的一区二区| 欧美日韩亚洲综合在线| 91精品国产麻豆国产自产在线| 69精品人人人人| 2020国产精品久久精品美国| 精品美女在线观看| 国产亚洲欧美激情| 国产女人18水真多18精品一级做| 欧美激情在线一区二区| 亚洲天堂精品视频| 亚洲线精品一区二区三区| 偷拍日韩校园综合在线| 久久国产人妖系列| 豆国产96在线|亚洲| 色乱码一区二区三区88| 欧美视频在线一区二区三区| 欧美一区二区大片| 国产女人18毛片水真多成人如厕| 中文字幕+乱码+中文字幕一区| 亚洲视频免费观看| 日一区二区三区| 国产精品456| 欧美性一级生活| 日韩精品一区国产麻豆| 中文字幕乱码亚洲精品一区| 亚洲一线二线三线视频| 久久99最新地址| 99久久精品国产毛片| 6080国产精品一区二区| 国产欧美一区二区精品性| 亚洲一级二级三级在线免费观看| 麻豆精品在线视频| 国产91清纯白嫩初高中在线观看| 91福利精品第一导航| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 综合激情网...| 奇米888四色在线精品| 成人久久视频在线观看| 欧美一区二区视频观看视频| 中文字幕一区二区三| 麻豆91在线观看| 色噜噜狠狠成人中文综合| 久久久一区二区三区| 亚洲一卡二卡三卡四卡无卡久久 | 中文幕一区二区三区久久蜜桃| 亚洲一区二区在线视频| 国产精品99精品久久免费| 欧美日韩电影在线| 国产精品每日更新在线播放网址| 免费的国产精品| 色婷婷综合久久久| 精品欧美黑人一区二区三区| 一区二区三区不卡视频在线观看| 国内精品免费**视频| 91麻豆精品国产综合久久久久久 | 色偷偷久久一区二区三区| 精品久久久久久无| 亚洲mv大片欧洲mv大片精品| eeuss影院一区二区三区| 精品久久久久久久久久久久久久久久久 | 日精品一区二区| 99久久国产免费看| 国产精品天美传媒| 国产精品一区三区| 91精品国产综合久久久蜜臀粉嫩| 亚洲视频一二三| 成av人片一区二区| 久久久三级国产网站| 精品亚洲国产成人av制服丝袜 | 麻豆精品久久精品色综合| 欧美图区在线视频| 一区二区三区不卡在线观看| 成人国产精品免费| 国产亚洲欧洲一区高清在线观看| 免费人成精品欧美精品| 在线播放亚洲一区| 亚洲mv在线观看| 欧美日韩成人综合在线一区二区| 亚洲一区二区三区中文字幕| 色婷婷av一区二区三区软件| 国产精品久久久久久亚洲伦| 国产成人综合自拍| 中文字幕av资源一区| 99精品欧美一区二区蜜桃免费|