blob: b0238e1f2e8ec72236ccdcdf3fb9e5b95b6811f7 [file] [log] [blame]
#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("&lt;")
#define kGt '>'
#define kGreaterThan T("&gt;")
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);
}
}
}
}