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

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

?? webs.c

?? 在嵌入式移動設備上實現動態網頁
?? 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一区二区三区免费野_久草精品视频
国产精品美女久久久久久久久久久 | 99久久国产综合精品女不卡| 不卡一区二区三区四区| 欧美影院一区二区三区| 久久美女艺术照精彩视频福利播放| ...xxx性欧美| 国产伦精一区二区三区| 欧美日韩国产成人在线免费| 国产精品女人毛片| 国产一区二区三区精品欧美日韩一区二区三区 | 日韩一区二区在线观看| 1024成人网| 国产 欧美在线| 精品国产凹凸成av人导航| 亚洲最大成人综合| 国产精品1区2区3区在线观看| 欧美性猛片xxxx免费看久爱| 国产精品理伦片| 国产精品一区一区三区| 日韩欧美一级片| 日韩经典中文字幕一区| 色偷偷成人一区二区三区91| 99九九99九九九视频精品| 国产精品一卡二| 精品免费国产二区三区| 人人精品人人爱| 欧美人动与zoxxxx乱| 洋洋av久久久久久久一区| 日本高清不卡视频| 亚洲免费在线播放| 色av一区二区| 一区二区三区四区不卡视频| 色综合久久久久综合体| 亚洲精品五月天| 亚洲一区二区视频在线| 日韩在线卡一卡二| 欧美一级专区免费大片| 麻豆国产一区二区| 丰满放荡岳乱妇91ww| 国产精品免费免费| 不卡的av电影| 亚洲精品一卡二卡| 欧美日韩在线直播| 欧美aⅴ一区二区三区视频| 日韩午夜精品电影| 国产综合久久久久影院| 国产婷婷一区二区| 9i看片成人免费高清| 夜夜夜精品看看| 91精品国产综合久久小美女 | 亚洲精品日韩专区silk| 91在线小视频| 日韩激情av在线| 亚洲欧美色一区| 裸体一区二区三区| 久久蜜桃香蕉精品一区二区三区| 国产麻豆精品视频| 91网站黄www| 欧美日韩国产影片| 国产一区二区h| 一区精品在线播放| 欧美日韩精品是欧美日韩精品| 日韩成人免费看| 国产亚洲精品7777| 欧美羞羞免费网站| 狠狠色丁香婷婷综合久久片| 中文字幕成人av| 精品视频一区二区不卡| 国产自产2019最新不卡| 亚洲欧美日韩国产成人精品影院| 6080日韩午夜伦伦午夜伦| 国产剧情在线观看一区二区| 一区二区三区日韩| 精品捆绑美女sm三区| 97精品超碰一区二区三区| 精品久久久久久无| 91久久精品一区二区| 日韩欧美aaaaaa| 中文字幕第一页久久| 在线播放视频一区| 99视频精品免费视频| 免费成人在线网站| 亚洲欧美日韩久久| 国产午夜亚洲精品不卡| 欧美另类z0zxhd电影| 成人免费黄色在线| 久久91精品国产91久久小草| 一区二区三区四区亚洲| 久久精品人人做人人爽97| 欧美日韩高清一区二区| 北条麻妃一区二区三区| 精品一区二区免费视频| 视频一区二区中文字幕| 亚洲精品免费看| 国产精品久久福利| 国产亚洲综合性久久久影院| 91精品国产综合久久精品app| 一本久久a久久免费精品不卡| 国产一区二三区好的| 热久久久久久久| 亚洲国产欧美在线人成| 亚洲女同一区二区| 亚洲欧美一区二区在线观看| 欧美国产日韩a欧美在线观看| 欧美大片免费久久精品三p| 欧美电影在哪看比较好| 欧美色图一区二区三区| 日本丶国产丶欧美色综合| 99久久国产综合色|国产精品| 成人免费精品视频| 成人永久aaa| 成人午夜激情片| 成人性色生活片| 亚洲人成在线观看一区二区| 成人黄色777网| 99re视频精品| 99久久精品国产观看| 91在线观看下载| 91丨九色丨蝌蚪丨老版| 91在线观看一区二区| 色先锋久久av资源部| 在线视频国内自拍亚洲视频| 欧美性videosxxxxx| 欧美图片一区二区三区| 欧美日韩国产123区| 欧美高清视频在线高清观看mv色露露十八 | 成人黄色777网| 色综合久久六月婷婷中文字幕| 一本色道a无线码一区v| 天天综合天天综合色| 国产精品一二一区| 亚洲精品五月天| 日韩二区在线观看| 久久国产免费看| 国产精品亚洲视频| av不卡免费在线观看| 欧美无砖砖区免费| 欧美哺乳videos| 国产精品久久毛片av大全日韩| 亚洲欧洲精品一区二区三区| 一区二区三区中文字幕| 午夜激情一区二区三区| 精品一二线国产| av成人老司机| 日韩午夜激情免费电影| 国产精品第四页| 午夜电影网亚洲视频| 国产一区二区视频在线播放| 99久久久国产精品免费蜜臀| 欧美色图激情小说| 精品久久久三级丝袜| 亚洲视频免费在线观看| 欧美a一区二区| 91在线观看免费视频| 欧美一级淫片007| 亚洲欧美偷拍三级| 久久99久久99小草精品免视看| 99久久久久久| 久久综合狠狠综合久久激情| 一区二区三区av电影| 国产剧情一区在线| 在线电影国产精品| 一区在线观看视频| 国产精品一区不卡| 欧美一区二区美女| 亚洲久本草在线中文字幕| 国产成人av在线影院| 在线播放中文字幕一区| 在线亚洲人成电影网站色www| 337p粉嫩大胆噜噜噜噜噜91av | 在线观看亚洲精品| 国产欧美日韩在线看| 亚洲va欧美va人人爽| 97久久人人超碰| 国产色一区二区| 麻豆成人在线观看| 欧美日韩三级视频| 亚洲欧美日韩中文播放| 国产精品123| 日韩欧美成人午夜| 日韩中文字幕一区二区三区| 91网站黄www| 中文字幕一区二区三区精华液| 激情伊人五月天久久综合| 欧美日本乱大交xxxxx| 一区二区在线电影| 91亚洲国产成人精品一区二三 | 91在线免费视频观看| 久久亚洲二区三区| 精品一区二区影视| 91精品国产色综合久久不卡电影 | 91精品国产综合久久香蕉麻豆 | 国产成人精品www牛牛影视| 欧美成人r级一区二区三区| 亚洲bt欧美bt精品777| 污片在线观看一区二区| 天堂av在线一区| 免费成人深夜小野草| 欧美一区国产二区| 美女任你摸久久|