| #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 /tmp/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); |
| } |
| |
| } |
| } |
| |
| } |
| |