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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? webs.c

?? 在嵌入式移動設(shè)備上實現(xiàn)動態(tài)網(wǎng)頁
?? 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));

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩va欧美va亚洲va久久| 日韩黄色免费网站| 欧美一区二区啪啪| 99国产精品久久久久| 看片网站欧美日韩| 一区二区三区免费| 国产午夜精品久久久久久免费视| 91国偷自产一区二区使用方法| 国产又黄又大久久| 日韩成人一区二区三区在线观看| 中文字幕一区日韩精品欧美| 精品国产乱码久久久久久久久| 在线观看亚洲专区| 白白色 亚洲乱淫| 加勒比av一区二区| 日韩精品福利网| 亚洲综合免费观看高清完整版在线 | 久久国产精品99久久人人澡| 一区二区理论电影在线观看| 中文字幕精品在线不卡| 欧美大片免费久久精品三p| 欧美日韩国产一区二区三区地区| av成人免费在线| 国产91对白在线观看九色| 久久超碰97中文字幕| 日韩精品午夜视频| 午夜精品国产更新| 一区二区在线观看免费视频播放| 国产欧美视频一区二区三区| 2020国产精品自拍| 日韩欧美不卡一区| 日韩精品影音先锋| 日韩精品一区二区三区在线| 欧美一级夜夜爽| 日韩视频在线永久播放| 欧美久久久久久久久| 欧美精品久久天天躁| 欧美片在线播放| 欧美日韩精品电影| 欧美日韩国产综合一区二区| 欧美在线你懂的| 欧美丰满一区二区免费视频 | 国产成人精品亚洲777人妖| 精品一区二区免费在线观看| 久久99久国产精品黄毛片色诱| 另类小说色综合网站| 国产一区二区调教| 国产不卡免费视频| 成人sese在线| 91美女在线观看| 欧美在线免费观看视频| 欧美日本免费一区二区三区| 91.xcao| 精品成人免费观看| 国产三级欧美三级日产三级99 | 一区二区三区中文在线| 亚洲午夜精品在线| 免费高清在线一区| 国产精品99久久久久久久女警| 日本成人在线一区| 国产精品一二二区| 91天堂素人约啪| 欧美伦理影视网| 精品国产青草久久久久福利| 国产三级精品在线| 一区二区三区成人在线视频| 无码av免费一区二区三区试看| 精品一区二区三区免费毛片爱| 国产一区二区不卡| 一本大道久久a久久精二百| 欧美日本一区二区三区| 精品999在线播放| 亚洲欧洲成人av每日更新| 亚洲一区二区视频在线观看| 热久久一区二区| 岛国一区二区在线观看| 91福利在线看| 精品日韩一区二区| 综合激情成人伊人| 免费观看在线综合色| 成人高清视频免费观看| 欧美年轻男男videosbes| 精品美女一区二区| 亚洲欧美日韩久久| 美女性感视频久久| 一本大道av伊人久久综合| 日韩三级中文字幕| 日韩一区二区在线看| 成人做爰69片免费看网站| 色婷婷激情久久| 欧美刺激午夜性久久久久久久| 国产精品蜜臀av| 日韩不卡免费视频| 91蜜桃在线免费视频| 精品成人在线观看| 亚洲高清免费视频| av高清不卡在线| 日韩欧美一二区| 亚洲国产精品一区二区www在线| 国产综合久久久久久久久久久久| 在线观看亚洲a| 中文字幕在线观看不卡视频| 久久99久久精品| 欧美日本韩国一区二区三区视频 | 国产精品人妖ts系列视频| 日韩精品电影一区亚洲| 99精品国产99久久久久久白柏| 日韩一区二区视频在线观看| 尤物在线观看一区| 成人精品免费网站| 26uuu精品一区二区| 日韩精品一二三四| 欧美性色综合网| 亚洲精品乱码久久久久久久久 | 一区二区视频免费在线观看| 日本欧美韩国一区三区| 99久久精品国产一区二区三区| 欧美精品一区二区在线观看| 亚洲bdsm女犯bdsm网站| 91亚洲精品久久久蜜桃网站 | 亚洲综合在线电影| 91亚洲国产成人精品一区二三| 久久久久久久久久久久电影| 久久激情五月婷婷| 日韩网站在线看片你懂的| 肉丝袜脚交视频一区二区| 91国模大尺度私拍在线视频| 亚洲日穴在线视频| 99re亚洲国产精品| 久久成人免费网| 欧美日本视频在线| 肉肉av福利一精品导航| 亚洲国产日韩精品| 久久久高清一区二区三区| 日韩精品欧美精品| 欧美日韩激情一区二区三区| 亚洲午夜激情av| 在线观看一区日韩| 一级做a爱片久久| 欧美日韩亚洲丝袜制服| 亚洲成人在线免费| 777精品伊人久久久久大香线蕉| 亚洲午夜激情网站| 欧美美女bb生活片| 久久精品99国产国产精| xf在线a精品一区二区视频网站| 国内一区二区在线| 国产精品美女久久久久aⅴ国产馆| 成人小视频免费在线观看| 国产精品高潮呻吟| 日本伦理一区二区| 亚洲第一会所有码转帖| 91精品国产美女浴室洗澡无遮挡| 美女脱光内衣内裤视频久久网站| 亚洲精品一线二线三线| 成人免费毛片片v| 亚洲人成精品久久久久久| 在线观看不卡一区| 美女视频一区二区| 欧美国产日韩在线观看| 99国产欧美久久久精品| 午夜精品久久久久久久| 精品国产乱子伦一区| 99久久精品99国产精品| 亚洲成av人片在www色猫咪| 欧美一区二区视频在线观看2022 | 亚洲一区二区在线观看视频| 欧美精选在线播放| 国产一本一道久久香蕉| 一区二区三区不卡视频| 6080日韩午夜伦伦午夜伦| 国产乱淫av一区二区三区| 亚洲欧美色一区| 日韩免费性生活视频播放| 成人av网在线| 日本欧美在线看| 自拍偷拍亚洲综合| 91精品在线一区二区| 成人免费av在线| 亚洲国产日韩一级| 国产日韩影视精品| 精品视频一区三区九区| 国产高清久久久| 一区二区三区在线免费视频| 精品毛片乱码1区2区3区| 91久久精品网| 国产大陆精品国产| 丝袜亚洲另类丝袜在线| 国产三级精品视频| 91精品黄色片免费大全| 99久久夜色精品国产网站| 日韩专区在线视频| 亚洲欧美偷拍卡通变态| 精品国产网站在线观看| 欧美性大战久久久久久久| 国产成人精品综合在线观看| 亚洲成a人片在线观看中文| 欧美国产欧美综合| 日韩一区二区免费在线观看| 久久久久久免费网|