| #include	"wsIntrn.h" | 
 | #ifdef DIGEST_ACCESS_SUPPORT | 
 | 	#include	"websda.h" | 
 | #endif | 
 | #include "../interface5.0/zte_web_interface.h" | 
 | //#include "../interface5.0/zte_rest_comm_interface.h" | 
 |  | 
 | websStatsType	websStats;				 | 
 | webs_t			*webs;					 | 
 | sym_fd_t		websMime;				 | 
 | int				websMax;				 | 
 | int				websPort;				 | 
 | char_t			websHost[64];			 | 
 | char_t			websIpaddr[64];			 | 
 | char_t			*websHostUrl = NULL;	 | 
 | char_t			*websIpaddrUrl = NULL;	 | 
 | //added by liuyingnan for PC Client begin, 20120829 | 
 | char websRecvHttpBuffer[HTTP_BUFFER_SIZE] = {0}; | 
 | char websRecvHttpBuffer_XML[HTTP_BUFFER_SIZE] = {0}; | 
 |  | 
 | extern void zte_change_wp_query(webs_t wp,char_t *xml_str); | 
 | //added by liuyingnan for PC Client begin, 20120829 | 
 |  | 
 | 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 } | 
 | }; | 
 |  | 
 | typedef enum {  | 
 | 	RET_DATA_ERROR = -1, | 
 | 	RET_FAILED = 0,  | 
 | 	RET_OK = 1,  | 
 | } ERROR_CODE; | 
 |  | 
 |  | 
 | #ifdef FEATURE_ZTE_WEB_TCARD | 
 | //added by guo shoupeng 10124224 for http share 20111001 start | 
 |  | 
 | typedef enum {  | 
 | 	RET_FAILED = 0,  | 
 | 	RET_OK = 1,  | 
 | 	RET_UNKNOWN = 3,	 | 
 | 	MALLOC_FIALED = 4, | 
 | 	SD_NONE = 5, | 
 | 	USB_OUT = 6, | 
 | 	USER_MALLOC_FAILED = 7, | 
 | 	UPLOAD_FILE_LIMITED = 8, | 
 | 	USER_UNKNOWN = 9,	 | 
 | } ERROR_CODE; | 
 |  | 
 | //added by guo shoupeng 10124224 for http share 20111001 end | 
 | #endif | 
 |  | 
 |  | 
 |  | 
 | static int 		websGetInput(webs_t wp, char_t **ptext, int *nbytes); | 
 | static int 		websParseFirst(webs_t wp, char_t *text); | 
 | static int 	websParseRequest(webs_t wp); | 
 | static void		websSocketEvent(int sid, int mask, int data); | 
 | static int		websGetTimeSinceMark(webs_t wp); | 
 |  | 
 | static int		websListenSock;					 | 
 | static char_t	websRealm[64] = T("GoAhead");	 | 
 |  | 
 | static int		websOpenCount = 0;		 | 
 |  | 
 |  | 
 | int websOpenServer(int port, int retries) | 
 | { | 
 | 	websMimeType	*mt; | 
 |  | 
 | 	if (++websOpenCount != 1) { | 
 | 		return websPort; | 
 | 	} | 
 |  | 
 | 	a_assert(port > 0); | 
 | 	a_assert(retries >= 0); | 
 |  | 
 | 	webs = NULL; | 
 | 	websMax = 0; | 
 |  | 
 | 	websMime = symOpen(WEBS_SYM_INIT * 4); | 
 | 	a_assert(websMime >= 0); | 
 | 	if(websMime < 0)  // cov M NEGATIVE_RETURNS | 
 | 	{ | 
 | 	    return -1; | 
 | 	} | 
 | 	for (mt = websMimeList; mt->type; mt++) { | 
 | 		symEnter(websMime, mt->ext, valueString(mt->type, 0), 0); | 
 | 	} | 
 |  | 
 | #if 1 | 
 |     // kw 3 INVARIANT_CONDITION.UNREACH websUrlHandlerOpen only return 0 | 
 |     websUrlHandlerOpen(); | 
 | #else | 
 | 	if (websUrlHandlerOpen() < 0) { | 
 | 		return -1; | 
 | 	} | 
 | #endif	 | 
 | 	websFormOpen(); | 
 |  | 
 | 	return websOpenListen(port, retries); | 
 | } | 
 |  | 
 |  | 
 |  | 
 | void websCloseServer() | 
 | { | 
 | 	webs_t	wp; | 
 | 	int		wid; | 
 |  | 
 | 	if (--websOpenCount > 0) { | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	websCloseListen(); | 
 |  | 
 | 	for (wid = websMax; webs && wid >= 0; wid--) { | 
 | 		if ((wp = webs[wid]) == NULL) { | 
 | 			continue; | 
 | 		} | 
 | 		socketCloseConnection(wp->sid); | 
 | 		websFree(wp); | 
 | 	} | 
 |  | 
 | 	symClose(websMime); | 
 | 	websFormClose(); | 
 | 	websUrlHandlerClose(); | 
 | } | 
 |  | 
 |  | 
 | void websCloseListen() | 
 | { | 
 | 	if (websListenSock >= 0) { | 
 | 		socketCloseConnection(websListenSock); | 
 | 		websListenSock = -1; | 
 | 	} | 
 | 	bfreeSafe(B_L, websHostUrl); | 
 | 	bfreeSafe(B_L, websIpaddrUrl); | 
 | 	websIpaddrUrl = websHostUrl = NULL; | 
 | } | 
 |  | 
 |  | 
 | int websOpenListen(int port, int retries) | 
 | { | 
 | 	int		i, orig; | 
 |  | 
 | 	a_assert(port > 0); | 
 | 	a_assert(retries >= 0); | 
 | 	 | 
 | 	orig = port; | 
 |  | 
 | 	for (i = 0; i <= retries; i++) { | 
 | 		websListenSock = socketOpenConnection6(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; | 
 | 	}  | 
 |  | 
 | 	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; | 
 | } | 
 |  | 
 |  | 
 | 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); | 
 | 		} | 
 | 	}  | 
 | } | 
 |  | 
 | 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); | 
 |  | 
 | 	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)); | 
 |  | 
 | 	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; | 
 | 	} | 
 |  | 
 | 	socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, (int) wp); | 
 |  | 
 | 	wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp); | 
 | 	//trace(8, T("webs: accept request\n")); | 
 | 	return 0; | 
 | } | 
 |  | 
 |  | 
 |  | 
 | #ifdef FEATURE_ZTE_WEB_TCARD | 
 | //added by guo shoupeng 10124224 for http share 20120110 start | 
 | static int read_bytes = 0; | 
 | //added by guo shoupeng 10124224 for http share 20120110 end | 
 | #endif | 
 |  | 
 | void websReadEvent(webs_t wp) | 
 | { | 
 | 	char_t 	*text; | 
 | 	int		rc, nbytes, len, done, fd; | 
 |  | 
 | 	a_assert(wp); | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	websSetTimeMark(wp); | 
 | 	 | 
 | 	static unsigned int timer = 0; | 
 |  | 
 | 	text = NULL; | 
 | 	fd = -1; | 
 | 	for (done = 0; !done; ) { | 
 | 		if (text) { | 
 | 			bfree(B_L, text); | 
 | 			text = NULL; | 
 | 		} | 
 |  | 
 |  | 
 | #ifdef FEATURE_ZTE_WEB_TCARD | 
 | //added by guo shoupeng 10124224 for http share 20120110 start | 
 | 		if( read_bytes > UPLOAD_INTERVAL) | 
 | 		{ | 
 | 			read_bytes = 0; | 
 | 			break; | 
 | 		} | 
 | //added by guo shoupeng 10124224 for http share 20120110 end | 
 | #endif | 
 | 		assert(wp); | 
 | 		assert(websValid(wp));		 | 
 | 		while ((rc = websGetInput(wp, &text, &nbytes)) == 0) { | 
 | 			; | 
 | 		} | 
 |  | 
 |  | 
 | 		if (rc < 0) { | 
 |             if(websValid(wp) && (wp->flags & WEBS_CGI_REQUEST )) | 
 |             { | 
 |                 //printf("\n +++sockettt upload websSetTimeMark+++ \n"); | 
 |                 websSetTimeMark(wp); | 
 |             } | 
 | 			break; | 
 | 		} | 
 | 		if(text == NULL) | 
 | 			break;//for kw | 
 |  | 
 | 		switch(wp->state) { | 
 | 		case WEBS_BEGIN: | 
 |  | 
 | 			if (websParseFirst(wp, text) < 0) { | 
 | 				done++; | 
 | 				break; | 
 | 			} | 
 | 			wp->state = WEBS_HEADER; | 
 | 			break; | 
 | 		 | 
 | 		case WEBS_HEADER: | 
 |  | 
 | 			if (ringqLen(&wp->header) > 0) { | 
 | 				ringqPutStr(&wp->header, T("\n")); | 
 | 			} | 
 | 			ringqPutStr(&wp->header, text); | 
 | 			break; | 
 |  | 
 | 		case WEBS_POST_CLEN: | 
 |  | 
 | #ifndef __NO_CGI_BIN | 
 | 			if (wp->flags & WEBS_CGI_REQUEST) { | 
 |  | 
 | 				//if(!(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD)) | 
 | 				if(wp->flags & WEBS_CGI_HTTPSHARE_UPLOAD) | 
 | 				{ | 
 | 					if( timer ==0) | 
 |                     { | 
 |                         websSetLoginTimemark(wp); | 
 | 						printf("[httpshare]upload reset login state~\n"); | 
 |                     } | 
 | 					ERROR_CODE ret = zte_process_cgi_recv(wp, wp->clen,text, nbytes);	 | 
 |  | 
 | 					if(RET_DATA_ERROR == ret || RET_FAILED == ret) | 
 | 					{												   | 
 | 						websError(wp, 404, T("Bad state")); | 
 | 						printf("[httpshare]ret->%d\n",ret); | 
 | 						done++; 						   | 
 | 						break;		   | 
 | 					}  | 
 | 					 | 
 | 					timer++; | 
 | 					timer=timer-(timer>>11<<11);  //timer%2^11 | 
 | 				}else if(wp->flags & WEBS_CGI_UPLOAD) | 
 | 				{ | 
 | 					if (fd == -1)  | 
 | 					{ | 
 | 						if(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD ) | 
 | 						{ | 
 | 							fd = gopen(FIRMWARE_TMP_FILE, O_CREAT | O_WRONLY | O_BINARY | O_APPEND, 0666); | 
 | 							printf("[goahead]open cgi temp file\n"); | 
 | 						} | 
 | 						else | 
 | 					  	{ | 
 | 							fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY | O_APPEND, 0666); | 
 | 	                    } | 
 | 					} | 
 |                     if(fd < 0){ | 
 |                         break; | 
 | 					} | 
 | 						 | 
 | 					 | 
 | 					gwrite(fd, text, nbytes); | 
 | 				}else | 
 | 				{ | 
 | 					websError(wp, 404, T("Bad state")); | 
 | 					printf("[goahead]bad cgi request\n"); | 
 | 					done++; 						   | 
 | 					break; | 
 | 				} | 
 |  | 
 |  | 
 | 			} else  | 
 | #endif | 
 | 			//added by liuyingnan for PC Client begin, 20120829 | 
 |             if(wp->flags & WEBS_REST_CLIENT_REQUEST){ | 
 |                 printf("%s", "websReadEvent: pc client post"); | 
 |                 if (nbytes > (HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer)-1)) | 
 |                 { | 
 |                     gstrncpy(websRecvHttpBuffer+gstrlen(websRecvHttpBuffer), text, HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer)-1); | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     gstrncpy(websRecvHttpBuffer+gstrlen(websRecvHttpBuffer), text, nbytes); | 
 |                 } | 
 |             } else  if(wp->flags & WEBS_XML_CLIENT_REQUEST){ | 
 |             if (nbytes > (HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer_XML)-1)) | 
 |             { | 
 |                 gstrncpy(websRecvHttpBuffer_XML+gstrlen(websRecvHttpBuffer_XML), text, HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer_XML)-1); | 
 |             } | 
 |             else | 
 |             { | 
 |                 gstrncpy(websRecvHttpBuffer_XML+gstrlen(websRecvHttpBuffer_XML), text, nbytes); | 
 |             } | 
 |             } else     | 
 | 			//added by liuyingnan for PC Client end, 20120829 | 
 |  | 
 |  | 
 |  | 
 | 			if (wp->query) { | 
 | 				if (wp->query[0] && !(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 == NULL) | 
 | 						break;//for kw | 
 | 					wp->query[len++] = '&'; | 
 | 					gstrcpy(&wp->query[len], text); | 
 |  | 
 | 				} else { | 
 |  | 
 |                //if (text != NULL)//for kw | 
 |                { | 
 |                   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); | 
 | 			} | 
 | #if 0 //for kw			 | 
 |             //Add By liuyingnan for XML COMM API START | 
 |             if(wp->flags & WEBS_XML_CLIENT_REQUEST) | 
 |             { | 
 |                 slog(MISC_PRINT,SLOG_DEBUG,"[websReadEvent]:change_wp_query function:%s\n",websRecvHttpBuffer_XML); | 
 |                 //zte_change_wp_query(wp,websRecvHttpBuffer_Json); | 
 |                 zte_change_wp_query(wp,websRecvHttpBuffer_XML); | 
 |                 memset(websRecvHttpBuffer_XML,0,HTTP_BUFFER_SIZE); | 
 |                 slog(MISC_PRINT,SLOG_DEBUG,"[out the function]:wp->query:%s\n",wp->query); | 
 |             }  | 
 |             //Add By liuyingnan for XML COMM API END | 
 | #endif | 
 |              | 
 | 			wp->flags |= WEBS_POST_DATA; | 
 | 			wp->clen -= nbytes; | 
 | 			if (wp->clen > 0) { | 
 | 				if (nbytes > 0) { | 
 | 					break; | 
 | 				} | 
 | 				done++; | 
 | 				break; | 
 | 			} | 
 | #ifdef FEATURE_ZTE_WEB_TCARD | 
 | //added by guo shoupeng 10124224 for http share 20120110 start | 
 | 			else | 
 | 			{ | 
 | 			    zte_efs_write(wp); | 
 | 			} | 
 | //added by guo shoupeng 10124224 for http share 20120110 end | 
 | #endif	 | 
 |  | 
 | 			if (fd != -1) { | 
 | 				gclose (fd); | 
 | 				fd = -1; | 
 | 			} | 
 | 			websUrlHandlerRequest(wp); | 
 | 			done++; | 
 | 			break; | 
 |  | 
 | 		case WEBS_POST: | 
 |  | 
 |  | 
 | #ifndef __NO_CGI_BIN | 
 | 			if (wp->flags & WEBS_CGI_REQUEST) { | 
 | 				if (fd == -1) { | 
 | 					fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY, | 
 | 						0666); | 
 | 				} | 
 |  | 
 | 				if(fd < 0){ | 
 |                     break; | 
 | 				} | 
 | 				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); | 
 | 	} | 
 | } | 
 | char_t	htmExt[] = T(".htm"); | 
 | int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath,  | 
 | 	char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag,  | 
 | 	char_t **pext) | 
 | { | 
 | 	char_t		*hostbuf, *portbuf, *buf; | 
 | 	int			c, len, ulen; | 
 | 	char_t		*tok, *cp, *host, *path, *port, *proto, *tag, *query, *ext; | 
 |  | 
 | 	a_assert(url); | 
 | 	a_assert(pbuf); | 
 |  | 
 | 	ulen = gstrlen(url); | 
 |  | 
 | 	len = ulen * 2 + MAX_PORT_LEN + 3; | 
 | 	if ((buf = balloc(B_L, len * sizeof(char_t))) == NULL) { | 
 | 		return -1; | 
 | 	} | 
 | 	portbuf = &buf[len - MAX_PORT_LEN - 1]; | 
 | 	hostbuf = &buf[ulen+1]; | 
 |  | 
 |  	websDecodeUrl(buf, url, ulen); | 
 |  | 
 | 	url = buf; | 
 |  | 
 | 	if(portbuf == NULL) //for kw 20210312 | 
 | 		return -1; | 
 | 	 | 
 | 	stritoa(websGetPort(), portbuf, MAX_PORT_LEN); | 
 | 	port = portbuf; | 
 | 	path = T("/"); | 
 | 	proto = T("http"); | 
 | 	host = T("localhost"); | 
 | 	query = T(""); | 
 | 	ext = htmExt; | 
 | 	tag = T(""); | 
 |  | 
 | 	if (gstrncmp(url, T("http://"), 7) == 0) { | 
 | 		tok = &url[7]; | 
 | 		tok[-3] = '\0'; | 
 | 		proto = url; | 
 | 		host = tok; | 
 | 		for (cp = tok; *cp; cp++) { | 
 | 			if (*cp == '/') { | 
 | 				break; | 
 | 			} | 
 | 			if (*cp == ':') { | 
 | 				*cp++ = '\0'; | 
 | 				port = cp; | 
 | 				tok = cp; | 
 | 			} | 
 | 		} | 
 | 		if ((cp = gstrchr(tok, '/')) != NULL) { | 
 |  | 
 | 			c = *cp; | 
 | 			*cp = '\0'; | 
 | 			gstrncpy(hostbuf, host, ulen); | 
 | 			gstrncpy(portbuf, port, MAX_PORT_LEN); | 
 | 			*cp = c; | 
 | 			host = hostbuf; | 
 | 			port = portbuf; | 
 | 			path = cp; | 
 | 			tok = cp; | 
 | 		} | 
 |  | 
 | 	} else { | 
 | 		path = url; | 
 | 		tok = url; | 
 | 	} | 
 |  | 
 | 	if ((cp = gstrchr(tok, '?')) != NULL) { | 
 | 		*cp++ = '\0'; | 
 | 		query = cp; | 
 | 		path = tok; | 
 | 		tok = query; | 
 | 	}  | 
 |  | 
 | 	if ((cp = gstrchr(tok, '#')) != NULL) { | 
 | 		*cp++ = '\0'; | 
 | 		if (*query == 0) { | 
 | 			path = tok; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	if (pext) { | 
 |  | 
 | 		if ((cp = gstrrchr(path, '.')) != NULL) { | 
 | 			const char_t* garbage = T("/\\"); | 
 | 			int length = gstrcspn(cp, garbage); | 
 | 			int garbageLength = gstrspn(cp + length, garbage); | 
 | 			int ok = (length + garbageLength == (int) gstrlen(cp)); | 
 |  | 
 | 			if (ok) { | 
 | 				cp[length] = '\0'; | 
 | 				ext = cp; | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	if (phost) | 
 | 		*phost = host; | 
 | 	if (ppath) | 
 | 		*ppath = path; | 
 | 	if (pport) | 
 | 		*pport = port; | 
 | 	if (pproto) | 
 | 		*pproto = proto; | 
 | 	if (pquery) | 
 | 		*pquery = query; | 
 | 	if (ptag) | 
 | 		*ptag = tag; | 
 | 	if (pext) | 
 | 		*pext = ext; | 
 | 	*pbuf = buf; | 
 | 	return 0; | 
 | } | 
 |  | 
 | char_t *websUrlType(char_t *url, char_t *buf, int charCnt) | 
 | { | 
 | 	char_t	*ext = NULL; //cov | 
 | 	char_t	*tmp_buf; | 
 | 	sym_t	*psym; | 
 |  | 
 | 	a_assert(url && *url); | 
 | 	a_assert(buf && charCnt > 0); | 
 |  | 
 | 	if (url == NULL || *url == '\0') { | 
 | 		gstrcpy(buf, T("text/plain")); | 
 | 		return buf; | 
 | 	} | 
 | 	if (websUrlParse(url, &tmp_buf, NULL, NULL, NULL, NULL, NULL,  | 
 | 			NULL, &ext) < 0) { | 
 | 		gstrcpy(buf, T("text/plain")); | 
 | 		return buf; | 
 | 	} | 
 | 	strlower(ext); | 
 |  | 
 | 	if ((psym = symLookup(websMime, ext)) != NULL) { | 
 | 		gstrncpy(buf, psym->content.value.string, charCnt); | 
 | 	} else { | 
 | 		gstrcpy(buf, T("text/plain")); | 
 | 	} | 
 | 	bfree(B_L, tmp_buf); | 
 | 	return buf; | 
 | } | 
 |  | 
 | static int websParseFirst(webs_t wp, char_t *text) | 
 | { | 
 | 	char_t 	*op, *proto, *protoVer, *url, *host, *query, *path, *port, *ext; | 
 | 	char_t	*buf; | 
 | 	int		testPort; | 
 |  | 
 | #ifdef FEATURE_ZTE_WEB_TCARD | 
 | //added by guo shoupeng 10124224 for http share 20111001 start | 
 | 	char *page_att=NULL; | 
 | //added by guo shoupeng 10124224 for http share 20111001 end | 
 | #endif | 
 | 	a_assert(websValid(wp)); | 
 | 	a_assert(text && *text); | 
 | #ifdef WEBINSPECT_FIX	 | 
 | 	if(text && (!is_print_str(text,strlen(text)) || strstr(text, "HTTP") == NULL)) | 
 | 	{ | 
 | 		websDone(wp, 0); | 
 | 		slog(MISC_PRINT, SLOG_ERR,"[goahead]es\n"); | 
 | 		return -1; | 
 | 	} | 
 | #endif | 
 | 	op = gstrtok(text, T(" \t")); | 
 | 	if (op == NULL || *op == '\0') { | 
 | 		websError(wp, 400, T("Bad HTTP request")); | 
 | 		return -1; | 
 | 	} | 
 | 	if (gstrcmp(op, T("GET")) != 0) { | 
 | 		if (gstrcmp(op, T("POST")) == 0) { | 
 | 			wp->flags |= WEBS_POST_REQUEST; | 
 | 		} else if (gstrcmp(op, T("HEAD")) == 0) { | 
 | 			wp->flags |= WEBS_HEAD_REQUEST; | 
 | 		} else { | 
 | 			websError(wp, 400, T("Bad request type")); | 
 | 			return -1; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	websSetVar(wp, T("REQUEST_METHOD"), op); | 
 |  | 
 | 	url = gstrtok(NULL, T(" \t\n")); | 
 | 	if (url == NULL || *url == '\0') { | 
 | 		websError(wp, 400, T("Bad HTTP request")); | 
 | 		return -1; | 
 | 	} | 
 | 	protoVer = gstrtok(NULL, T(" \t\n")); | 
 |  | 
 | 	host = path = port = proto = query = ext = NULL; | 
 | 	if (websUrlParse(url, &buf, &host, &path, &port, &query, &proto,  | 
 | 			NULL, &ext) < 0) { | 
 | 		websError(wp, 400, T("Bad URL format")); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	wp->url = bstrdup(B_L, url); | 
 |  | 
 | #ifndef __NO_CGI_BIN | 
 |  | 
 |  | 
 | 	if ((gstrstr(url, CGI_BIN) != NULL)&&((wp->flags & WEBS_POST_REQUEST))) { | 
 | 		wp->flags |= WEBS_CGI_REQUEST; | 
 | 		 | 
 | 		printf("[goahead]set WEBS_CGI_REQUEST \n"); | 
 |  | 
 | 		// special case: upload.cgi | 
 | 		 | 
 | 		if(gstrstr(url, CGI_BIN_UPLOAD) != NULL) | 
 | 		{ | 
 | 			if(gstrstr(url, CGI_FIRMWARE_UPLOAD) != NULL){ | 
 | 				wp->flags |= WEBS_CGI_FIRMWARE_UPLOAD; | 
 | 				system("rm -rf  /firmware_tmp_file"); | 
 | 				zte_mgmt_login_timemark_set(); | 
 | 				printf("[goahead]set WEBS_CGI_FIRMWARE_UPLOAD \n"); | 
 | 			} | 
 | 			wp->cgiStdin = websGetCgiCommName(wp); | 
 | 			printf("[goahead]get cgi name.\n"); | 
 | 			// ex: upload_setting.... | 
 | 			wp->flags |= WEBS_CGI_UPLOAD; | 
 | 		} | 
 |  | 
 | 		if(gstrstr(url, CGI_BIN_HTTPSHARE) != NULL) | 
 | 		{ | 
 | 			printf("[httpshare]upload file.\n");  | 
 |  | 
 | 			if(!zte_reset_cgi_state(wp))	 | 
 | 			{ | 
 | 				printf("[httpshare]upload file.reset cgi state error.\n"); | 
 | 				bfree(B_L, buf); | 
 | 				return -1; | 
 | 			} | 
 | 			wp->flags |= WEBS_CGI_HTTPSHARE_UPLOAD; | 
 | 		} | 
 | 	             | 
 |  | 
 | 	} | 
 | #endif | 
 |  | 
 | 	wp->query = bstrdup(B_L, query); | 
 | 	wp->host = bstrdup(B_L, host); | 
 | 	wp->path = bstrdup(B_L, path); | 
 | 	wp->protocol = bstrdup(B_L, proto); | 
 | 	wp->protoVersion = bstrdup(B_L, protoVer); | 
 | 	 | 
 | 	//added by liuyingnan for PC Client begin, 20120829 | 
 |     if (gstrstr(url, "api/client/post") != NULL) { | 
 |         printf("%s", "websParseFirst: pc client post"); | 
 |         wp->flags |= WEBS_REST_CLIENT_REQUEST; | 
 |     } | 
 |     //added by huangmin for PC Client end, 20120829 | 
 |     if (gstrstr(url, "api/xmlclient/post") != NULL) { | 
 |         wp->flags |= WEBS_XML_CLIENT_REQUEST; | 
 |     } | 
 | 	 | 
 | 	if ((testPort = socketGetPort(wp->listenSid)) >= 0) { | 
 | 		wp->port = testPort; | 
 | 	} else { | 
 | 		wp->port = gatoi(port); | 
 | 	} | 
 |  | 
 | 	if (gstrcmp(ext, T(".asp")) == 0) { | 
 | 		wp->flags |= WEBS_ASP; | 
 | 	} | 
 | 	bfree(B_L, buf); | 
 |  | 
 | 	websUrlType(url, wp->type, TSZ(wp->type)); | 
 |  | 
 | 	ringqFlush(&wp->header); | 
 | 	return 0; | 
 | } | 
 |  | 
 | 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)); | 
 | 	a_assert(ptext); | 
 | 	a_assert(pnbytes); | 
 |  | 
 | 	if(websValid(wp) == 0 || ptext == NULL || pnbytes == NULL){ | 
 | 		softap_assert("websGetInput 1"); | 
 | 		return -1;//for kw | 
 | 	} | 
 |  | 
 | 	*ptext = text = NULL; | 
 | 	*pnbytes = 0; | 
 |  | 
 | 	if (wp->state == WEBS_POST_CLEN) { | 
 | 		len = (wp->clen > WEBS_SOCKET_BUFSIZ) ? WEBS_SOCKET_BUFSIZ : wp->clen; | 
 | 	} else { | 
 | 		len = 0; | 
 | 	} | 
 |  | 
 | 	if (len > 0) { | 
 |  | 
 | #ifdef WEBS_SSL_SUPPORT | 
 | 		if (wp->flags & WEBS_SECURE) { | 
 | 			nbytes = websSSLRead(wp->wsp, buf, len); | 
 | 		} else { | 
 | 			nbytes = socketRead(wp->sid, buf, len); | 
 | 		} | 
 | #else | 
 | 		nbytes = socketRead(wp->sid, buf, len); | 
 | #endif | 
 | 		if (nbytes < 0) {						/* Error */ | 
 | 			websDone(wp, 0); | 
 | 			return -1; | 
 |  | 
 | 		}  else if (nbytes == 0) {				/* EOF or No data available */ | 
 | 			//trace(8, T("@@@@webs 0x%x 0x%x: websGetInput read 0\n"),wp,wp->sid); | 
 | 			if (socketEof(wp->sid)) { | 
 | 				websDone(wp, 0); | 
 | 			} | 
 | 			return -1; | 
 |  | 
 | 		} else {								/* Valid data */ | 
 |  | 
 | 			buf[nbytes] = '\0'; | 
 | 			if ((text = ballocAscToUni(buf, nbytes)) == NULL) { | 
 | 				websError(wp, 503, T("Insufficient memory")); | 
 | 				return -1; | 
 | 			} | 
 | 		} | 
 |  | 
 | 	} else { | 
 | #ifdef WEBS_SSL_SUPPORT | 
 | 		if (wp->flags & WEBS_SECURE) { | 
 | 			nbytes = websSSLGets(wp->wsp, &text); | 
 | 		} else { | 
 | 			nbytes = socketGets(wp->sid, &text); | 
 | 		} | 
 | #else | 
 | 		nbytes = socketGets(wp->sid, &text); | 
 | #endif | 
 |  | 
 | 		if (nbytes < 0) { | 
 | 			int eof; | 
 |  | 
 | #ifdef WEBS_SSL_SUPPORT | 
 | 			if (wp->flags & WEBS_SECURE) { | 
 |  | 
 | 				if (wp->state == WEBS_BEGIN) { | 
 | 					eof = 1; | 
 | 				} else { | 
 | 					eof = websSSLEof(wp->wsp); | 
 | 				} | 
 | 			} else { | 
 | 				eof = socketEof(wp->sid); | 
 | 			} | 
 | #else | 
 | 			eof = socketEof(wp->sid); | 
 | #endif | 
 |  | 
 | 			if (eof) { | 
 |  | 
 | 				if (wp->state == WEBS_POST) { | 
 | 					websUrlHandlerRequest(wp); | 
 | 				} else { | 
 | 					websDone(wp, 0); | 
 | 				} | 
 | 			} else { | 
 | 					trace(8, T("@@@@webs 0x%x 0x%x: websGetInput no eof\n"),wp,wp->sid); | 
 |  | 
 | #if 1//def HP_FIX | 
 | 				websDone(wp, 0); | 
 | #endif /*HP_FIX*/ | 
 |  | 
 | 			} | 
 |  | 
 | #if 0 //def UNUSED | 
 | 			if (wp->state == WEBS_HEADER && ringqLen(&wp->header) <= 0) { | 
 | 				websParseRequest(wp); | 
 | 				websUrlHandlerRequest(wp); | 
 | 			} | 
 | #endif | 
 | 			bfreeSafe(B_L,text);//for kw | 
 | 			return -1; | 
 |  | 
 | 		} else if (nbytes == 0) { | 
 | 			if (wp->state == WEBS_HEADER) { | 
 |  | 
 | 				if(websParseRequest(wp) != 0){ | 
 | 					return -1; | 
 | 				} | 
 | 				if (wp->flags & WEBS_POST_REQUEST) { | 
 | 					if (wp->flags & WEBS_CLEN) { | 
 | 						wp->state = WEBS_POST_CLEN; | 
 | 						clen = wp->clen; | 
 | 					} else { | 
 | 						wp->state = WEBS_POST; | 
 | 						clen = 1; | 
 | 					} | 
 | 					if (clen > 0) { | 
 |  | 
 | 						return 0; | 
 | 					} | 
 | 					return 1; | 
 | 				} | 
 |  | 
 | 				websUrlHandlerRequest(wp); | 
 | 			} | 
 | 			return -1; | 
 | 		} | 
 | 	} | 
 |  | 
 | //	if(text == NULL || nbytes <= 0){ // kw 3 nbytes <= 0 already return | 
 |     if(text == NULL){ | 
 | 		softap_assert("websGetInput 2"); | 
 | 	} | 
 | 	a_assert(text); | 
 | 	a_assert(nbytes > 0); | 
 | 	*ptext = text; | 
 | 	*pnbytes = nbytes; | 
 | 	return 1; | 
 | } | 
 |  | 
 |  | 
 | #define isgoodchar(s) (gisalnum((s)) || ((s) == '/') || ((s) == '_') || \ | 
 | 						((s) == '.')  || ((s) == '-') ) | 
 |  | 
 | static int websParseRequest(webs_t wp) | 
 | { | 
 | 	char_t	*authType, *upperKey, *cp, *browser, *lp, *key, *value; | 
 | 	int smugglingFlag = 0; | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	websSetVar(wp, T("HTTP_AUTHORIZATION"), T("")); | 
 |  | 
 | 	browser = NULL; | 
 | 	char tmp[4] = T(""); | 
 | 	for (lp = (char_t*) wp->header.servp; lp && *lp; ) { | 
 | 		cp = lp; | 
 | 		if ((lp = gstrchr(lp, '\n')) != NULL) { | 
 | 			lp++; | 
 | 		} | 
 |  | 
 | 		if ((key = gstrtok(cp, T(": \t\n"))) == NULL) { | 
 | 			continue; | 
 | 		} | 
 |  | 
 | 		if ((value = gstrtok(NULL, T("\n"))) == NULL) { | 
 | 			//value = T(""); | 
 | 			value = tmp;// kw OVERWRITE_CONST_CHAR | 
 | 		} | 
 |  | 
 | 		while (gisspace(*value)) { | 
 | 			value++; | 
 | 		} | 
 | 		strlower(key); | 
 |  | 
 | 		fmtAlloc(&upperKey, (gstrlen(key) + 6), T("HTTP_%s"), key); | 
 | 		for (cp = upperKey; *cp; cp++) { | 
 | 			if (*cp == '-') | 
 | 				*cp = '_'; | 
 | 		} | 
 | 		strupper(upperKey); | 
 | 		websSetVar(wp, upperKey, value); | 
 | 		bfree(B_L, upperKey); | 
 |  | 
 | 		if (gstrcmp(key, T("user-agent")) == 0) { | 
 | 			if (wp->userAgent) | 
 | 				bfree(B_L, wp->userAgent); | 
 | 			wp->userAgent = bstrdup(B_L, value); | 
 |  | 
 | 		} else if (gstricmp(key, T("authorization")) == 0) { | 
 |  | 
 | 			authType = bstrdup (B_L, value); | 
 | 			a_assert (authType); | 
 |  | 
 | 			cp = authType; | 
 | 			while (gisalpha(*cp)) { | 
 | 				cp++; | 
 | 			} | 
 | 			*cp = '\0'; | 
 | 			if (wp->authType) | 
 | 				bfree(B_L, wp->authType); | 
 | 			wp->authType = bstrdup(B_L, authType); | 
 | 			bfree(B_L, authType); | 
 |  | 
 | 			if (gstricmp(wp->authType, T("basic")) == 0) { | 
 | 				char_t	userAuth[FNAMESIZE]; | 
 |  | 
 | 				if ((cp = gstrchr(value, ' ')) != NULL) { | 
 | 					*cp = '\0'; | 
 |  | 
 |                bfree(B_L, wp->authType); | 
 | 					wp->authType = bstrdup(B_L, value); | 
 | 					websDecode64(userAuth, ++cp, sizeof(userAuth)); | 
 | 				} else { | 
 | 					websDecode64(userAuth, value, sizeof(userAuth)); | 
 | 				} | 
 |  | 
 | 				if ((cp = gstrchr(userAuth, ':')) != NULL) { | 
 | 					*cp++ = '\0'; | 
 | 				} | 
 | 				if (wp->password) | 
 | 					bfree(B_L, wp->password); | 
 | 				if (wp->userName) | 
 | 					bfree(B_L, wp->userName); | 
 | 				if (cp) { | 
 | 					wp->userName = bstrdup(B_L, userAuth); | 
 | 					wp->password = bstrdup(B_L, cp); | 
 | 				} else { | 
 | 					wp->userName = bstrdup(B_L, T("")); | 
 | 					wp->password = bstrdup(B_L, T("")); | 
 | 				} | 
 |  | 
 | 				wp->flags |= WEBS_AUTH_BASIC; | 
 | 			} else { | 
 | #ifdef DIGEST_ACCESS_SUPPORT | 
 |  | 
 | 				char_t *np;		 | 
 | 				char_t tp;		 | 
 | 				char_t *vp;		 | 
 | 				char_t *npv;	 | 
 | 				char_t tpv;		 | 
 |  | 
 | 				wp->flags |= WEBS_AUTH_DIGEST; | 
 |  | 
 |  				cp = value; | 
 | 				while (isgoodchar(*cp)) { | 
 | 					cp++; | 
 | 				} | 
 | 				while (!isgoodchar(*cp)) { | 
 | 					cp++; | 
 | 				} | 
 |  | 
 |  | 
 | 				vp = gstrchr(cp, '='); | 
 | 				while (vp) { | 
 |  | 
 | 					np = cp; | 
 | 					while (isgoodchar(*np)) { | 
 | 						np++; | 
 | 					} | 
 | 					tp = *np; | 
 | 					*np = 0; | 
 |  | 
 | 					vp++; | 
 | 					while (!isgoodchar(*vp)) { | 
 | 						vp++; | 
 | 					} | 
 |  | 
 | 					npv = vp; | 
 | 					while (isgoodchar(*npv)) { | 
 | 						npv++; | 
 | 					} | 
 | 					tpv = *npv; | 
 | 					*npv = 0; | 
 |  | 
 | 					if (gstricmp(cp, T("username")) == 0) { | 
 | 						wp->userName = bstrdup(B_L, vp); | 
 | 					} else if (gstricmp(cp, T("response")) == 0) { | 
 | 						wp->digest = bstrdup(B_L, vp); | 
 | 					} else if (gstricmp(cp, T("opaque")) == 0) { | 
 | 						wp->opaque = bstrdup(B_L, vp); | 
 | 					} else if (gstricmp(cp, T("uri")) == 0) { | 
 | 						wp->uri = bstrdup(B_L, vp); | 
 | 					} else if (gstricmp(cp, T("realm")) == 0) { | 
 | 						wp->realm = bstrdup(B_L, vp); | 
 | 					} else if (gstricmp(cp, T("nonce")) == 0) { | 
 | 						wp->nonce = bstrdup(B_L, vp); | 
 | 					} else if (gstricmp(cp, T("nc")) == 0) { | 
 | 						wp->nc = bstrdup(B_L, vp); | 
 | 					} else if (gstricmp(cp, T("cnonce")) == 0) { | 
 | 						wp->cnonce = bstrdup(B_L, vp); | 
 | 					} else if (gstricmp(cp, T("qop")) == 0) { | 
 | 						wp->qop = bstrdup(B_L, vp); | 
 | 					} | 
 |  | 
 | 					*np = tp; | 
 | 					*npv = tpv; | 
 |  | 
 |  					cp = npv; | 
 | 					while (*cp && isgoodchar(*cp)) { | 
 | 						cp++; | 
 | 					} | 
 | 					while (*cp && !isgoodchar(*cp)) { | 
 | 						cp++; | 
 | 					} | 
 |  | 
 | 					if (*cp) { | 
 | 						vp = gstrchr(cp, '='); | 
 | 					} else { | 
 | 						vp = NULL; | 
 | 					} | 
 | 				} | 
 | #endif /* DIGEST_ACCESS_SUPPORT */ | 
 | 			} /* if (gstrcmp(wp->authType)) */ | 
 | #ifdef WEBS_SECURITY | 
 | 		} else if (gstrcmp(key, T("x-http-method")) == 0) { | 
 | 			printf("websParseRequest: key=%s\n",key); | 
 | 			websError(wp, 405, T("")); | 
 | 			return -1; | 
 | 		} else if (gstrcmp(key, T("x-http-method-override")) == 0) { | 
 | 			printf("websParseRequest: key=%s\n",key); | 
 | 			websError(wp, 405, T("")); | 
 | 			return -1; | 
 | 		} else if (gstrcmp(key, T("x-method-override")) == 0) { | 
 | 			printf("websParseRequest: key=%s\n",key); | 
 | 			websError(wp, 405, T("")); | 
 | 			return -1; | 
 | 		} else if (gstrcmp(key, T("transfer-encoding")) == 0) { | 
 | 			printf("websParseRequest: key=%s\n",key); | 
 | 			if(smugglingFlag) { | 
 | 				websError(wp, 403, T("")); | 
 | 				return -1; | 
 | 			} | 
 | 			smugglingFlag = 1; | 
 | #endif | 
 |  | 
 | 		} else if (gstrcmp(key, T("content-length")) == 0) { | 
 |  | 
 | #ifdef WEBS_SECURITY | 
 | 		 if(smugglingFlag) { | 
 | 			 websError(wp, 403, T("")); | 
 | 			 return -1; | 
 | 		 } | 
 | 		 smugglingFlag = 1; | 
 | #endif		  | 
 |          wp->clen = gatoi(value); | 
 |          if (wp->clen > 0) | 
 |          { | 
 | 			   wp->flags |= WEBS_CLEN;			 | 
 | 			   websSetVar(wp, T("CONTENT_LENGTH"), value); | 
 |          } | 
 |          else | 
 |          { | 
 |             wp->clen = 0; | 
 |          } | 
 |  | 
 | 		} else if (gstrcmp(key, T("content-type")) == 0) { | 
 | 			websSetVar(wp, T("CONTENT_TYPE"), value); | 
 |  | 
 | #ifdef WEBS_KEEP_ALIVE_SUPPORT | 
 | 		} else if (gstrcmp(key, T("connection")) == 0) { | 
 | 			strlower(value); | 
 | 			if (gstrcmp(value, T("keep-alive")) == 0) { | 
 | 				wp->flags |= WEBS_KEEP_ALIVE; | 
 | 			} | 
 | #endif | 
 |  | 
 | #ifdef WEBS_PROXY_SUPPORT | 
 |  | 
 | 		} else if (gstrcmp(key, T("pragma")) == 0) { | 
 | 			char_t	tmp[256]; | 
 | 			gstrncpy(tmp, value, TSZ(tmp)); | 
 | 			strlower(tmp); | 
 | 			if (gstrstr(tmp, T("no-cache"))) { | 
 | 				wp->flags |= WEBS_DONT_USE_CACHE; | 
 | 			} | 
 | #endif /* WEBS_PROXY_SUPPORT */ | 
 |  | 
 |  | 
 | 		} else if (gstrcmp(key, T("cookie")) == 0) { | 
 | 			wp->flags |= WEBS_COOKIE; | 
 | 			if (wp->cookie) | 
 | 				bfree(B_L, wp->cookie); | 
 | 			wp->cookie = bstrdup(B_L, value); | 
 | 		} else if (gstrcmp(key, T("referer")) == 0) { | 
 | 			if (wp->referer) | 
 | 				bfree(B_L, wp->referer); | 
 | 			wp->referer = bstrdup(B_L, value); | 
 |  | 
 | 		} | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 |  | 
 | int websTestVar(webs_t wp, char_t *var) | 
 | { | 
 | 	sym_t		*sp; | 
 |  | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	if (var == NULL || *var == '\0') { | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	if ((sp = symLookup(wp->cgiVars, var)) == NULL) { | 
 | 		return 0; | 
 | 	} | 
 | 	return 1; | 
 | } | 
 |  | 
 | void websSetVar(webs_t wp, char_t *var, char_t *value) | 
 | { | 
 | 	value_t		 v; | 
 |  | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	if (value) { | 
 | 		v = valueString(value, VALUE_ALLOCATE); | 
 | 	} else { | 
 | 		v = valueString(T(""), VALUE_ALLOCATE); | 
 | 	} | 
 | 	symEnter(wp->cgiVars, var, v, 0); | 
 | } | 
 |  | 
 |  | 
 | void websSetEnv(webs_t wp) | 
 | { | 
 | 	char_t	portBuf[8]; | 
 | 	char_t	*keyword, *value, *valCheck, *valNew; | 
 |  | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	websSetVar(wp, T("QUERY_STRING"), wp->query); | 
 | 	websSetVar(wp, T("GATEWAY_INTERFACE"), T("CGI/1.1")); | 
 | 	websSetVar(wp, T("SERVER_HOST"), websHost); | 
 | 	websSetVar(wp, T("SERVER_NAME"), websHost); | 
 | 	websSetVar(wp, T("SERVER_URL"), websHostUrl); | 
 | 	websSetVar(wp, T("REMOTE_HOST"), wp->ipaddr); | 
 | 	websSetVar(wp, T("REMOTE_ADDR"), wp->ipaddr); | 
 | 	websSetVar(wp, T("PATH_INFO"), wp->path); | 
 | 	stritoa(websPort, portBuf, sizeof(portBuf)); | 
 | 	websSetVar(wp, T("SERVER_PORT"), portBuf); | 
 | 	websSetVar(wp, T("SERVER_ADDR"), websIpaddr); | 
 | 	fmtAlloc(&value, FNAMESIZE, T("%s/%s"), WEBS_NAME, WEBS_VERSION); | 
 | 	websSetVar(wp, T("SERVER_SOFTWARE"), value); | 
 | 	bfreeSafe(B_L, value); | 
 | 	websSetVar(wp, T("SERVER_PROTOCOL"), wp->protoVersion); | 
 |  | 
 | 	wp->decodedQuery = bstrdup(B_L, wp->query); | 
 | 	keyword = gstrtok(wp->decodedQuery, T("&")); | 
 | 	char tmp[4] = T(""); | 
 | 	while (keyword != NULL) { | 
 | 		if ((value = gstrchr(keyword, '=')) != NULL) { | 
 | 			*value++ = '\0'; | 
 | 			websDecodeUrl(keyword, keyword, gstrlen(keyword)); | 
 | 			websDecodeUrl(value, value, gstrlen(value)); | 
 | 		} else { | 
 | 			//value = T(""); | 
 | 			value = tmp;// kw OVERWRITE_CONST_CHAR | 
 | 		} | 
 |  | 
 | 		if (*keyword) { | 
 |  | 
 | 			if ((valCheck = websGetVar(wp, keyword, NULL)) != 0) { | 
 | 				fmtAlloc(&valNew, 256, T("%s %s"), valCheck, value); | 
 | 				websSetVar(wp, keyword, valNew); | 
 | 				bfreeSafe(B_L, valNew); | 
 | 			} else { | 
 | 				websSetVar(wp, keyword, value); | 
 | 			} | 
 | 		} | 
 | 		keyword = gstrtok(NULL, T("&")); | 
 | 	} | 
 |  | 
 | #ifdef EMF | 
 |  | 
 | 	websSetEmfEnvironment(wp); | 
 | #endif | 
 | } | 
 |  | 
 |  | 
 | int websCompareVar(webs_t wp, char_t *var, char_t *value) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 | 	a_assert(var && *var); | 
 |   | 
 | 	if (gstrcmp(value, websGetVar(wp, var, T(" __UNDEF__ "))) == 0) { | 
 | 		return 1; | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 | char_t *websGetVar(webs_t wp, char_t *var, char_t *defaultGetValue) | 
 | { | 
 | 	sym_t	*sp; | 
 |  | 
 | 	a_assert(websValid(wp)); | 
 | 	a_assert(var && *var); | 
 |   | 
 | 	if ((sp = symLookup(wp->cgiVars, var)) != NULL) { | 
 | 		a_assert(sp->content.type == string); | 
 | 		if (sp->content.value.string) { | 
 | 			return sp->content.value.string; | 
 | 		} else { | 
 | 			return T(""); | 
 | 		} | 
 | 	} | 
 | 	return defaultGetValue; | 
 | } | 
 |  | 
 |  | 
 | void websResponse(webs_t wp, int code, char_t *message, char_t *redirect) | 
 | { | 
 | 	char_t		*date; | 
 |  | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	wp->flags &= ~WEBS_KEEP_ALIVE; | 
 |  | 
 | 	if ( !(wp->flags & WEBS_HEADER_DONE)) { | 
 | 		wp->flags |= WEBS_HEADER_DONE; | 
 |  | 
 | 		if (redirect != NULL) { | 
 | 			websWrite(wp, T("HTTP/1.0 %d %s\r\n"), code, websErrorMsg(code)); | 
 | 		} else { | 
 | 			websWrite(wp, T("HTTP/1.1 %d %s\r\n"), code, websErrorMsg(code)); | 
 | 		} | 
 |  | 
 |  | 
 | 		websWrite(wp, T("Server: %s\r\n"), WEBS_NAME); | 
 |  | 
 | 		if ((date = websGetDateString(NULL)) != NULL) { | 
 | 			websWrite(wp, T("Date: %s\r\n"), date); | 
 | 			bfree(B_L, date); | 
 | 		} | 
 |  | 
 | 		if (code == 401) { | 
 | 			if (!(wp->flags & WEBS_AUTH_DIGEST)) { | 
 | 				websWrite(wp, T("WWW-Authenticate: Basic realm=\"%s\"\r\n"),  | 
 | 					websGetRealm()); | 
 | #ifdef DIGEST_ACCESS_SUPPORT | 
 | 			} else { | 
 | 				char_t *nonce, *opaque; | 
 |  | 
 |             /* $$$ before... (note commas instead of semicolons...) | 
 | 				nonce = websCalcNonce(wp),  | 
 | 				opaque = websCalcOpaque(wp),  | 
 |             $$$ after */ | 
 | 				nonce = websCalcNonce(wp); | 
 | 				opaque = websCalcOpaque(wp);  | 
 |             /* ...$$$ end */ | 
 | 				websWrite(wp,  | 
 | 					T("WWW-Authenticate: Digest realm=\"%s\", domain=\"%s\",") | 
 | 					T("qop=\"%s\", nonce=\"%s\", opaque=\"%s\",") | 
 | 					T("algorithm=\"%s\", stale=\"%s\"\r\n"),  | 
 | 					websGetRealm(), | 
 | 					websGetHostUrl(), | 
 | 					T("auth"), | 
 | 					nonce, | 
 | 					opaque, T("MD5"), T("FALSE")); | 
 | 				bfree(B_L, nonce); | 
 | 				bfree(B_L, opaque); | 
 | #endif | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if (wp->flags & WEBS_KEEP_ALIVE) { | 
 | 			websWrite(wp, T("Connection: keep-alive\r\n")); | 
 | 		} | 
 | #ifdef WEBINSPECT_FIX | 
 | 		websWrite(wp, T("X-Frame-Options: SAMEORIGIN\r\n")); | 
 | #endif | 
 | 		websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n")); | 
 | 		websWrite(wp, T("Content-Type: text/html\r\n")); | 
 |  | 
 | 		if (redirect) { | 
 | 			websWrite(wp, T("Location: %s\r\n"), redirect); | 
 | 		} | 
 | 		websWrite(wp, T("\r\n")); | 
 | 	} | 
 |  | 
 |  | 
 | 	if ((wp->flags & WEBS_HEAD_REQUEST) == 0 && message && *message) { | 
 | 		websWrite(wp, T("%s\r\n"), message); | 
 | 	} | 
 | 	websDone(wp, code); | 
 | } | 
 |  | 
 | void websTimeoutCancel(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	if (wp->timeout >= 0) { | 
 | 		emfUnschedCallback(wp->timeout); | 
 | 		wp->timeout = -1; | 
 | 	} | 
 | } | 
 |  | 
 | void websRedirect(webs_t wp, char_t *url) | 
 | { | 
 | 	char_t	*msgbuf, *urlbuf, *redirectFmt; | 
 |  | 
 | 	a_assert(websValid(wp)); | 
 | 	a_assert(url); | 
 |  | 
 | 	websStats.redirects++; | 
 | 	msgbuf = urlbuf = NULL; | 
 | 	 | 
 | 	if (gstrstr(url, T("%0D")) || gstrstr(url, T("%0A"))  | 
 | 		|| gstrstr(url, T("%0d")) || gstrstr(url, T("%0a")) | 
 | 		|| gstrstr(url, T("\r")) || gstrstr(url, T("\n"))) { | 
 | 		printf("[goahead]Redirect injo %s\n",url); | 
 | 		url = T(ZTE_WEB_PAGE_LOGIN_NAME); | 
 | 		/*ÓÃÓÚÖØ¶¨ÏòµÄÊäÈë²ÎÊý²»Äܰüº¬»Ø³µºÍ»»ÐÐ×Ö·û£¬ÒÔ·ÀÖ¹HTTPÏìÓ¦²ð·Ö¹¥»÷*/ | 
 | 	} | 
 |  | 
 |  | 
 | 	if (gstrstr(url, T("http://")) == NULL && gstrstr(url, T("https://")) == NULL) { | 
 | 		if (*url == '/') { | 
 | 			url++; | 
 | 		} | 
 |  | 
 | 		//redirectFmt = T("http://%s/%s"); | 
 |  | 
 | #ifdef WEBS_SSL_SUPPORT | 
 | 		//if (wp->flags & WEBS_SECURE) {			 | 
 | 		if (websSSLIsOpen()) { | 
 | 			//redirectFmt = T("https://%s/%s");// kw OVERWRITE_CONST_CHAR | 
 | 			fmtAlloc(&urlbuf, WEBS_MAX_URL + 80, "https://%s/%s", | 
 | 				websGetVar(wp, T("HTTP_HOST"),	websHostUrl), url); | 
 | 		} | 
 | 		else | 
 | #endif | 
 | 		{ | 
 | 			fmtAlloc(&urlbuf, WEBS_MAX_URL + 80, "http://%s/%s", | 
 | 				websGetVar(wp, T("HTTP_HOST"), 	websHostUrl), url); | 
 | 		} | 
 | 		url = urlbuf; | 
 | 		printf("[goahead]Redirect %s\n",url); | 
 | 	} | 
 |  | 
 |  | 
 | 	fmtAlloc(&msgbuf, WEBS_MAX_URL + 80,  | 
 | 		T("<html><head></head><body>\r\n\ | 
 | 		This document has moved to a new <a href=\"%s\">location</a>.\r\n\ | 
 | 		Please update your documents to reflect the new location.\r\n\ | 
 | 		</body></html>\r\n"), url); | 
 |  | 
 | 	websResponse(wp, 302, msgbuf, url); | 
 |  | 
 | 	bfreeSafe(B_L, msgbuf); | 
 | 	bfreeSafe(B_L, urlbuf); | 
 | } | 
 |  | 
 | static int charCount(const char_t* str, char_t ch); | 
 |  | 
 | #define kLt '<' | 
 | #define kLessThan T("<") | 
 | #define kGt '>' | 
 | #define kGreaterThan T(">") | 
 |  | 
 | static char_t* websSafeUrl(const char_t* url) | 
 | { | 
 |  | 
 |    int ltCount = charCount(url, kLt); | 
 |    int gtCount = charCount(url, kGt); | 
 |    int safeLen = 0; | 
 |    char_t* safeUrl = NULL; | 
 |    char_t* src = NULL; | 
 |    char_t* dest = NULL; | 
 |  | 
 |    if (NULL != url) | 
 |    { | 
 |       safeLen = gstrlen(url); | 
 |       if (ltCount == 0 && gtCount == 0) | 
 |       { | 
 |          safeUrl = bstrdup(B_L, (char_t*) url); | 
 |       } | 
 |       else | 
 |       { | 
 |          safeLen += (ltCount * 4); | 
 |          safeLen += (gtCount * 4); | 
 |  | 
 |          safeUrl = balloc(B_L, safeLen); | 
 |          if (safeUrl != NULL) | 
 |          { | 
 |             src = (char_t*) url; | 
 |             dest = safeUrl; | 
 |             while (*src) | 
 |             { | 
 |                if (*src == kLt) | 
 |                { | 
 |                   gstrcpy(dest, kLessThan); | 
 |                   dest += gstrlen(kLessThan); | 
 |                } | 
 |                else if (*src == kGt) | 
 |                { | 
 |                   gstrcpy(dest, kGreaterThan); | 
 |                   dest += gstrlen(kGreaterThan); | 
 |                } | 
 |                else | 
 |                { | 
 |                   *dest++ = *src; | 
 |                } | 
 |                ++src; | 
 |             } | 
 |             /* don't forget to terminate the string...*/ | 
 |             *dest = '\0'; | 
 |          } | 
 |       } | 
 |    } | 
 |    return safeUrl; | 
 | } | 
 |  | 
 | static int charCount(const char_t* str, char_t ch) | 
 | { | 
 |    int count = 0; | 
 |    char_t* p = (char_t*) str; | 
 |     | 
 |    if (NULL == str) | 
 |    { | 
 |       return 0; | 
 |    } | 
 |  | 
 |    while (1) | 
 |    { | 
 |       p = gstrchr(p, ch); | 
 |       if (NULL == p) | 
 |       { | 
 |          break; | 
 |       } | 
 |  | 
 |       ++count; | 
 |       ++p; | 
 |    } | 
 |    return count; | 
 | } | 
 |  | 
 |  | 
 | char_t *websErrorMsg(int code) | 
 | { | 
 | 	websErrorType	*ep; | 
 |  | 
 | 	for (ep = websErrors; ep->code; ep++) { | 
 | 		if (code == ep->code) { | 
 | 			return ep->msg; | 
 | 		} | 
 | 	} | 
 | 	a_assert(0); | 
 | 	return T(""); | 
 | } | 
 |  | 
 |  | 
 | #ifdef qRichErrorPage | 
 | extern int dmfRichError(webs_t wp, int code, char_t* userMsg); | 
 | #endif | 
 | void websError(webs_t wp, int code, char_t *fmt, ...) | 
 | { | 
 | 	va_list		args = {0}; | 
 | 	char_t		*msg, *userMsg, *buf; | 
 |    char_t*     safeUrl = NULL; | 
 |    char_t*     safeMsg = NULL; | 
 | #ifdef qRichErrorPage | 
 |    static int reEntry = 0; | 
 |    int errorOk; | 
 | #endif | 
 |  | 
 | 	a_assert(websValid(wp)); | 
 | 	a_assert(fmt); | 
 |  | 
 | 	websStats.errors++; | 
 |  | 
 |    safeUrl = websSafeUrl(wp->url); | 
 |    bfreeSafe(B_L, wp->url); | 
 |    wp->url = safeUrl; | 
 |  | 
 | 	va_start(args, fmt); | 
 | 	userMsg = NULL; | 
 | 	fmtValloc(&userMsg, WEBS_BUFSIZE, fmt, args); | 
 | 	va_end(args); | 
 |    safeMsg = websSafeUrl(userMsg); | 
 |    bfreeSafe(B_L, userMsg); | 
 |    userMsg = safeMsg; | 
 |    safeMsg  = NULL; | 
 |  | 
 |  | 
 |  | 
 | #ifdef qRichErrorPage | 
 |    if (!reEntry) | 
 |    { | 
 |  | 
 |       reEntry = 1; | 
 |       errorOk = dmfRichError(wp, code, userMsg); | 
 |       reEntry = 0; | 
 |       if (errorOk) | 
 |       { | 
 |          bfreeSafe(B_L, userMsg); | 
 |          return; | 
 |       } | 
 |        | 
 |    } | 
 |     | 
 | #endif | 
 |  | 
 | /*	msg = T("<html><head><title>Document Error: %s</title></head>\r\n\ | 
 | 		<body><h2>Access Error: %s</h2>\r\n\ | 
 | 		<p>%s</p></body></html>\r\n");*/ | 
 | // kw OVERWRITE_CONST_CHAR | 
 |  | 
 | 	buf = NULL; | 
 | 	fmtAlloc(&buf, WEBS_BUFSIZE, "<html><head><title>Document Error: %s</title></head>\r\n\ | 
 | 		<body><h2>Access Error: %s</h2>\r\n\ | 
 | 		<p>%s</p></body></html>\r\n", websErrorMsg(code),  | 
 | 		websErrorMsg(code), userMsg); | 
 |  | 
 | 	websResponse(wp, code, buf, NULL); | 
 | 	bfreeSafe(B_L, buf); | 
 | 	bfreeSafe(B_L, userMsg); | 
 | } | 
 |  | 
 |  | 
 | int websWriteBlock(webs_t wp, char_t *buf, int nChars) | 
 | { | 
 | 	int		len, done; | 
 | 	char	*asciiBuf, *pBuf; | 
 |  | 
 | 	a_assert(wp); | 
 | 	a_assert(websValid(wp)); | 
 | 	a_assert(buf); | 
 | 	a_assert(nChars >= 0); | 
 | 	if(wp == NULL) | 
 | 		return -1;//for kw | 
 |  | 
 | 	done = len = 0; | 
 |  | 
 | 	pBuf = asciiBuf = ballocUniToAsc(buf, nChars); | 
 | 	if(asciiBuf == NULL) | 
 | 		return -1;//for kw | 
 |  | 
 | 	while (nChars > 0) {   | 
 | #ifdef WEBS_SSL_SUPPORT | 
 | 		if (wp->flags & WEBS_SECURE) { | 
 | 			if ((len = websSSLWrite(wp->wsp, pBuf, nChars)) < 0) { | 
 | 				bfree(B_L, asciiBuf); | 
 | 				return -1; | 
 | 			} | 
 | 			websSSLFlush(wp->wsp); | 
 | 		} else { | 
 | 			if ((len = socketWrite(wp->sid, pBuf, nChars)) < 0) { | 
 | 				bfree(B_L, asciiBuf); | 
 | 				return -1; | 
 | 			} | 
 | 			socketFlush(wp->sid); | 
 | 		} | 
 | #else /* ! WEBS_SSL_SUPPORT */ | 
 | 		if ((len = socketWrite(wp->sid, pBuf, nChars)) < 0) { | 
 | 			bfree(B_L, asciiBuf); | 
 | 			return -1; | 
 | 		} | 
 | 		socketFlush(wp->sid); | 
 | #endif /* WEBS_SSL_SUPPORT */ | 
 | 		nChars -= len; | 
 | 		pBuf += len; | 
 | 		done += len; | 
 | 	} | 
 |  | 
 | 	bfree(B_L, asciiBuf); | 
 | 	return done; | 
 | } | 
 |  | 
 | int websWrite(webs_t wp, char_t *fmt, ...) | 
 | { | 
 | 	va_list		 vargs = {0}; | 
 | 	char_t		*buf; | 
 | 	int			 rc; | 
 | 	 | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	va_start(vargs, fmt); | 
 |  | 
 | 	buf = NULL; | 
 | 	rc = 0; | 
 |  | 
 | 	if (fmtValloc(&buf, WEBS_BUFSIZE, fmt, vargs) >= WEBS_BUFSIZE) { | 
 | 		trace(0, T("webs: websWrite lost data, buffer overflow\n")); | 
 | 	} | 
 |     | 
 | 	va_end(vargs); | 
 | 	a_assert(buf); | 
 | 	if (buf) { | 
 | 		rc = websWriteBlock(wp, buf, gstrlen(buf)); | 
 | 		bfree(B_L, buf); | 
 | 	} | 
 | 	return rc; | 
 | } | 
 |  | 
 |  | 
 | 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])) { | 
 |  | 
 | 			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'; | 
 | } | 
 |  | 
 | 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; | 
 | } | 
 |  | 
 |  | 
 | void websTimeout(void *arg, int id) | 
 | { | 
 | 	webs_t		wp; | 
 | 	int			delay, tm; | 
 |  | 
 | 	wp = (webs_t) arg; | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	tm = websGetTimeSinceMark(wp) * 1000; | 
 | 	trace(8, T("@@websTimeout %d ip:%s url:%s\n"),tm,wp->ipaddr,wp->url); | 
 | 	if (tm >= WEBS_TIMEOUT) { | 
 | 		websStats.timeouts++; | 
 | 		emfUnschedCallback(id); | 
 |  | 
 | 		wp->timeout = -1; | 
 | 		websDone(wp, 404); | 
 | 	} else { | 
 | 		delay = WEBS_TIMEOUT - tm; | 
 | 		a_assert(delay > 0); | 
 | 		emfReschedCallback(id, delay); | 
 | 	} | 
 | } | 
 |  | 
 | void websDone(webs_t wp, int code) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	socketDeleteHandler(wp->sid); | 
 |  | 
 | 	if (code != 200) { | 
 | 		wp->flags &= ~WEBS_KEEP_ALIVE; | 
 | 	} | 
 |  | 
 | 	websPageClose(wp); | 
 |  | 
 | #ifdef WEBS_SSL_SUPPORT | 
 | 	if (wp->flags & WEBS_SECURE) { | 
 | 		websTimeoutCancel(wp); | 
 | 		websSSLFlush(wp->wsp); | 
 | 		socketCloseConnection(wp->sid); | 
 | 		websFree(wp); | 
 | 		return; | 
 | 	} | 
 | #endif | 
 |  | 
 | 	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); | 
 | } | 
 |  | 
 | 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->referer) | 
 | 		bfree(B_L, wp->referer); | 
 | 	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); | 
 | } | 
 |  | 
 |  | 
 | int websAlloc(int sid) | 
 | { | 
 | 	webs_t		wp; | 
 | 	int			wid; | 
 |  | 
 | 	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; | 
 | 	wp->cookie = NULL; | 
 | 	wp->referer = NULL; | 
 | 	wp->has_firmware_upload_clean = 0; | 
 |     wp->has_firmware_upload_shell = 0; | 
 | #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); | 
 |  | 
 | 	wp->cgiVars = symOpen(WEBS_SYM_INIT); | 
 |  | 
 | 	return wid; | 
 | } | 
 |  | 
 |  | 
 | char_t *websGetIpaddrUrl() | 
 | { | 
 | 	return websIpaddrUrl; | 
 | } | 
 |  | 
 |  | 
 | char_t *websGetHostUrl() | 
 | { | 
 | 	return websHostUrl; | 
 | } | 
 |  | 
 |  | 
 | int websGetPort() | 
 | { | 
 | 	return websPort; | 
 | } | 
 |  | 
 | char_t *websGetHost() | 
 | { | 
 | 	return websHost; | 
 | } | 
 |  | 
 |  | 
 | int websGetRequestBytes(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->numbytes; | 
 | } | 
 |  | 
 |  | 
 | int websGetRequestFlags(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->flags; | 
 | } | 
 |  | 
 | char_t *websGetRequestDir(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	if (wp->dir == NULL) { | 
 | 		return T(""); | 
 | 	} | 
 |  | 
 | 	return wp->dir; | 
 | } | 
 |  | 
 |  | 
 | int websGetSid(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->sid; | 
 | } | 
 |  | 
 |  | 
 | char_t *websGetRequestIpaddr(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 | 	return wp->ipaddr; | 
 | } | 
 |  | 
 |  | 
 | #ifdef FEATURE_ZTE_WEB_TCARD | 
 | //added by guo shoupeng 10124224 for http share 20111001 start | 
 | char_t * websGetURL(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->url; | 
 | } | 
 |  | 
 | char_t *websGetFileName(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->cgiStdin; | 
 | } | 
 |  | 
 |  | 
 | int websGetState(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->state; | 
 | } | 
 |  | 
 | int websGetlen(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->clen; | 
 | } | 
 |  | 
 | //added by guo shoupeng 10124224 for http share 20111001 end | 
 | #endif | 
 |  | 
 |  | 
 | char_t *websGetRequestLpath(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->lpath; | 
 | } | 
 |  | 
 |  | 
 | char_t *websGetRequestPassword(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->password; | 
 | } | 
 |  | 
 | char_t *websGetRequestPath(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	if (wp->path == NULL) { | 
 | 		return T(""); | 
 | 	} | 
 |  | 
 | 	return wp->path; | 
 | } | 
 |  | 
 |  | 
 | char_t *websGetRequestType(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->type; | 
 | } | 
 |  | 
 |  | 
 | int websGetRequestWritten(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->written; | 
 | } | 
 |  | 
 |  | 
 | char_t *websGetRequestUserName(webs_t wp) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	return wp->userName; | 
 | } | 
 |  | 
 | void websSetHost(char_t *host) | 
 | { | 
 | 	gstrncpy(websHost, host, TSZ(websHost)-1); | 
 | } | 
 |  | 
 |  | 
 | void websSetIpaddr(char_t *ipaddr) | 
 | { | 
 | 	a_assert(ipaddr && *ipaddr); | 
 |  | 
 | 	gstrncpy(websIpaddr, ipaddr, TSZ(websIpaddr)-1); | 
 | } | 
 |  | 
 | void websSetHostUrl(char_t *url) | 
 | { | 
 | 	a_assert(url && *url); | 
 |  | 
 | 	bfreeSafe(B_L, websHostUrl); | 
 | 	websHostUrl = gstrdup(B_L, url); | 
 | } | 
 |  | 
 |  | 
 | void websSetRequestBytes(webs_t wp, int bytes) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 | 	a_assert(bytes >= 0); | 
 |  | 
 | 	wp->numbytes = bytes; | 
 | } | 
 |  | 
 |  | 
 | void websSetRequestLpath(webs_t wp, char_t *lpath) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 | 	a_assert(lpath && *lpath); | 
 |  | 
 | 	if (wp->lpath) { | 
 | 		bfree(B_L, wp->lpath); | 
 | 	} | 
 | 	wp->lpath = bstrdup(B_L, lpath); | 
 | 	websSetVar(wp, T("PATH_TRANSLATED"), wp->lpath); | 
 | } | 
 |  | 
 | void websSetRequestFlags(webs_t wp, int flags) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	wp->flags = flags; | 
 | } | 
 |  | 
 |  | 
 | void websSetRequestPath(webs_t wp, char_t *dir, char_t *path) | 
 | { | 
 | 	char_t	*tmp; | 
 |  | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	if (dir) {  | 
 | 		tmp = wp->dir; | 
 | 		wp->dir = bstrdup(B_L, dir); | 
 | 		if (tmp) { | 
 | 			bfree(B_L, tmp); | 
 | 		} | 
 | 	} | 
 | 	if (path) { | 
 | 		tmp = wp->path; | 
 | 		wp->path = bstrdup(B_L, path); | 
 | 		websSetVar(wp, T("PATH_INFO"), wp->path); | 
 | 		if (tmp) { | 
 | 			bfree(B_L, tmp); | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 |  | 
 | void websSetRequestWritten(webs_t wp, int written) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	wp->written = written; | 
 | } | 
 |  | 
 |  | 
 | void websSetRequestSocketHandler(webs_t wp, int mask, void (*fn)(webs_t wp)) | 
 | { | 
 | 	a_assert(websValid(wp)); | 
 |  | 
 | 	wp->writeSocket = fn; | 
 | 	socketCreateHandler(wp->sid, SOCKET_WRITABLE, websSocketEvent, (int) wp); | 
 | } | 
 |  | 
 |  | 
 | char_t *websGetDateString(websStatType *sbuf) | 
 | { | 
 | 	char_t*	cp, *r; | 
 | 	time_t	now; | 
 |  | 
 | 	if (sbuf == NULL) { | 
 | 		time(&now); | 
 | 	} else { | 
 | 		now = sbuf->mtime; | 
 | 	} | 
 | 	if ((cp = gctime(&now)) != NULL) { | 
 | 		cp[gstrlen(cp) - 1] = '\0'; | 
 | 		r = bstrdup(B_L, cp); | 
 | 		return r; | 
 | 	} | 
 | 	return NULL; | 
 | } | 
 |  | 
 |  | 
 | int websValid(webs_t wp) | 
 | { | 
 | 	int		wid; | 
 |  | 
 | 	for (wid = 0; wid < websMax; wid++) { | 
 | 		if (wp == webs[wid]) { | 
 | 			return 1; | 
 | 		} | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 |  | 
 | void websSetTimeMark(webs_t wp) | 
 | { | 
 | 	wp->timestamp = get_sys_uptime(); | 
 | } | 
 |  | 
 |  | 
 | void websSetRealm(char_t *realmName) | 
 | { | 
 | 	a_assert(realmName); | 
 |  | 
 | 	gstrncpy(websRealm, realmName, TSZ(websRealm)-1); | 
 | } | 
 |  | 
 |  | 
 | char_t *websGetRealm() | 
 | { | 
 | 	return websRealm; | 
 | } | 
 |  | 
 |  | 
 | static int websGetTimeSinceMark(webs_t wp) | 
 | { | 
 | 	return get_sys_uptime() - wp->timestamp; | 
 | } | 
 |  | 
 | void websSetLoginTimemark(webs_t wp) | 
 | { | 
 |  | 
 |     char_t login_timemark[64] = {0}; | 
 |     char_t login_info[20] = {0}; | 
 |     char_t nv_ipaddr[40] = {0}; | 
 |     char_t *ip_address = NULL; | 
 |     zte_topsw_state_e_type status = ZTE_NVIO_MAX; | 
 |     long timemark = 0;     | 
 |     char_t user_login_timemark[64] = {0}; | 
 |     long timemark_check = 0; | 
 | 	long luser_login_timemark = 0; | 
 |  | 
 |    | 
 |     status = zte_web_read(NV_LOGINFO, login_info); | 
 |  | 
 |     if(0 == strcmp(login_info,"ok")) | 
 |     { | 
 |  | 
 |         zte_web_read("user_login_timemark", user_login_timemark); | 
 |  | 
 |         luser_login_timemark = atol(user_login_timemark); | 
 | 		if(luser_login_timemark < 0 || luser_login_timemark > LONG_MAX-1){ | 
 |             luser_login_timemark = LONG_MAX; | 
 | 		} | 
 | 		 | 
 |         timemark_check = time(0) - luser_login_timemark;   | 
 |         if(timemark_check > LOGIN_TIMEOUT) | 
 |         { | 
 |             (void)zte_web_write(NV_USER_IP_ADDR,""); | 
 |             (void)zte_web_write(NV_LOGINFO,"timeout"); | 
 | 			(void)zte_web_write(NV_COOKIE_ID, ""); | 
 |             (void)zte_web_write(NV_USER_LOGIN_TIMEMARK,"0"); | 
 |             slog(MISC_PRINT,SLOG_ERR,"mgmt_login_timemark_check: the login is timeout .\n"); | 
 |         } | 
 |         else | 
 |         { | 
 |             ip_address = websGetRequestIpaddr(wp); | 
 | #if 0		 // kw 3 INVARIANT_CONDITION.UNREACH	  wp->ipaddr is array, address can not be null | 
 |             if (NULL == ip_address) | 
 |             { | 
 |                 slog(MISC_PRINT,SLOG_ERR,"websSetLoginTimemark: ip_address is null.\n"); | 
 |                 return ; | 
 |             } | 
 | #endif | 
 |             zte_web_read(NV_USER_IP_ADDR, nv_ipaddr); | 
 |             | 
 |  | 
 |             if (0 == strcmp(ip_address,nv_ipaddr)) | 
 |             { | 
 |                 timemark = time(0); | 
 |                 sprintf(login_timemark,"%ld",timemark);   | 
 |                 (void)zte_web_write(NV_USER_LOGIN_TIMEMARK, login_timemark); | 
 |             } | 
 |  | 
 |          } | 
 |     }   | 
 |  | 
 | } | 
 |  |