[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/goahead/server/webs.c b/ap/app/goahead/server/webs.c
new file mode 100755
index 0000000..b0238e1
--- /dev/null
+++ b/ap/app/goahead/server/webs.c
@@ -0,0 +1,2303 @@
+#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]:zte_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,"zte_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);
+ }
+
+ }
+ }
+
+}
+