lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | #include "wsIntrn.h" |
| 2 | #ifdef DIGEST_ACCESS_SUPPORT |
| 3 | #include "websda.h" |
| 4 | #endif |
| 5 | #include "../interface5.0/zte_web_interface.h" |
| 6 | //#include "../interface5.0/zte_rest_comm_interface.h" |
| 7 | |
| 8 | websStatsType websStats; |
| 9 | webs_t *webs; |
| 10 | sym_fd_t websMime; |
| 11 | int websMax; |
| 12 | int websPort; |
| 13 | char_t websHost[64]; |
| 14 | char_t websIpaddr[64]; |
| 15 | char_t *websHostUrl = NULL; |
| 16 | char_t *websIpaddrUrl = NULL; |
| 17 | //added by liuyingnan for PC Client begin, 20120829 |
| 18 | char websRecvHttpBuffer[HTTP_BUFFER_SIZE] = {0}; |
| 19 | char websRecvHttpBuffer_XML[HTTP_BUFFER_SIZE] = {0}; |
| 20 | |
| 21 | extern void zte_change_wp_query(webs_t wp,char_t *xml_str); |
| 22 | //added by liuyingnan for PC Client begin, 20120829 |
| 23 | |
| 24 | websErrorType websErrors[] = { |
| 25 | { 200, T("Data follows") }, |
| 26 | { 204, T("No Content") }, |
| 27 | { 301, T("Redirect") }, |
| 28 | { 302, T("Redirect") }, |
| 29 | { 304, T("Use local copy") }, |
| 30 | { 400, T("Page not found") }, |
| 31 | { 401, T("Unauthorized") }, |
| 32 | { 403, T("Forbidden") }, |
| 33 | { 404, T("Site or Page Not Found") }, |
| 34 | { 405, T("Access Denied") }, |
| 35 | { 500, T("Web Error") }, |
| 36 | { 501, T("Not Implemented") }, |
| 37 | { 503, T("Site Temporarily Unavailable. Try again.") }, |
| 38 | { 0, NULL } |
| 39 | }; |
| 40 | |
| 41 | typedef enum { |
| 42 | RET_DATA_ERROR = -1, |
| 43 | RET_FAILED = 0, |
| 44 | RET_OK = 1, |
| 45 | } ERROR_CODE; |
| 46 | |
| 47 | |
| 48 | #ifdef FEATURE_ZTE_WEB_TCARD |
| 49 | //added by guo shoupeng 10124224 for http share 20111001 start |
| 50 | |
| 51 | typedef enum { |
| 52 | RET_FAILED = 0, |
| 53 | RET_OK = 1, |
| 54 | RET_UNKNOWN = 3, |
| 55 | MALLOC_FIALED = 4, |
| 56 | SD_NONE = 5, |
| 57 | USB_OUT = 6, |
| 58 | USER_MALLOC_FAILED = 7, |
| 59 | UPLOAD_FILE_LIMITED = 8, |
| 60 | USER_UNKNOWN = 9, |
| 61 | } ERROR_CODE; |
| 62 | |
| 63 | //added by guo shoupeng 10124224 for http share 20111001 end |
| 64 | #endif |
| 65 | |
| 66 | |
| 67 | |
| 68 | static int websGetInput(webs_t wp, char_t **ptext, int *nbytes); |
| 69 | static int websParseFirst(webs_t wp, char_t *text); |
| 70 | static int websParseRequest(webs_t wp); |
| 71 | static void websSocketEvent(int sid, int mask, int data); |
| 72 | static int websGetTimeSinceMark(webs_t wp); |
| 73 | |
| 74 | static int websListenSock; |
| 75 | static char_t websRealm[64] = T("GoAhead"); |
| 76 | |
| 77 | static int websOpenCount = 0; |
| 78 | |
| 79 | |
| 80 | int websOpenServer(int port, int retries) |
| 81 | { |
| 82 | websMimeType *mt; |
| 83 | |
| 84 | if (++websOpenCount != 1) { |
| 85 | return websPort; |
| 86 | } |
| 87 | |
| 88 | a_assert(port > 0); |
| 89 | a_assert(retries >= 0); |
| 90 | |
| 91 | webs = NULL; |
| 92 | websMax = 0; |
| 93 | |
| 94 | websMime = symOpen(WEBS_SYM_INIT * 4); |
| 95 | a_assert(websMime >= 0); |
| 96 | if(websMime < 0) // cov M NEGATIVE_RETURNS |
| 97 | { |
| 98 | return -1; |
| 99 | } |
| 100 | for (mt = websMimeList; mt->type; mt++) { |
| 101 | symEnter(websMime, mt->ext, valueString(mt->type, 0), 0); |
| 102 | } |
| 103 | |
| 104 | #if 1 |
| 105 | // kw 3 INVARIANT_CONDITION.UNREACH websUrlHandlerOpen only return 0 |
| 106 | websUrlHandlerOpen(); |
| 107 | #else |
| 108 | if (websUrlHandlerOpen() < 0) { |
| 109 | return -1; |
| 110 | } |
| 111 | #endif |
| 112 | websFormOpen(); |
| 113 | |
| 114 | return websOpenListen(port, retries); |
| 115 | } |
| 116 | |
| 117 | |
| 118 | |
| 119 | void websCloseServer() |
| 120 | { |
| 121 | webs_t wp; |
| 122 | int wid; |
| 123 | |
| 124 | if (--websOpenCount > 0) { |
| 125 | return; |
| 126 | } |
| 127 | |
| 128 | websCloseListen(); |
| 129 | |
| 130 | for (wid = websMax; webs && wid >= 0; wid--) { |
| 131 | if ((wp = webs[wid]) == NULL) { |
| 132 | continue; |
| 133 | } |
| 134 | socketCloseConnection(wp->sid); |
| 135 | websFree(wp); |
| 136 | } |
| 137 | |
| 138 | symClose(websMime); |
| 139 | websFormClose(); |
| 140 | websUrlHandlerClose(); |
| 141 | } |
| 142 | |
| 143 | |
| 144 | void websCloseListen() |
| 145 | { |
| 146 | if (websListenSock >= 0) { |
| 147 | socketCloseConnection(websListenSock); |
| 148 | websListenSock = -1; |
| 149 | } |
| 150 | bfreeSafe(B_L, websHostUrl); |
| 151 | bfreeSafe(B_L, websIpaddrUrl); |
| 152 | websIpaddrUrl = websHostUrl = NULL; |
| 153 | } |
| 154 | |
| 155 | |
| 156 | int websOpenListen(int port, int retries) |
| 157 | { |
| 158 | int i, orig; |
| 159 | |
| 160 | a_assert(port > 0); |
| 161 | a_assert(retries >= 0); |
| 162 | |
| 163 | orig = port; |
| 164 | |
| 165 | for (i = 0; i <= retries; i++) { |
| 166 | websListenSock = socketOpenConnection6(NULL, port, websAccept, 0); |
| 167 | if (websListenSock >= 0) { |
| 168 | break; |
| 169 | } |
| 170 | port++; |
| 171 | } |
| 172 | if (i > retries) { |
| 173 | error(E_L, E_USER, T("Couldn't open a socket on ports %d - %d"), |
| 174 | orig, port - 1); |
| 175 | return -1; |
| 176 | } |
| 177 | |
| 178 | websPort = port; |
| 179 | bfreeSafe(B_L, websHostUrl); |
| 180 | bfreeSafe(B_L, websIpaddrUrl); |
| 181 | websIpaddrUrl = websHostUrl = NULL; |
| 182 | |
| 183 | if (port == 80) { |
| 184 | websHostUrl = bstrdup(B_L, websHost); |
| 185 | websIpaddrUrl = bstrdup(B_L, websIpaddr); |
| 186 | } else { |
| 187 | fmtAlloc(&websHostUrl, WEBS_MAX_URL + 80, T("%s:%d"), websHost, port); |
| 188 | fmtAlloc(&websIpaddrUrl, WEBS_MAX_URL + 80, T("%s:%d"), |
| 189 | websIpaddr, port); |
| 190 | } |
| 191 | trace(0, T("webs: Listening for HTTP requests at address %s\n"), |
| 192 | websIpaddrUrl); |
| 193 | |
| 194 | return port; |
| 195 | } |
| 196 | |
| 197 | |
| 198 | static void websSocketEvent(int sid, int mask, int iwp) |
| 199 | { |
| 200 | webs_t wp; |
| 201 | |
| 202 | wp = (webs_t) iwp; |
| 203 | a_assert(wp); |
| 204 | |
| 205 | if (! websValid(wp)) { |
| 206 | return; |
| 207 | } |
| 208 | |
| 209 | if (mask & SOCKET_READABLE) { |
| 210 | websReadEvent(wp); |
| 211 | } |
| 212 | if (mask & SOCKET_WRITABLE) { |
| 213 | if (websValid(wp) && wp->writeSocket) { |
| 214 | (*wp->writeSocket)(wp); |
| 215 | } |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | int websAccept(int sid, char *ipaddr, int port, int listenSid) |
| 220 | { |
| 221 | webs_t wp; |
| 222 | int wid; |
| 223 | |
| 224 | a_assert(ipaddr && *ipaddr); |
| 225 | a_assert(sid >= 0); |
| 226 | a_assert(port >= 0); |
| 227 | |
| 228 | if ((wid = websAlloc(sid)) < 0) { |
| 229 | return -1; |
| 230 | } |
| 231 | wp = webs[wid]; |
| 232 | a_assert(wp); |
| 233 | wp->listenSid = listenSid; |
| 234 | |
| 235 | ascToUni(wp->ipaddr, ipaddr, min(sizeof(wp->ipaddr), strlen(ipaddr) + 1)); |
| 236 | |
| 237 | if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 || |
| 238 | gstrcmp(wp->ipaddr, websIpaddr) == 0 || |
| 239 | gstrcmp(wp->ipaddr, websHost) == 0) { |
| 240 | wp->flags |= WEBS_LOCAL_REQUEST; |
| 241 | } |
| 242 | |
| 243 | socketCreateHandler(sid, SOCKET_READABLE, websSocketEvent, (int) wp); |
| 244 | |
| 245 | wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp); |
| 246 | //trace(8, T("webs: accept request\n")); |
| 247 | return 0; |
| 248 | } |
| 249 | |
| 250 | |
| 251 | |
| 252 | #ifdef FEATURE_ZTE_WEB_TCARD |
| 253 | //added by guo shoupeng 10124224 for http share 20120110 start |
| 254 | static int read_bytes = 0; |
| 255 | //added by guo shoupeng 10124224 for http share 20120110 end |
| 256 | #endif |
| 257 | |
| 258 | void websReadEvent(webs_t wp) |
| 259 | { |
| 260 | char_t *text; |
| 261 | int rc, nbytes, len, done, fd; |
| 262 | |
| 263 | a_assert(wp); |
| 264 | a_assert(websValid(wp)); |
| 265 | |
| 266 | websSetTimeMark(wp); |
| 267 | |
| 268 | static unsigned int timer = 0; |
| 269 | |
| 270 | text = NULL; |
| 271 | fd = -1; |
| 272 | for (done = 0; !done; ) { |
| 273 | if (text) { |
| 274 | bfree(B_L, text); |
| 275 | text = NULL; |
| 276 | } |
| 277 | |
| 278 | |
| 279 | #ifdef FEATURE_ZTE_WEB_TCARD |
| 280 | //added by guo shoupeng 10124224 for http share 20120110 start |
| 281 | if( read_bytes > UPLOAD_INTERVAL) |
| 282 | { |
| 283 | read_bytes = 0; |
| 284 | break; |
| 285 | } |
| 286 | //added by guo shoupeng 10124224 for http share 20120110 end |
| 287 | #endif |
| 288 | assert(wp); |
| 289 | assert(websValid(wp)); |
| 290 | while ((rc = websGetInput(wp, &text, &nbytes)) == 0) { |
| 291 | ; |
| 292 | } |
| 293 | |
| 294 | |
| 295 | if (rc < 0) { |
| 296 | if(websValid(wp) && (wp->flags & WEBS_CGI_REQUEST )) |
| 297 | { |
| 298 | //printf("\n +++sockettt upload websSetTimeMark+++ \n"); |
| 299 | websSetTimeMark(wp); |
| 300 | } |
| 301 | break; |
| 302 | } |
| 303 | if(text == NULL) |
| 304 | break;//for kw |
| 305 | |
| 306 | switch(wp->state) { |
| 307 | case WEBS_BEGIN: |
| 308 | |
| 309 | if (websParseFirst(wp, text) < 0) { |
| 310 | done++; |
| 311 | break; |
| 312 | } |
| 313 | wp->state = WEBS_HEADER; |
| 314 | break; |
| 315 | |
| 316 | case WEBS_HEADER: |
| 317 | |
| 318 | if (ringqLen(&wp->header) > 0) { |
| 319 | ringqPutStr(&wp->header, T("\n")); |
| 320 | } |
| 321 | ringqPutStr(&wp->header, text); |
| 322 | break; |
| 323 | |
| 324 | case WEBS_POST_CLEN: |
| 325 | |
| 326 | #ifndef __NO_CGI_BIN |
| 327 | if (wp->flags & WEBS_CGI_REQUEST) { |
| 328 | |
| 329 | //if(!(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD)) |
| 330 | if(wp->flags & WEBS_CGI_HTTPSHARE_UPLOAD) |
| 331 | { |
| 332 | if( timer ==0) |
| 333 | { |
| 334 | websSetLoginTimemark(wp); |
| 335 | printf("[httpshare]upload reset login state~\n"); |
| 336 | } |
| 337 | ERROR_CODE ret = zte_process_cgi_recv(wp, wp->clen,text, nbytes); |
| 338 | |
| 339 | if(RET_DATA_ERROR == ret || RET_FAILED == ret) |
| 340 | { |
| 341 | websError(wp, 404, T("Bad state")); |
| 342 | printf("[httpshare]ret->%d\n",ret); |
| 343 | done++; |
| 344 | break; |
| 345 | } |
| 346 | |
| 347 | timer++; |
| 348 | timer=timer-(timer>>11<<11); //timer%2^11 |
| 349 | }else if(wp->flags & WEBS_CGI_UPLOAD) |
| 350 | { |
| 351 | if (fd == -1) |
| 352 | { |
| 353 | if(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD ) |
| 354 | { |
| 355 | fd = gopen(FIRMWARE_TMP_FILE, O_CREAT | O_WRONLY | O_BINARY | O_APPEND, 0666); |
| 356 | printf("[goahead]open cgi temp file\n"); |
| 357 | } |
| 358 | else |
| 359 | { |
| 360 | fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY | O_APPEND, 0666); |
| 361 | } |
| 362 | } |
| 363 | if(fd < 0){ |
| 364 | break; |
| 365 | } |
| 366 | |
| 367 | |
| 368 | gwrite(fd, text, nbytes); |
| 369 | }else |
| 370 | { |
| 371 | websError(wp, 404, T("Bad state")); |
| 372 | printf("[goahead]bad cgi request\n"); |
| 373 | done++; |
| 374 | break; |
| 375 | } |
| 376 | |
| 377 | |
| 378 | } else |
| 379 | #endif |
| 380 | //added by liuyingnan for PC Client begin, 20120829 |
| 381 | if(wp->flags & WEBS_REST_CLIENT_REQUEST){ |
| 382 | printf("%s", "websReadEvent: pc client post"); |
| 383 | if (nbytes > (HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer)-1)) |
| 384 | { |
| 385 | gstrncpy(websRecvHttpBuffer+gstrlen(websRecvHttpBuffer), text, HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer)-1); |
| 386 | } |
| 387 | else |
| 388 | { |
| 389 | gstrncpy(websRecvHttpBuffer+gstrlen(websRecvHttpBuffer), text, nbytes); |
| 390 | } |
| 391 | } else if(wp->flags & WEBS_XML_CLIENT_REQUEST){ |
| 392 | if (nbytes > (HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer_XML)-1)) |
| 393 | { |
| 394 | gstrncpy(websRecvHttpBuffer_XML+gstrlen(websRecvHttpBuffer_XML), text, HTTP_BUFFER_SIZE-gstrlen(websRecvHttpBuffer_XML)-1); |
| 395 | } |
| 396 | else |
| 397 | { |
| 398 | gstrncpy(websRecvHttpBuffer_XML+gstrlen(websRecvHttpBuffer_XML), text, nbytes); |
| 399 | } |
| 400 | } else |
| 401 | //added by liuyingnan for PC Client end, 20120829 |
| 402 | |
| 403 | |
| 404 | |
| 405 | if (wp->query) { |
| 406 | if (wp->query[0] && !(wp->flags & WEBS_POST_DATA)) { |
| 407 | |
| 408 | len = gstrlen(wp->query); |
| 409 | wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) + |
| 410 | 2) * sizeof(char_t)); |
| 411 | if(wp->query == NULL) |
| 412 | break;//for kw |
| 413 | wp->query[len++] = '&'; |
| 414 | gstrcpy(&wp->query[len], text); |
| 415 | |
| 416 | } else { |
| 417 | |
| 418 | //if (text != NULL)//for kw |
| 419 | { |
| 420 | len = gstrlen(wp->query); |
| 421 | wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) + |
| 422 | 1) * sizeof(char_t)); |
| 423 | if (wp->query) { |
| 424 | gstrcpy(&wp->query[len], text); |
| 425 | } |
| 426 | } |
| 427 | } |
| 428 | |
| 429 | } else { |
| 430 | wp->query = bstrdup(B_L, text); |
| 431 | } |
| 432 | #if 0 //for kw |
| 433 | //Add By liuyingnan for XML COMM API START |
| 434 | if(wp->flags & WEBS_XML_CLIENT_REQUEST) |
| 435 | { |
xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 436 | slog(MISC_PRINT,SLOG_DEBUG,"[websReadEvent]:change_wp_query function:%s\n",websRecvHttpBuffer_XML); |
lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 437 | //zte_change_wp_query(wp,websRecvHttpBuffer_Json); |
| 438 | zte_change_wp_query(wp,websRecvHttpBuffer_XML); |
| 439 | memset(websRecvHttpBuffer_XML,0,HTTP_BUFFER_SIZE); |
| 440 | slog(MISC_PRINT,SLOG_DEBUG,"[out the function]:wp->query:%s\n",wp->query); |
| 441 | } |
| 442 | //Add By liuyingnan for XML COMM API END |
| 443 | #endif |
| 444 | |
| 445 | wp->flags |= WEBS_POST_DATA; |
| 446 | wp->clen -= nbytes; |
| 447 | if (wp->clen > 0) { |
| 448 | if (nbytes > 0) { |
| 449 | break; |
| 450 | } |
| 451 | done++; |
| 452 | break; |
| 453 | } |
| 454 | #ifdef FEATURE_ZTE_WEB_TCARD |
| 455 | //added by guo shoupeng 10124224 for http share 20120110 start |
| 456 | else |
| 457 | { |
| 458 | zte_efs_write(wp); |
| 459 | } |
| 460 | //added by guo shoupeng 10124224 for http share 20120110 end |
| 461 | #endif |
| 462 | |
| 463 | if (fd != -1) { |
| 464 | gclose (fd); |
| 465 | fd = -1; |
| 466 | } |
| 467 | websUrlHandlerRequest(wp); |
| 468 | done++; |
| 469 | break; |
| 470 | |
| 471 | case WEBS_POST: |
| 472 | |
| 473 | |
| 474 | #ifndef __NO_CGI_BIN |
| 475 | if (wp->flags & WEBS_CGI_REQUEST) { |
| 476 | if (fd == -1) { |
| 477 | fd = gopen(wp->cgiStdin, O_CREAT | O_WRONLY | O_BINARY, |
| 478 | 0666); |
| 479 | } |
| 480 | |
| 481 | if(fd < 0){ |
| 482 | break; |
| 483 | } |
| 484 | gwrite(fd, text, gstrlen(text)); |
| 485 | gwrite(fd, T("\n"), sizeof(char_t)); |
| 486 | } else |
| 487 | #endif |
| 488 | if (wp->query && *wp->query && !(wp->flags & WEBS_POST_DATA)) { |
| 489 | len = gstrlen(wp->query); |
| 490 | wp->query = brealloc(B_L, wp->query, (len + gstrlen(text) + |
| 491 | 2) * sizeof(char_t)); |
| 492 | if (wp->query) { |
| 493 | wp->query[len++] = '&'; |
| 494 | gstrcpy(&wp->query[len], text); |
| 495 | } |
| 496 | |
| 497 | } else { |
| 498 | wp->query = bstrdup(B_L, text); |
| 499 | } |
| 500 | wp->flags |= WEBS_POST_DATA; |
| 501 | done++; |
| 502 | break; |
| 503 | |
| 504 | default: |
| 505 | websError(wp, 404, T("Bad state")); |
| 506 | done++; |
| 507 | break; |
| 508 | } |
| 509 | } |
| 510 | |
| 511 | if (fd != -1) { |
| 512 | fd = gclose (fd); |
| 513 | } |
| 514 | |
| 515 | if (text) { |
| 516 | bfree(B_L, text); |
| 517 | } |
| 518 | } |
| 519 | char_t htmExt[] = T(".htm"); |
| 520 | int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath, |
| 521 | char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag, |
| 522 | char_t **pext) |
| 523 | { |
| 524 | char_t *hostbuf, *portbuf, *buf; |
| 525 | int c, len, ulen; |
| 526 | char_t *tok, *cp, *host, *path, *port, *proto, *tag, *query, *ext; |
| 527 | |
| 528 | a_assert(url); |
| 529 | a_assert(pbuf); |
| 530 | |
| 531 | ulen = gstrlen(url); |
| 532 | |
| 533 | len = ulen * 2 + MAX_PORT_LEN + 3; |
| 534 | if ((buf = balloc(B_L, len * sizeof(char_t))) == NULL) { |
| 535 | return -1; |
| 536 | } |
| 537 | portbuf = &buf[len - MAX_PORT_LEN - 1]; |
| 538 | hostbuf = &buf[ulen+1]; |
| 539 | |
| 540 | websDecodeUrl(buf, url, ulen); |
| 541 | |
| 542 | url = buf; |
| 543 | |
| 544 | if(portbuf == NULL) //for kw 20210312 |
| 545 | return -1; |
| 546 | |
| 547 | stritoa(websGetPort(), portbuf, MAX_PORT_LEN); |
| 548 | port = portbuf; |
| 549 | path = T("/"); |
| 550 | proto = T("http"); |
| 551 | host = T("localhost"); |
| 552 | query = T(""); |
| 553 | ext = htmExt; |
| 554 | tag = T(""); |
| 555 | |
| 556 | if (gstrncmp(url, T("http://"), 7) == 0) { |
| 557 | tok = &url[7]; |
| 558 | tok[-3] = '\0'; |
| 559 | proto = url; |
| 560 | host = tok; |
| 561 | for (cp = tok; *cp; cp++) { |
| 562 | if (*cp == '/') { |
| 563 | break; |
| 564 | } |
| 565 | if (*cp == ':') { |
| 566 | *cp++ = '\0'; |
| 567 | port = cp; |
| 568 | tok = cp; |
| 569 | } |
| 570 | } |
| 571 | if ((cp = gstrchr(tok, '/')) != NULL) { |
| 572 | |
| 573 | c = *cp; |
| 574 | *cp = '\0'; |
| 575 | gstrncpy(hostbuf, host, ulen); |
| 576 | gstrncpy(portbuf, port, MAX_PORT_LEN); |
| 577 | *cp = c; |
| 578 | host = hostbuf; |
| 579 | port = portbuf; |
| 580 | path = cp; |
| 581 | tok = cp; |
| 582 | } |
| 583 | |
| 584 | } else { |
| 585 | path = url; |
| 586 | tok = url; |
| 587 | } |
| 588 | |
| 589 | if ((cp = gstrchr(tok, '?')) != NULL) { |
| 590 | *cp++ = '\0'; |
| 591 | query = cp; |
| 592 | path = tok; |
| 593 | tok = query; |
| 594 | } |
| 595 | |
| 596 | if ((cp = gstrchr(tok, '#')) != NULL) { |
| 597 | *cp++ = '\0'; |
| 598 | if (*query == 0) { |
| 599 | path = tok; |
| 600 | } |
| 601 | } |
| 602 | |
| 603 | if (pext) { |
| 604 | |
| 605 | if ((cp = gstrrchr(path, '.')) != NULL) { |
| 606 | const char_t* garbage = T("/\\"); |
| 607 | int length = gstrcspn(cp, garbage); |
| 608 | int garbageLength = gstrspn(cp + length, garbage); |
| 609 | int ok = (length + garbageLength == (int) gstrlen(cp)); |
| 610 | |
| 611 | if (ok) { |
| 612 | cp[length] = '\0'; |
| 613 | ext = cp; |
| 614 | } |
| 615 | } |
| 616 | } |
| 617 | |
| 618 | if (phost) |
| 619 | *phost = host; |
| 620 | if (ppath) |
| 621 | *ppath = path; |
| 622 | if (pport) |
| 623 | *pport = port; |
| 624 | if (pproto) |
| 625 | *pproto = proto; |
| 626 | if (pquery) |
| 627 | *pquery = query; |
| 628 | if (ptag) |
| 629 | *ptag = tag; |
| 630 | if (pext) |
| 631 | *pext = ext; |
| 632 | *pbuf = buf; |
| 633 | return 0; |
| 634 | } |
| 635 | |
| 636 | char_t *websUrlType(char_t *url, char_t *buf, int charCnt) |
| 637 | { |
| 638 | char_t *ext = NULL; //cov |
| 639 | char_t *tmp_buf; |
| 640 | sym_t *psym; |
| 641 | |
| 642 | a_assert(url && *url); |
| 643 | a_assert(buf && charCnt > 0); |
| 644 | |
| 645 | if (url == NULL || *url == '\0') { |
| 646 | gstrcpy(buf, T("text/plain")); |
| 647 | return buf; |
| 648 | } |
| 649 | if (websUrlParse(url, &tmp_buf, NULL, NULL, NULL, NULL, NULL, |
| 650 | NULL, &ext) < 0) { |
| 651 | gstrcpy(buf, T("text/plain")); |
| 652 | return buf; |
| 653 | } |
| 654 | strlower(ext); |
| 655 | |
| 656 | if ((psym = symLookup(websMime, ext)) != NULL) { |
| 657 | gstrncpy(buf, psym->content.value.string, charCnt); |
| 658 | } else { |
| 659 | gstrcpy(buf, T("text/plain")); |
| 660 | } |
| 661 | bfree(B_L, tmp_buf); |
| 662 | return buf; |
| 663 | } |
| 664 | |
| 665 | static int websParseFirst(webs_t wp, char_t *text) |
| 666 | { |
| 667 | char_t *op, *proto, *protoVer, *url, *host, *query, *path, *port, *ext; |
| 668 | char_t *buf; |
| 669 | int testPort; |
| 670 | |
| 671 | #ifdef FEATURE_ZTE_WEB_TCARD |
| 672 | //added by guo shoupeng 10124224 for http share 20111001 start |
| 673 | char *page_att=NULL; |
| 674 | //added by guo shoupeng 10124224 for http share 20111001 end |
| 675 | #endif |
| 676 | a_assert(websValid(wp)); |
| 677 | a_assert(text && *text); |
| 678 | #ifdef WEBINSPECT_FIX |
| 679 | if(text && (!is_print_str(text,strlen(text)) || strstr(text, "HTTP") == NULL)) |
| 680 | { |
| 681 | websDone(wp, 0); |
| 682 | slog(MISC_PRINT, SLOG_ERR,"[goahead]es\n"); |
| 683 | return -1; |
| 684 | } |
| 685 | #endif |
| 686 | op = gstrtok(text, T(" \t")); |
| 687 | if (op == NULL || *op == '\0') { |
| 688 | websError(wp, 400, T("Bad HTTP request")); |
| 689 | return -1; |
| 690 | } |
| 691 | if (gstrcmp(op, T("GET")) != 0) { |
| 692 | if (gstrcmp(op, T("POST")) == 0) { |
| 693 | wp->flags |= WEBS_POST_REQUEST; |
| 694 | } else if (gstrcmp(op, T("HEAD")) == 0) { |
| 695 | wp->flags |= WEBS_HEAD_REQUEST; |
| 696 | } else { |
| 697 | websError(wp, 400, T("Bad request type")); |
| 698 | return -1; |
| 699 | } |
| 700 | } |
| 701 | |
| 702 | websSetVar(wp, T("REQUEST_METHOD"), op); |
| 703 | |
| 704 | url = gstrtok(NULL, T(" \t\n")); |
| 705 | if (url == NULL || *url == '\0') { |
| 706 | websError(wp, 400, T("Bad HTTP request")); |
| 707 | return -1; |
| 708 | } |
| 709 | protoVer = gstrtok(NULL, T(" \t\n")); |
| 710 | |
| 711 | host = path = port = proto = query = ext = NULL; |
| 712 | if (websUrlParse(url, &buf, &host, &path, &port, &query, &proto, |
| 713 | NULL, &ext) < 0) { |
| 714 | websError(wp, 400, T("Bad URL format")); |
| 715 | return -1; |
| 716 | } |
| 717 | |
| 718 | wp->url = bstrdup(B_L, url); |
| 719 | |
| 720 | #ifndef __NO_CGI_BIN |
| 721 | |
| 722 | |
| 723 | if ((gstrstr(url, CGI_BIN) != NULL)&&((wp->flags & WEBS_POST_REQUEST))) { |
| 724 | wp->flags |= WEBS_CGI_REQUEST; |
| 725 | |
| 726 | printf("[goahead]set WEBS_CGI_REQUEST \n"); |
| 727 | |
| 728 | // special case: upload.cgi |
| 729 | |
| 730 | if(gstrstr(url, CGI_BIN_UPLOAD) != NULL) |
| 731 | { |
| 732 | if(gstrstr(url, CGI_FIRMWARE_UPLOAD) != NULL){ |
| 733 | wp->flags |= WEBS_CGI_FIRMWARE_UPLOAD; |
| 734 | system("rm -rf /firmware_tmp_file"); |
| 735 | zte_mgmt_login_timemark_set(); |
| 736 | printf("[goahead]set WEBS_CGI_FIRMWARE_UPLOAD \n"); |
| 737 | } |
| 738 | wp->cgiStdin = websGetCgiCommName(wp); |
| 739 | printf("[goahead]get cgi name.\n"); |
| 740 | // ex: upload_setting.... |
| 741 | wp->flags |= WEBS_CGI_UPLOAD; |
| 742 | } |
| 743 | |
| 744 | if(gstrstr(url, CGI_BIN_HTTPSHARE) != NULL) |
| 745 | { |
| 746 | printf("[httpshare]upload file.\n"); |
| 747 | |
| 748 | if(!zte_reset_cgi_state(wp)) |
| 749 | { |
| 750 | printf("[httpshare]upload file.reset cgi state error.\n"); |
| 751 | bfree(B_L, buf); |
| 752 | return -1; |
| 753 | } |
| 754 | wp->flags |= WEBS_CGI_HTTPSHARE_UPLOAD; |
| 755 | } |
| 756 | |
| 757 | |
| 758 | } |
| 759 | #endif |
| 760 | |
| 761 | wp->query = bstrdup(B_L, query); |
| 762 | wp->host = bstrdup(B_L, host); |
| 763 | wp->path = bstrdup(B_L, path); |
| 764 | wp->protocol = bstrdup(B_L, proto); |
| 765 | wp->protoVersion = bstrdup(B_L, protoVer); |
| 766 | |
| 767 | //added by liuyingnan for PC Client begin, 20120829 |
| 768 | if (gstrstr(url, "api/client/post") != NULL) { |
| 769 | printf("%s", "websParseFirst: pc client post"); |
| 770 | wp->flags |= WEBS_REST_CLIENT_REQUEST; |
| 771 | } |
| 772 | //added by huangmin for PC Client end, 20120829 |
| 773 | if (gstrstr(url, "api/xmlclient/post") != NULL) { |
| 774 | wp->flags |= WEBS_XML_CLIENT_REQUEST; |
| 775 | } |
| 776 | |
| 777 | if ((testPort = socketGetPort(wp->listenSid)) >= 0) { |
| 778 | wp->port = testPort; |
| 779 | } else { |
| 780 | wp->port = gatoi(port); |
| 781 | } |
| 782 | |
| 783 | if (gstrcmp(ext, T(".asp")) == 0) { |
| 784 | wp->flags |= WEBS_ASP; |
| 785 | } |
| 786 | bfree(B_L, buf); |
| 787 | |
| 788 | websUrlType(url, wp->type, TSZ(wp->type)); |
| 789 | |
| 790 | ringqFlush(&wp->header); |
| 791 | return 0; |
| 792 | } |
| 793 | |
| 794 | static int websGetInput(webs_t wp, char_t **ptext, int *pnbytes) |
| 795 | { |
| 796 | char_t *text; |
| 797 | char buf[WEBS_SOCKET_BUFSIZ+1]; |
| 798 | int nbytes, len, clen; |
| 799 | |
| 800 | a_assert(websValid(wp)); |
| 801 | a_assert(ptext); |
| 802 | a_assert(pnbytes); |
| 803 | |
| 804 | if(websValid(wp) == 0 || ptext == NULL || pnbytes == NULL){ |
| 805 | softap_assert("websGetInput 1"); |
| 806 | return -1;//for kw |
| 807 | } |
| 808 | |
| 809 | *ptext = text = NULL; |
| 810 | *pnbytes = 0; |
| 811 | |
| 812 | if (wp->state == WEBS_POST_CLEN) { |
| 813 | len = (wp->clen > WEBS_SOCKET_BUFSIZ) ? WEBS_SOCKET_BUFSIZ : wp->clen; |
| 814 | } else { |
| 815 | len = 0; |
| 816 | } |
| 817 | |
| 818 | if (len > 0) { |
| 819 | |
| 820 | #ifdef WEBS_SSL_SUPPORT |
| 821 | if (wp->flags & WEBS_SECURE) { |
| 822 | nbytes = websSSLRead(wp->wsp, buf, len); |
| 823 | } else { |
| 824 | nbytes = socketRead(wp->sid, buf, len); |
| 825 | } |
| 826 | #else |
| 827 | nbytes = socketRead(wp->sid, buf, len); |
| 828 | #endif |
| 829 | if (nbytes < 0) { /* Error */ |
| 830 | websDone(wp, 0); |
| 831 | return -1; |
| 832 | |
| 833 | } else if (nbytes == 0) { /* EOF or No data available */ |
| 834 | //trace(8, T("@@@@webs 0x%x 0x%x: websGetInput read 0\n"),wp,wp->sid); |
| 835 | if (socketEof(wp->sid)) { |
| 836 | websDone(wp, 0); |
| 837 | } |
| 838 | return -1; |
| 839 | |
| 840 | } else { /* Valid data */ |
| 841 | |
| 842 | buf[nbytes] = '\0'; |
| 843 | if ((text = ballocAscToUni(buf, nbytes)) == NULL) { |
| 844 | websError(wp, 503, T("Insufficient memory")); |
| 845 | return -1; |
| 846 | } |
| 847 | } |
| 848 | |
| 849 | } else { |
| 850 | #ifdef WEBS_SSL_SUPPORT |
| 851 | if (wp->flags & WEBS_SECURE) { |
| 852 | nbytes = websSSLGets(wp->wsp, &text); |
| 853 | } else { |
| 854 | nbytes = socketGets(wp->sid, &text); |
| 855 | } |
| 856 | #else |
| 857 | nbytes = socketGets(wp->sid, &text); |
| 858 | #endif |
| 859 | |
| 860 | if (nbytes < 0) { |
| 861 | int eof; |
| 862 | |
| 863 | #ifdef WEBS_SSL_SUPPORT |
| 864 | if (wp->flags & WEBS_SECURE) { |
| 865 | |
| 866 | if (wp->state == WEBS_BEGIN) { |
| 867 | eof = 1; |
| 868 | } else { |
| 869 | eof = websSSLEof(wp->wsp); |
| 870 | } |
| 871 | } else { |
| 872 | eof = socketEof(wp->sid); |
| 873 | } |
| 874 | #else |
| 875 | eof = socketEof(wp->sid); |
| 876 | #endif |
| 877 | |
| 878 | if (eof) { |
| 879 | |
| 880 | if (wp->state == WEBS_POST) { |
| 881 | websUrlHandlerRequest(wp); |
| 882 | } else { |
| 883 | websDone(wp, 0); |
| 884 | } |
| 885 | } else { |
| 886 | trace(8, T("@@@@webs 0x%x 0x%x: websGetInput no eof\n"),wp,wp->sid); |
| 887 | |
| 888 | #if 1//def HP_FIX |
| 889 | websDone(wp, 0); |
| 890 | #endif /*HP_FIX*/ |
| 891 | |
| 892 | } |
| 893 | |
| 894 | #if 0 //def UNUSED |
| 895 | if (wp->state == WEBS_HEADER && ringqLen(&wp->header) <= 0) { |
| 896 | websParseRequest(wp); |
| 897 | websUrlHandlerRequest(wp); |
| 898 | } |
| 899 | #endif |
| 900 | bfreeSafe(B_L,text);//for kw |
| 901 | return -1; |
| 902 | |
| 903 | } else if (nbytes == 0) { |
| 904 | if (wp->state == WEBS_HEADER) { |
| 905 | |
| 906 | if(websParseRequest(wp) != 0){ |
| 907 | return -1; |
| 908 | } |
| 909 | if (wp->flags & WEBS_POST_REQUEST) { |
| 910 | if (wp->flags & WEBS_CLEN) { |
| 911 | wp->state = WEBS_POST_CLEN; |
| 912 | clen = wp->clen; |
| 913 | } else { |
| 914 | wp->state = WEBS_POST; |
| 915 | clen = 1; |
| 916 | } |
| 917 | if (clen > 0) { |
| 918 | |
| 919 | return 0; |
| 920 | } |
| 921 | return 1; |
| 922 | } |
| 923 | |
| 924 | websUrlHandlerRequest(wp); |
| 925 | } |
| 926 | return -1; |
| 927 | } |
| 928 | } |
| 929 | |
| 930 | // if(text == NULL || nbytes <= 0){ // kw 3 nbytes <= 0 already return |
| 931 | if(text == NULL){ |
| 932 | softap_assert("websGetInput 2"); |
| 933 | } |
| 934 | a_assert(text); |
| 935 | a_assert(nbytes > 0); |
| 936 | *ptext = text; |
| 937 | *pnbytes = nbytes; |
| 938 | return 1; |
| 939 | } |
| 940 | |
| 941 | |
| 942 | #define isgoodchar(s) (gisalnum((s)) || ((s) == '/') || ((s) == '_') || \ |
| 943 | ((s) == '.') || ((s) == '-') ) |
| 944 | |
| 945 | static int websParseRequest(webs_t wp) |
| 946 | { |
| 947 | char_t *authType, *upperKey, *cp, *browser, *lp, *key, *value; |
| 948 | int smugglingFlag = 0; |
| 949 | a_assert(websValid(wp)); |
| 950 | |
| 951 | websSetVar(wp, T("HTTP_AUTHORIZATION"), T("")); |
| 952 | |
| 953 | browser = NULL; |
| 954 | char tmp[4] = T(""); |
| 955 | for (lp = (char_t*) wp->header.servp; lp && *lp; ) { |
| 956 | cp = lp; |
| 957 | if ((lp = gstrchr(lp, '\n')) != NULL) { |
| 958 | lp++; |
| 959 | } |
| 960 | |
| 961 | if ((key = gstrtok(cp, T(": \t\n"))) == NULL) { |
| 962 | continue; |
| 963 | } |
| 964 | |
| 965 | if ((value = gstrtok(NULL, T("\n"))) == NULL) { |
| 966 | //value = T(""); |
| 967 | value = tmp;// kw OVERWRITE_CONST_CHAR |
| 968 | } |
| 969 | |
| 970 | while (gisspace(*value)) { |
| 971 | value++; |
| 972 | } |
| 973 | strlower(key); |
| 974 | |
| 975 | fmtAlloc(&upperKey, (gstrlen(key) + 6), T("HTTP_%s"), key); |
| 976 | for (cp = upperKey; *cp; cp++) { |
| 977 | if (*cp == '-') |
| 978 | *cp = '_'; |
| 979 | } |
| 980 | strupper(upperKey); |
| 981 | websSetVar(wp, upperKey, value); |
| 982 | bfree(B_L, upperKey); |
| 983 | |
| 984 | if (gstrcmp(key, T("user-agent")) == 0) { |
| 985 | if (wp->userAgent) |
| 986 | bfree(B_L, wp->userAgent); |
| 987 | wp->userAgent = bstrdup(B_L, value); |
| 988 | |
| 989 | } else if (gstricmp(key, T("authorization")) == 0) { |
| 990 | |
| 991 | authType = bstrdup (B_L, value); |
| 992 | a_assert (authType); |
| 993 | |
| 994 | cp = authType; |
| 995 | while (gisalpha(*cp)) { |
| 996 | cp++; |
| 997 | } |
| 998 | *cp = '\0'; |
| 999 | if (wp->authType) |
| 1000 | bfree(B_L, wp->authType); |
| 1001 | wp->authType = bstrdup(B_L, authType); |
| 1002 | bfree(B_L, authType); |
| 1003 | |
| 1004 | if (gstricmp(wp->authType, T("basic")) == 0) { |
| 1005 | char_t userAuth[FNAMESIZE]; |
| 1006 | |
| 1007 | if ((cp = gstrchr(value, ' ')) != NULL) { |
| 1008 | *cp = '\0'; |
| 1009 | |
| 1010 | bfree(B_L, wp->authType); |
| 1011 | wp->authType = bstrdup(B_L, value); |
| 1012 | websDecode64(userAuth, ++cp, sizeof(userAuth)); |
| 1013 | } else { |
| 1014 | websDecode64(userAuth, value, sizeof(userAuth)); |
| 1015 | } |
| 1016 | |
| 1017 | if ((cp = gstrchr(userAuth, ':')) != NULL) { |
| 1018 | *cp++ = '\0'; |
| 1019 | } |
| 1020 | if (wp->password) |
| 1021 | bfree(B_L, wp->password); |
| 1022 | if (wp->userName) |
| 1023 | bfree(B_L, wp->userName); |
| 1024 | if (cp) { |
| 1025 | wp->userName = bstrdup(B_L, userAuth); |
| 1026 | wp->password = bstrdup(B_L, cp); |
| 1027 | } else { |
| 1028 | wp->userName = bstrdup(B_L, T("")); |
| 1029 | wp->password = bstrdup(B_L, T("")); |
| 1030 | } |
| 1031 | |
| 1032 | wp->flags |= WEBS_AUTH_BASIC; |
| 1033 | } else { |
| 1034 | #ifdef DIGEST_ACCESS_SUPPORT |
| 1035 | |
| 1036 | char_t *np; |
| 1037 | char_t tp; |
| 1038 | char_t *vp; |
| 1039 | char_t *npv; |
| 1040 | char_t tpv; |
| 1041 | |
| 1042 | wp->flags |= WEBS_AUTH_DIGEST; |
| 1043 | |
| 1044 | cp = value; |
| 1045 | while (isgoodchar(*cp)) { |
| 1046 | cp++; |
| 1047 | } |
| 1048 | while (!isgoodchar(*cp)) { |
| 1049 | cp++; |
| 1050 | } |
| 1051 | |
| 1052 | |
| 1053 | vp = gstrchr(cp, '='); |
| 1054 | while (vp) { |
| 1055 | |
| 1056 | np = cp; |
| 1057 | while (isgoodchar(*np)) { |
| 1058 | np++; |
| 1059 | } |
| 1060 | tp = *np; |
| 1061 | *np = 0; |
| 1062 | |
| 1063 | vp++; |
| 1064 | while (!isgoodchar(*vp)) { |
| 1065 | vp++; |
| 1066 | } |
| 1067 | |
| 1068 | npv = vp; |
| 1069 | while (isgoodchar(*npv)) { |
| 1070 | npv++; |
| 1071 | } |
| 1072 | tpv = *npv; |
| 1073 | *npv = 0; |
| 1074 | |
| 1075 | if (gstricmp(cp, T("username")) == 0) { |
| 1076 | wp->userName = bstrdup(B_L, vp); |
| 1077 | } else if (gstricmp(cp, T("response")) == 0) { |
| 1078 | wp->digest = bstrdup(B_L, vp); |
| 1079 | } else if (gstricmp(cp, T("opaque")) == 0) { |
| 1080 | wp->opaque = bstrdup(B_L, vp); |
| 1081 | } else if (gstricmp(cp, T("uri")) == 0) { |
| 1082 | wp->uri = bstrdup(B_L, vp); |
| 1083 | } else if (gstricmp(cp, T("realm")) == 0) { |
| 1084 | wp->realm = bstrdup(B_L, vp); |
| 1085 | } else if (gstricmp(cp, T("nonce")) == 0) { |
| 1086 | wp->nonce = bstrdup(B_L, vp); |
| 1087 | } else if (gstricmp(cp, T("nc")) == 0) { |
| 1088 | wp->nc = bstrdup(B_L, vp); |
| 1089 | } else if (gstricmp(cp, T("cnonce")) == 0) { |
| 1090 | wp->cnonce = bstrdup(B_L, vp); |
| 1091 | } else if (gstricmp(cp, T("qop")) == 0) { |
| 1092 | wp->qop = bstrdup(B_L, vp); |
| 1093 | } |
| 1094 | |
| 1095 | *np = tp; |
| 1096 | *npv = tpv; |
| 1097 | |
| 1098 | cp = npv; |
| 1099 | while (*cp && isgoodchar(*cp)) { |
| 1100 | cp++; |
| 1101 | } |
| 1102 | while (*cp && !isgoodchar(*cp)) { |
| 1103 | cp++; |
| 1104 | } |
| 1105 | |
| 1106 | if (*cp) { |
| 1107 | vp = gstrchr(cp, '='); |
| 1108 | } else { |
| 1109 | vp = NULL; |
| 1110 | } |
| 1111 | } |
| 1112 | #endif /* DIGEST_ACCESS_SUPPORT */ |
| 1113 | } /* if (gstrcmp(wp->authType)) */ |
| 1114 | #ifdef WEBS_SECURITY |
| 1115 | } else if (gstrcmp(key, T("x-http-method")) == 0) { |
| 1116 | printf("websParseRequest: key=%s\n",key); |
| 1117 | websError(wp, 405, T("")); |
| 1118 | return -1; |
| 1119 | } else if (gstrcmp(key, T("x-http-method-override")) == 0) { |
| 1120 | printf("websParseRequest: key=%s\n",key); |
| 1121 | websError(wp, 405, T("")); |
| 1122 | return -1; |
| 1123 | } else if (gstrcmp(key, T("x-method-override")) == 0) { |
| 1124 | printf("websParseRequest: key=%s\n",key); |
| 1125 | websError(wp, 405, T("")); |
| 1126 | return -1; |
| 1127 | } else if (gstrcmp(key, T("transfer-encoding")) == 0) { |
| 1128 | printf("websParseRequest: key=%s\n",key); |
| 1129 | if(smugglingFlag) { |
| 1130 | websError(wp, 403, T("")); |
| 1131 | return -1; |
| 1132 | } |
| 1133 | smugglingFlag = 1; |
| 1134 | #endif |
| 1135 | |
| 1136 | } else if (gstrcmp(key, T("content-length")) == 0) { |
| 1137 | |
| 1138 | #ifdef WEBS_SECURITY |
| 1139 | if(smugglingFlag) { |
| 1140 | websError(wp, 403, T("")); |
| 1141 | return -1; |
| 1142 | } |
| 1143 | smugglingFlag = 1; |
| 1144 | #endif |
| 1145 | wp->clen = gatoi(value); |
| 1146 | if (wp->clen > 0) |
| 1147 | { |
| 1148 | wp->flags |= WEBS_CLEN; |
| 1149 | websSetVar(wp, T("CONTENT_LENGTH"), value); |
| 1150 | } |
| 1151 | else |
| 1152 | { |
| 1153 | wp->clen = 0; |
| 1154 | } |
| 1155 | |
| 1156 | } else if (gstrcmp(key, T("content-type")) == 0) { |
| 1157 | websSetVar(wp, T("CONTENT_TYPE"), value); |
| 1158 | |
| 1159 | #ifdef WEBS_KEEP_ALIVE_SUPPORT |
| 1160 | } else if (gstrcmp(key, T("connection")) == 0) { |
| 1161 | strlower(value); |
| 1162 | if (gstrcmp(value, T("keep-alive")) == 0) { |
| 1163 | wp->flags |= WEBS_KEEP_ALIVE; |
| 1164 | } |
| 1165 | #endif |
| 1166 | |
| 1167 | #ifdef WEBS_PROXY_SUPPORT |
| 1168 | |
| 1169 | } else if (gstrcmp(key, T("pragma")) == 0) { |
| 1170 | char_t tmp[256]; |
| 1171 | gstrncpy(tmp, value, TSZ(tmp)); |
| 1172 | strlower(tmp); |
| 1173 | if (gstrstr(tmp, T("no-cache"))) { |
| 1174 | wp->flags |= WEBS_DONT_USE_CACHE; |
| 1175 | } |
| 1176 | #endif /* WEBS_PROXY_SUPPORT */ |
| 1177 | |
| 1178 | |
| 1179 | } else if (gstrcmp(key, T("cookie")) == 0) { |
| 1180 | wp->flags |= WEBS_COOKIE; |
| 1181 | if (wp->cookie) |
| 1182 | bfree(B_L, wp->cookie); |
| 1183 | wp->cookie = bstrdup(B_L, value); |
| 1184 | } else if (gstrcmp(key, T("referer")) == 0) { |
| 1185 | if (wp->referer) |
| 1186 | bfree(B_L, wp->referer); |
| 1187 | wp->referer = bstrdup(B_L, value); |
| 1188 | |
| 1189 | } |
| 1190 | } |
| 1191 | return 0; |
| 1192 | } |
| 1193 | |
| 1194 | |
| 1195 | int websTestVar(webs_t wp, char_t *var) |
| 1196 | { |
| 1197 | sym_t *sp; |
| 1198 | |
| 1199 | a_assert(websValid(wp)); |
| 1200 | |
| 1201 | if (var == NULL || *var == '\0') { |
| 1202 | return 0; |
| 1203 | } |
| 1204 | |
| 1205 | if ((sp = symLookup(wp->cgiVars, var)) == NULL) { |
| 1206 | return 0; |
| 1207 | } |
| 1208 | return 1; |
| 1209 | } |
| 1210 | |
| 1211 | void websSetVar(webs_t wp, char_t *var, char_t *value) |
| 1212 | { |
| 1213 | value_t v; |
| 1214 | |
| 1215 | a_assert(websValid(wp)); |
| 1216 | |
| 1217 | if (value) { |
| 1218 | v = valueString(value, VALUE_ALLOCATE); |
| 1219 | } else { |
| 1220 | v = valueString(T(""), VALUE_ALLOCATE); |
| 1221 | } |
| 1222 | symEnter(wp->cgiVars, var, v, 0); |
| 1223 | } |
| 1224 | |
| 1225 | |
| 1226 | void websSetEnv(webs_t wp) |
| 1227 | { |
| 1228 | char_t portBuf[8]; |
| 1229 | char_t *keyword, *value, *valCheck, *valNew; |
| 1230 | |
| 1231 | a_assert(websValid(wp)); |
| 1232 | |
| 1233 | websSetVar(wp, T("QUERY_STRING"), wp->query); |
| 1234 | websSetVar(wp, T("GATEWAY_INTERFACE"), T("CGI/1.1")); |
| 1235 | websSetVar(wp, T("SERVER_HOST"), websHost); |
| 1236 | websSetVar(wp, T("SERVER_NAME"), websHost); |
| 1237 | websSetVar(wp, T("SERVER_URL"), websHostUrl); |
| 1238 | websSetVar(wp, T("REMOTE_HOST"), wp->ipaddr); |
| 1239 | websSetVar(wp, T("REMOTE_ADDR"), wp->ipaddr); |
| 1240 | websSetVar(wp, T("PATH_INFO"), wp->path); |
| 1241 | stritoa(websPort, portBuf, sizeof(portBuf)); |
| 1242 | websSetVar(wp, T("SERVER_PORT"), portBuf); |
| 1243 | websSetVar(wp, T("SERVER_ADDR"), websIpaddr); |
| 1244 | fmtAlloc(&value, FNAMESIZE, T("%s/%s"), WEBS_NAME, WEBS_VERSION); |
| 1245 | websSetVar(wp, T("SERVER_SOFTWARE"), value); |
| 1246 | bfreeSafe(B_L, value); |
| 1247 | websSetVar(wp, T("SERVER_PROTOCOL"), wp->protoVersion); |
| 1248 | |
| 1249 | wp->decodedQuery = bstrdup(B_L, wp->query); |
| 1250 | keyword = gstrtok(wp->decodedQuery, T("&")); |
| 1251 | char tmp[4] = T(""); |
| 1252 | while (keyword != NULL) { |
| 1253 | if ((value = gstrchr(keyword, '=')) != NULL) { |
| 1254 | *value++ = '\0'; |
| 1255 | websDecodeUrl(keyword, keyword, gstrlen(keyword)); |
| 1256 | websDecodeUrl(value, value, gstrlen(value)); |
| 1257 | } else { |
| 1258 | //value = T(""); |
| 1259 | value = tmp;// kw OVERWRITE_CONST_CHAR |
| 1260 | } |
| 1261 | |
| 1262 | if (*keyword) { |
| 1263 | |
| 1264 | if ((valCheck = websGetVar(wp, keyword, NULL)) != 0) { |
| 1265 | fmtAlloc(&valNew, 256, T("%s %s"), valCheck, value); |
| 1266 | websSetVar(wp, keyword, valNew); |
| 1267 | bfreeSafe(B_L, valNew); |
| 1268 | } else { |
| 1269 | websSetVar(wp, keyword, value); |
| 1270 | } |
| 1271 | } |
| 1272 | keyword = gstrtok(NULL, T("&")); |
| 1273 | } |
| 1274 | |
| 1275 | #ifdef EMF |
| 1276 | |
| 1277 | websSetEmfEnvironment(wp); |
| 1278 | #endif |
| 1279 | } |
| 1280 | |
| 1281 | |
| 1282 | int websCompareVar(webs_t wp, char_t *var, char_t *value) |
| 1283 | { |
| 1284 | a_assert(websValid(wp)); |
| 1285 | a_assert(var && *var); |
| 1286 | |
| 1287 | if (gstrcmp(value, websGetVar(wp, var, T(" __UNDEF__ "))) == 0) { |
| 1288 | return 1; |
| 1289 | } |
| 1290 | return 0; |
| 1291 | } |
| 1292 | |
| 1293 | char_t *websGetVar(webs_t wp, char_t *var, char_t *defaultGetValue) |
| 1294 | { |
| 1295 | sym_t *sp; |
| 1296 | |
| 1297 | a_assert(websValid(wp)); |
| 1298 | a_assert(var && *var); |
| 1299 | |
| 1300 | if ((sp = symLookup(wp->cgiVars, var)) != NULL) { |
| 1301 | a_assert(sp->content.type == string); |
| 1302 | if (sp->content.value.string) { |
| 1303 | return sp->content.value.string; |
| 1304 | } else { |
| 1305 | return T(""); |
| 1306 | } |
| 1307 | } |
| 1308 | return defaultGetValue; |
| 1309 | } |
| 1310 | |
| 1311 | |
| 1312 | void websResponse(webs_t wp, int code, char_t *message, char_t *redirect) |
| 1313 | { |
| 1314 | char_t *date; |
| 1315 | |
| 1316 | a_assert(websValid(wp)); |
| 1317 | |
| 1318 | wp->flags &= ~WEBS_KEEP_ALIVE; |
| 1319 | |
| 1320 | if ( !(wp->flags & WEBS_HEADER_DONE)) { |
| 1321 | wp->flags |= WEBS_HEADER_DONE; |
| 1322 | |
| 1323 | if (redirect != NULL) { |
| 1324 | websWrite(wp, T("HTTP/1.0 %d %s\r\n"), code, websErrorMsg(code)); |
| 1325 | } else { |
| 1326 | websWrite(wp, T("HTTP/1.1 %d %s\r\n"), code, websErrorMsg(code)); |
| 1327 | } |
| 1328 | |
| 1329 | |
| 1330 | websWrite(wp, T("Server: %s\r\n"), WEBS_NAME); |
| 1331 | |
| 1332 | if ((date = websGetDateString(NULL)) != NULL) { |
| 1333 | websWrite(wp, T("Date: %s\r\n"), date); |
| 1334 | bfree(B_L, date); |
| 1335 | } |
| 1336 | |
| 1337 | if (code == 401) { |
| 1338 | if (!(wp->flags & WEBS_AUTH_DIGEST)) { |
| 1339 | websWrite(wp, T("WWW-Authenticate: Basic realm=\"%s\"\r\n"), |
| 1340 | websGetRealm()); |
| 1341 | #ifdef DIGEST_ACCESS_SUPPORT |
| 1342 | } else { |
| 1343 | char_t *nonce, *opaque; |
| 1344 | |
| 1345 | /* $$$ before... (note commas instead of semicolons...) |
| 1346 | nonce = websCalcNonce(wp), |
| 1347 | opaque = websCalcOpaque(wp), |
| 1348 | $$$ after */ |
| 1349 | nonce = websCalcNonce(wp); |
| 1350 | opaque = websCalcOpaque(wp); |
| 1351 | /* ...$$$ end */ |
| 1352 | websWrite(wp, |
| 1353 | T("WWW-Authenticate: Digest realm=\"%s\", domain=\"%s\",") |
| 1354 | T("qop=\"%s\", nonce=\"%s\", opaque=\"%s\",") |
| 1355 | T("algorithm=\"%s\", stale=\"%s\"\r\n"), |
| 1356 | websGetRealm(), |
| 1357 | websGetHostUrl(), |
| 1358 | T("auth"), |
| 1359 | nonce, |
| 1360 | opaque, T("MD5"), T("FALSE")); |
| 1361 | bfree(B_L, nonce); |
| 1362 | bfree(B_L, opaque); |
| 1363 | #endif |
| 1364 | } |
| 1365 | } |
| 1366 | |
| 1367 | if (wp->flags & WEBS_KEEP_ALIVE) { |
| 1368 | websWrite(wp, T("Connection: keep-alive\r\n")); |
| 1369 | } |
| 1370 | #ifdef WEBINSPECT_FIX |
| 1371 | websWrite(wp, T("X-Frame-Options: SAMEORIGIN\r\n")); |
| 1372 | #endif |
| 1373 | websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n")); |
| 1374 | websWrite(wp, T("Content-Type: text/html\r\n")); |
| 1375 | |
| 1376 | if (redirect) { |
| 1377 | websWrite(wp, T("Location: %s\r\n"), redirect); |
| 1378 | } |
| 1379 | websWrite(wp, T("\r\n")); |
| 1380 | } |
| 1381 | |
| 1382 | |
| 1383 | if ((wp->flags & WEBS_HEAD_REQUEST) == 0 && message && *message) { |
| 1384 | websWrite(wp, T("%s\r\n"), message); |
| 1385 | } |
| 1386 | websDone(wp, code); |
| 1387 | } |
| 1388 | |
| 1389 | void websTimeoutCancel(webs_t wp) |
| 1390 | { |
| 1391 | a_assert(websValid(wp)); |
| 1392 | |
| 1393 | if (wp->timeout >= 0) { |
| 1394 | emfUnschedCallback(wp->timeout); |
| 1395 | wp->timeout = -1; |
| 1396 | } |
| 1397 | } |
| 1398 | |
| 1399 | void websRedirect(webs_t wp, char_t *url) |
| 1400 | { |
| 1401 | char_t *msgbuf, *urlbuf, *redirectFmt; |
| 1402 | |
| 1403 | a_assert(websValid(wp)); |
| 1404 | a_assert(url); |
| 1405 | |
| 1406 | websStats.redirects++; |
| 1407 | msgbuf = urlbuf = NULL; |
| 1408 | |
| 1409 | if (gstrstr(url, T("%0D")) || gstrstr(url, T("%0A")) |
| 1410 | || gstrstr(url, T("%0d")) || gstrstr(url, T("%0a")) |
| 1411 | || gstrstr(url, T("\r")) || gstrstr(url, T("\n"))) { |
| 1412 | printf("[goahead]Redirect injo %s\n",url); |
| 1413 | url = T(ZTE_WEB_PAGE_LOGIN_NAME); |
| 1414 | /*ÓÃÓÚÖØ¶¨ÏòµÄÊäÈë²ÎÊý²»Äܰüº¬»Ø³µºÍ»»ÐÐ×Ö·û£¬ÒÔ·ÀÖ¹HTTPÏìÓ¦²ð·Ö¹¥»÷*/ |
| 1415 | } |
| 1416 | |
| 1417 | |
| 1418 | if (gstrstr(url, T("http://")) == NULL && gstrstr(url, T("https://")) == NULL) { |
| 1419 | if (*url == '/') { |
| 1420 | url++; |
| 1421 | } |
| 1422 | |
| 1423 | //redirectFmt = T("http://%s/%s"); |
| 1424 | |
| 1425 | #ifdef WEBS_SSL_SUPPORT |
| 1426 | //if (wp->flags & WEBS_SECURE) { |
| 1427 | if (websSSLIsOpen()) { |
| 1428 | //redirectFmt = T("https://%s/%s");// kw OVERWRITE_CONST_CHAR |
| 1429 | fmtAlloc(&urlbuf, WEBS_MAX_URL + 80, "https://%s/%s", |
| 1430 | websGetVar(wp, T("HTTP_HOST"), websHostUrl), url); |
| 1431 | } |
| 1432 | else |
| 1433 | #endif |
| 1434 | { |
| 1435 | fmtAlloc(&urlbuf, WEBS_MAX_URL + 80, "http://%s/%s", |
| 1436 | websGetVar(wp, T("HTTP_HOST"), websHostUrl), url); |
| 1437 | } |
| 1438 | url = urlbuf; |
| 1439 | printf("[goahead]Redirect %s\n",url); |
| 1440 | } |
| 1441 | |
| 1442 | |
| 1443 | fmtAlloc(&msgbuf, WEBS_MAX_URL + 80, |
| 1444 | T("<html><head></head><body>\r\n\ |
| 1445 | This document has moved to a new <a href=\"%s\">location</a>.\r\n\ |
| 1446 | Please update your documents to reflect the new location.\r\n\ |
| 1447 | </body></html>\r\n"), url); |
| 1448 | |
| 1449 | websResponse(wp, 302, msgbuf, url); |
| 1450 | |
| 1451 | bfreeSafe(B_L, msgbuf); |
| 1452 | bfreeSafe(B_L, urlbuf); |
| 1453 | } |
| 1454 | |
| 1455 | static int charCount(const char_t* str, char_t ch); |
| 1456 | |
| 1457 | #define kLt '<' |
| 1458 | #define kLessThan T("<") |
| 1459 | #define kGt '>' |
| 1460 | #define kGreaterThan T(">") |
| 1461 | |
| 1462 | static char_t* websSafeUrl(const char_t* url) |
| 1463 | { |
| 1464 | |
| 1465 | int ltCount = charCount(url, kLt); |
| 1466 | int gtCount = charCount(url, kGt); |
| 1467 | int safeLen = 0; |
| 1468 | char_t* safeUrl = NULL; |
| 1469 | char_t* src = NULL; |
| 1470 | char_t* dest = NULL; |
| 1471 | |
| 1472 | if (NULL != url) |
| 1473 | { |
| 1474 | safeLen = gstrlen(url); |
| 1475 | if (ltCount == 0 && gtCount == 0) |
| 1476 | { |
| 1477 | safeUrl = bstrdup(B_L, (char_t*) url); |
| 1478 | } |
| 1479 | else |
| 1480 | { |
| 1481 | safeLen += (ltCount * 4); |
| 1482 | safeLen += (gtCount * 4); |
| 1483 | |
| 1484 | safeUrl = balloc(B_L, safeLen); |
| 1485 | if (safeUrl != NULL) |
| 1486 | { |
| 1487 | src = (char_t*) url; |
| 1488 | dest = safeUrl; |
| 1489 | while (*src) |
| 1490 | { |
| 1491 | if (*src == kLt) |
| 1492 | { |
| 1493 | gstrcpy(dest, kLessThan); |
| 1494 | dest += gstrlen(kLessThan); |
| 1495 | } |
| 1496 | else if (*src == kGt) |
| 1497 | { |
| 1498 | gstrcpy(dest, kGreaterThan); |
| 1499 | dest += gstrlen(kGreaterThan); |
| 1500 | } |
| 1501 | else |
| 1502 | { |
| 1503 | *dest++ = *src; |
| 1504 | } |
| 1505 | ++src; |
| 1506 | } |
| 1507 | /* don't forget to terminate the string...*/ |
| 1508 | *dest = '\0'; |
| 1509 | } |
| 1510 | } |
| 1511 | } |
| 1512 | return safeUrl; |
| 1513 | } |
| 1514 | |
| 1515 | static int charCount(const char_t* str, char_t ch) |
| 1516 | { |
| 1517 | int count = 0; |
| 1518 | char_t* p = (char_t*) str; |
| 1519 | |
| 1520 | if (NULL == str) |
| 1521 | { |
| 1522 | return 0; |
| 1523 | } |
| 1524 | |
| 1525 | while (1) |
| 1526 | { |
| 1527 | p = gstrchr(p, ch); |
| 1528 | if (NULL == p) |
| 1529 | { |
| 1530 | break; |
| 1531 | } |
| 1532 | |
| 1533 | ++count; |
| 1534 | ++p; |
| 1535 | } |
| 1536 | return count; |
| 1537 | } |
| 1538 | |
| 1539 | |
| 1540 | char_t *websErrorMsg(int code) |
| 1541 | { |
| 1542 | websErrorType *ep; |
| 1543 | |
| 1544 | for (ep = websErrors; ep->code; ep++) { |
| 1545 | if (code == ep->code) { |
| 1546 | return ep->msg; |
| 1547 | } |
| 1548 | } |
| 1549 | a_assert(0); |
| 1550 | return T(""); |
| 1551 | } |
| 1552 | |
| 1553 | |
| 1554 | #ifdef qRichErrorPage |
| 1555 | extern int dmfRichError(webs_t wp, int code, char_t* userMsg); |
| 1556 | #endif |
| 1557 | void websError(webs_t wp, int code, char_t *fmt, ...) |
| 1558 | { |
| 1559 | va_list args = {0}; |
| 1560 | char_t *msg, *userMsg, *buf; |
| 1561 | char_t* safeUrl = NULL; |
| 1562 | char_t* safeMsg = NULL; |
| 1563 | #ifdef qRichErrorPage |
| 1564 | static int reEntry = 0; |
| 1565 | int errorOk; |
| 1566 | #endif |
| 1567 | |
| 1568 | a_assert(websValid(wp)); |
| 1569 | a_assert(fmt); |
| 1570 | |
| 1571 | websStats.errors++; |
| 1572 | |
| 1573 | safeUrl = websSafeUrl(wp->url); |
| 1574 | bfreeSafe(B_L, wp->url); |
| 1575 | wp->url = safeUrl; |
| 1576 | |
| 1577 | va_start(args, fmt); |
| 1578 | userMsg = NULL; |
| 1579 | fmtValloc(&userMsg, WEBS_BUFSIZE, fmt, args); |
| 1580 | va_end(args); |
| 1581 | safeMsg = websSafeUrl(userMsg); |
| 1582 | bfreeSafe(B_L, userMsg); |
| 1583 | userMsg = safeMsg; |
| 1584 | safeMsg = NULL; |
| 1585 | |
| 1586 | |
| 1587 | |
| 1588 | #ifdef qRichErrorPage |
| 1589 | if (!reEntry) |
| 1590 | { |
| 1591 | |
| 1592 | reEntry = 1; |
| 1593 | errorOk = dmfRichError(wp, code, userMsg); |
| 1594 | reEntry = 0; |
| 1595 | if (errorOk) |
| 1596 | { |
| 1597 | bfreeSafe(B_L, userMsg); |
| 1598 | return; |
| 1599 | } |
| 1600 | |
| 1601 | } |
| 1602 | |
| 1603 | #endif |
| 1604 | |
| 1605 | /* msg = T("<html><head><title>Document Error: %s</title></head>\r\n\ |
| 1606 | <body><h2>Access Error: %s</h2>\r\n\ |
| 1607 | <p>%s</p></body></html>\r\n");*/ |
| 1608 | // kw OVERWRITE_CONST_CHAR |
| 1609 | |
| 1610 | buf = NULL; |
| 1611 | fmtAlloc(&buf, WEBS_BUFSIZE, "<html><head><title>Document Error: %s</title></head>\r\n\ |
| 1612 | <body><h2>Access Error: %s</h2>\r\n\ |
| 1613 | <p>%s</p></body></html>\r\n", websErrorMsg(code), |
| 1614 | websErrorMsg(code), userMsg); |
| 1615 | |
| 1616 | websResponse(wp, code, buf, NULL); |
| 1617 | bfreeSafe(B_L, buf); |
| 1618 | bfreeSafe(B_L, userMsg); |
| 1619 | } |
| 1620 | |
| 1621 | |
| 1622 | int websWriteBlock(webs_t wp, char_t *buf, int nChars) |
| 1623 | { |
| 1624 | int len, done; |
| 1625 | char *asciiBuf, *pBuf; |
| 1626 | |
| 1627 | a_assert(wp); |
| 1628 | a_assert(websValid(wp)); |
| 1629 | a_assert(buf); |
| 1630 | a_assert(nChars >= 0); |
| 1631 | if(wp == NULL) |
| 1632 | return -1;//for kw |
| 1633 | |
| 1634 | done = len = 0; |
| 1635 | |
| 1636 | pBuf = asciiBuf = ballocUniToAsc(buf, nChars); |
| 1637 | if(asciiBuf == NULL) |
| 1638 | return -1;//for kw |
| 1639 | |
| 1640 | while (nChars > 0) { |
| 1641 | #ifdef WEBS_SSL_SUPPORT |
| 1642 | if (wp->flags & WEBS_SECURE) { |
| 1643 | if ((len = websSSLWrite(wp->wsp, pBuf, nChars)) < 0) { |
| 1644 | bfree(B_L, asciiBuf); |
| 1645 | return -1; |
| 1646 | } |
| 1647 | websSSLFlush(wp->wsp); |
| 1648 | } else { |
| 1649 | if ((len = socketWrite(wp->sid, pBuf, nChars)) < 0) { |
| 1650 | bfree(B_L, asciiBuf); |
| 1651 | return -1; |
| 1652 | } |
| 1653 | socketFlush(wp->sid); |
| 1654 | } |
| 1655 | #else /* ! WEBS_SSL_SUPPORT */ |
| 1656 | if ((len = socketWrite(wp->sid, pBuf, nChars)) < 0) { |
| 1657 | bfree(B_L, asciiBuf); |
| 1658 | return -1; |
| 1659 | } |
| 1660 | socketFlush(wp->sid); |
| 1661 | #endif /* WEBS_SSL_SUPPORT */ |
| 1662 | nChars -= len; |
| 1663 | pBuf += len; |
| 1664 | done += len; |
| 1665 | } |
| 1666 | |
| 1667 | bfree(B_L, asciiBuf); |
| 1668 | return done; |
| 1669 | } |
| 1670 | |
| 1671 | int websWrite(webs_t wp, char_t *fmt, ...) |
| 1672 | { |
| 1673 | va_list vargs = {0}; |
| 1674 | char_t *buf; |
| 1675 | int rc; |
| 1676 | |
| 1677 | a_assert(websValid(wp)); |
| 1678 | |
| 1679 | va_start(vargs, fmt); |
| 1680 | |
| 1681 | buf = NULL; |
| 1682 | rc = 0; |
| 1683 | |
| 1684 | if (fmtValloc(&buf, WEBS_BUFSIZE, fmt, vargs) >= WEBS_BUFSIZE) { |
| 1685 | trace(0, T("webs: websWrite lost data, buffer overflow\n")); |
| 1686 | } |
| 1687 | |
| 1688 | va_end(vargs); |
| 1689 | a_assert(buf); |
| 1690 | if (buf) { |
| 1691 | rc = websWriteBlock(wp, buf, gstrlen(buf)); |
| 1692 | bfree(B_L, buf); |
| 1693 | } |
| 1694 | return rc; |
| 1695 | } |
| 1696 | |
| 1697 | |
| 1698 | void websDecodeUrl(char_t *decoded, char_t *token, int len) |
| 1699 | { |
| 1700 | char_t *ip, *op; |
| 1701 | int num, i, c; |
| 1702 | |
| 1703 | a_assert(decoded); |
| 1704 | a_assert(token); |
| 1705 | |
| 1706 | op = decoded; |
| 1707 | for (ip = token; *ip && len > 0; ip++, op++) { |
| 1708 | if (*ip == '+') { |
| 1709 | *op = ' '; |
| 1710 | } else if (*ip == '%' && gisxdigit(ip[1]) && gisxdigit(ip[2])) { |
| 1711 | |
| 1712 | ip++; |
| 1713 | for (i = 0, num = 0; i < 2; i++, ip++) { |
| 1714 | c = tolower(*ip); |
| 1715 | if (c >= 'a' && c <= 'f') { |
| 1716 | num = (num * 16) + 10 + c - 'a'; |
| 1717 | } else { |
| 1718 | num = (num * 16) + c - '0'; |
| 1719 | } |
| 1720 | } |
| 1721 | *op = (char_t) num; |
| 1722 | ip--; |
| 1723 | |
| 1724 | } else { |
| 1725 | *op = *ip; |
| 1726 | } |
| 1727 | len--; |
| 1728 | } |
| 1729 | *op = '\0'; |
| 1730 | } |
| 1731 | |
| 1732 | int websWriteDataNonBlock(webs_t wp, char *buf, int nChars) |
| 1733 | { |
| 1734 | int r; |
| 1735 | |
| 1736 | a_assert(wp); |
| 1737 | a_assert(websValid(wp)); |
| 1738 | a_assert(buf); |
| 1739 | a_assert(nChars >= 0); |
| 1740 | |
| 1741 | #ifdef WEBS_SSL_SUPPORT |
| 1742 | if (wp->flags & WEBS_SECURE) { |
| 1743 | r = websSSLWrite(wp->wsp, buf, nChars); |
| 1744 | websSSLFlush(wp->wsp); |
| 1745 | } else { |
| 1746 | r = socketWrite(wp->sid, buf, nChars); |
| 1747 | socketFlush(wp->sid); |
| 1748 | } |
| 1749 | #else |
| 1750 | r = socketWrite(wp->sid, buf, nChars); |
| 1751 | socketFlush(wp->sid); |
| 1752 | #endif |
| 1753 | |
| 1754 | return r; |
| 1755 | } |
| 1756 | |
| 1757 | |
| 1758 | void websTimeout(void *arg, int id) |
| 1759 | { |
| 1760 | webs_t wp; |
| 1761 | int delay, tm; |
| 1762 | |
| 1763 | wp = (webs_t) arg; |
| 1764 | a_assert(websValid(wp)); |
| 1765 | |
| 1766 | tm = websGetTimeSinceMark(wp) * 1000; |
| 1767 | trace(8, T("@@websTimeout %d ip:%s url:%s\n"),tm,wp->ipaddr,wp->url); |
| 1768 | if (tm >= WEBS_TIMEOUT) { |
| 1769 | websStats.timeouts++; |
| 1770 | emfUnschedCallback(id); |
| 1771 | |
| 1772 | wp->timeout = -1; |
| 1773 | websDone(wp, 404); |
| 1774 | } else { |
| 1775 | delay = WEBS_TIMEOUT - tm; |
| 1776 | a_assert(delay > 0); |
| 1777 | emfReschedCallback(id, delay); |
| 1778 | } |
| 1779 | } |
| 1780 | |
| 1781 | void websDone(webs_t wp, int code) |
| 1782 | { |
| 1783 | a_assert(websValid(wp)); |
| 1784 | |
| 1785 | socketDeleteHandler(wp->sid); |
| 1786 | |
| 1787 | if (code != 200) { |
| 1788 | wp->flags &= ~WEBS_KEEP_ALIVE; |
| 1789 | } |
| 1790 | |
| 1791 | websPageClose(wp); |
| 1792 | |
| 1793 | #ifdef WEBS_SSL_SUPPORT |
| 1794 | if (wp->flags & WEBS_SECURE) { |
| 1795 | websTimeoutCancel(wp); |
| 1796 | websSSLFlush(wp->wsp); |
| 1797 | socketCloseConnection(wp->sid); |
| 1798 | websFree(wp); |
| 1799 | return; |
| 1800 | } |
| 1801 | #endif |
| 1802 | |
| 1803 | if (wp->flags & WEBS_KEEP_ALIVE) { |
| 1804 | if (socketFlush(wp->sid) == 0) { |
| 1805 | wp->state = WEBS_BEGIN; |
| 1806 | wp->flags |= WEBS_REQUEST_DONE; |
| 1807 | if (wp->header.buf) { |
| 1808 | ringqFlush(&wp->header); |
| 1809 | } |
| 1810 | socketCreateHandler(wp->sid, SOCKET_READABLE, websSocketEvent, |
| 1811 | (int) wp); |
| 1812 | websTimeoutCancel(wp); |
| 1813 | wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, |
| 1814 | (void *) wp); |
| 1815 | return; |
| 1816 | } |
| 1817 | } else { |
| 1818 | websTimeoutCancel(wp); |
| 1819 | socketSetBlock(wp->sid, 1); |
| 1820 | socketFlush(wp->sid); |
| 1821 | socketCloseConnection(wp->sid); |
| 1822 | } |
| 1823 | websFree(wp); |
| 1824 | } |
| 1825 | |
| 1826 | void websFree(webs_t wp) |
| 1827 | { |
| 1828 | a_assert(websValid(wp)); |
| 1829 | |
| 1830 | if (wp->path) |
| 1831 | bfree(B_L, wp->path); |
| 1832 | if (wp->url) |
| 1833 | bfree(B_L, wp->url); |
| 1834 | if (wp->host) |
| 1835 | bfree(B_L, wp->host); |
| 1836 | if (wp->lpath) |
| 1837 | bfree(B_L, wp->lpath); |
| 1838 | if (wp->query) |
| 1839 | bfree(B_L, wp->query); |
| 1840 | if (wp->decodedQuery) |
| 1841 | bfree(B_L, wp->decodedQuery); |
| 1842 | if (wp->authType) |
| 1843 | bfree(B_L, wp->authType); |
| 1844 | if (wp->password) |
| 1845 | bfree(B_L, wp->password); |
| 1846 | if (wp->userName) |
| 1847 | bfree(B_L, wp->userName); |
| 1848 | if (wp->cookie) |
| 1849 | bfree(B_L, wp->cookie); |
| 1850 | if (wp->referer) |
| 1851 | bfree(B_L, wp->referer); |
| 1852 | if (wp->userAgent) |
| 1853 | bfree(B_L, wp->userAgent); |
| 1854 | if (wp->dir) |
| 1855 | bfree(B_L, wp->dir); |
| 1856 | if (wp->protocol) |
| 1857 | bfree(B_L, wp->protocol); |
| 1858 | if (wp->protoVersion) |
| 1859 | bfree(B_L, wp->protoVersion); |
| 1860 | if (wp->cgiStdin) |
| 1861 | bfree(B_L, wp->cgiStdin); |
| 1862 | |
| 1863 | |
| 1864 | #ifdef DIGEST_ACCESS_SUPPORT |
| 1865 | if (wp->realm) |
| 1866 | bfree(B_L, wp->realm); |
| 1867 | if (wp->uri) |
| 1868 | bfree(B_L, wp->uri); |
| 1869 | if (wp->digest) |
| 1870 | bfree(B_L, wp->digest); |
| 1871 | if (wp->opaque) |
| 1872 | bfree(B_L, wp->opaque); |
| 1873 | if (wp->nonce) |
| 1874 | bfree(B_L, wp->nonce); |
| 1875 | if (wp->nc) |
| 1876 | bfree(B_L, wp->nc); |
| 1877 | if (wp->cnonce) |
| 1878 | bfree(B_L, wp->cnonce); |
| 1879 | if (wp->qop) |
| 1880 | bfree(B_L, wp->qop); |
| 1881 | #endif |
| 1882 | #ifdef WEBS_SSL_SUPPORT |
| 1883 | websSSLFree(wp->wsp); |
| 1884 | #endif |
| 1885 | symClose(wp->cgiVars); |
| 1886 | |
| 1887 | if (wp->header.buf) { |
| 1888 | ringqClose(&wp->header); |
| 1889 | } |
| 1890 | |
| 1891 | websMax = hFree((void***) &webs, wp->wid); |
| 1892 | bfree(B_L, wp); |
| 1893 | a_assert(websMax >= 0); |
| 1894 | } |
| 1895 | |
| 1896 | |
| 1897 | int websAlloc(int sid) |
| 1898 | { |
| 1899 | webs_t wp; |
| 1900 | int wid; |
| 1901 | |
| 1902 | if ((wid = hAllocEntry((void***) &webs, &websMax, |
| 1903 | sizeof(struct websRec))) < 0) { |
| 1904 | return -1; |
| 1905 | } |
| 1906 | wp = webs[wid]; |
| 1907 | |
| 1908 | wp->wid = wid; |
| 1909 | wp->sid = sid; |
| 1910 | wp->state = WEBS_BEGIN; |
| 1911 | wp->docfd = -1; |
| 1912 | wp->timeout = -1; |
| 1913 | wp->dir = NULL; |
| 1914 | wp->authType = NULL; |
| 1915 | wp->protocol = NULL; |
| 1916 | wp->protoVersion = NULL; |
| 1917 | wp->password = NULL; |
| 1918 | wp->userName = NULL; |
| 1919 | wp->cookie = NULL; |
| 1920 | wp->referer = NULL; |
| 1921 | wp->has_firmware_upload_clean = 0; |
| 1922 | wp->has_firmware_upload_shell = 0; |
| 1923 | #ifdef DIGEST_ACCESS_SUPPORT |
| 1924 | wp->realm = NULL; |
| 1925 | wp->nonce = NULL; |
| 1926 | wp->digest = NULL; |
| 1927 | wp->uri = NULL; |
| 1928 | wp->opaque = NULL; |
| 1929 | wp->nc = NULL; |
| 1930 | wp->cnonce = NULL; |
| 1931 | wp->qop = NULL; |
| 1932 | #endif |
| 1933 | #ifdef WEBS_SSL_SUPPORT |
| 1934 | wp->wsp = NULL; |
| 1935 | #endif |
| 1936 | |
| 1937 | ringqOpen(&wp->header, WEBS_HEADER_BUFINC, WEBS_MAX_HEADER); |
| 1938 | |
| 1939 | wp->cgiVars = symOpen(WEBS_SYM_INIT); |
| 1940 | |
| 1941 | return wid; |
| 1942 | } |
| 1943 | |
| 1944 | |
| 1945 | char_t *websGetIpaddrUrl() |
| 1946 | { |
| 1947 | return websIpaddrUrl; |
| 1948 | } |
| 1949 | |
| 1950 | |
| 1951 | char_t *websGetHostUrl() |
| 1952 | { |
| 1953 | return websHostUrl; |
| 1954 | } |
| 1955 | |
| 1956 | |
| 1957 | int websGetPort() |
| 1958 | { |
| 1959 | return websPort; |
| 1960 | } |
| 1961 | |
| 1962 | char_t *websGetHost() |
| 1963 | { |
| 1964 | return websHost; |
| 1965 | } |
| 1966 | |
| 1967 | |
| 1968 | int websGetRequestBytes(webs_t wp) |
| 1969 | { |
| 1970 | a_assert(websValid(wp)); |
| 1971 | |
| 1972 | return wp->numbytes; |
| 1973 | } |
| 1974 | |
| 1975 | |
| 1976 | int websGetRequestFlags(webs_t wp) |
| 1977 | { |
| 1978 | a_assert(websValid(wp)); |
| 1979 | |
| 1980 | return wp->flags; |
| 1981 | } |
| 1982 | |
| 1983 | char_t *websGetRequestDir(webs_t wp) |
| 1984 | { |
| 1985 | a_assert(websValid(wp)); |
| 1986 | |
| 1987 | if (wp->dir == NULL) { |
| 1988 | return T(""); |
| 1989 | } |
| 1990 | |
| 1991 | return wp->dir; |
| 1992 | } |
| 1993 | |
| 1994 | |
| 1995 | int websGetSid(webs_t wp) |
| 1996 | { |
| 1997 | a_assert(websValid(wp)); |
| 1998 | |
| 1999 | return wp->sid; |
| 2000 | } |
| 2001 | |
| 2002 | |
| 2003 | char_t *websGetRequestIpaddr(webs_t wp) |
| 2004 | { |
| 2005 | a_assert(websValid(wp)); |
| 2006 | return wp->ipaddr; |
| 2007 | } |
| 2008 | |
| 2009 | |
| 2010 | #ifdef FEATURE_ZTE_WEB_TCARD |
| 2011 | //added by guo shoupeng 10124224 for http share 20111001 start |
| 2012 | char_t * websGetURL(webs_t wp) |
| 2013 | { |
| 2014 | a_assert(websValid(wp)); |
| 2015 | |
| 2016 | return wp->url; |
| 2017 | } |
| 2018 | |
| 2019 | char_t *websGetFileName(webs_t wp) |
| 2020 | { |
| 2021 | a_assert(websValid(wp)); |
| 2022 | |
| 2023 | return wp->cgiStdin; |
| 2024 | } |
| 2025 | |
| 2026 | |
| 2027 | int websGetState(webs_t wp) |
| 2028 | { |
| 2029 | a_assert(websValid(wp)); |
| 2030 | |
| 2031 | return wp->state; |
| 2032 | } |
| 2033 | |
| 2034 | int websGetlen(webs_t wp) |
| 2035 | { |
| 2036 | a_assert(websValid(wp)); |
| 2037 | |
| 2038 | return wp->clen; |
| 2039 | } |
| 2040 | |
| 2041 | //added by guo shoupeng 10124224 for http share 20111001 end |
| 2042 | #endif |
| 2043 | |
| 2044 | |
| 2045 | char_t *websGetRequestLpath(webs_t wp) |
| 2046 | { |
| 2047 | a_assert(websValid(wp)); |
| 2048 | |
| 2049 | return wp->lpath; |
| 2050 | } |
| 2051 | |
| 2052 | |
| 2053 | char_t *websGetRequestPassword(webs_t wp) |
| 2054 | { |
| 2055 | a_assert(websValid(wp)); |
| 2056 | |
| 2057 | return wp->password; |
| 2058 | } |
| 2059 | |
| 2060 | char_t *websGetRequestPath(webs_t wp) |
| 2061 | { |
| 2062 | a_assert(websValid(wp)); |
| 2063 | |
| 2064 | if (wp->path == NULL) { |
| 2065 | return T(""); |
| 2066 | } |
| 2067 | |
| 2068 | return wp->path; |
| 2069 | } |
| 2070 | |
| 2071 | |
| 2072 | char_t *websGetRequestType(webs_t wp) |
| 2073 | { |
| 2074 | a_assert(websValid(wp)); |
| 2075 | |
| 2076 | return wp->type; |
| 2077 | } |
| 2078 | |
| 2079 | |
| 2080 | int websGetRequestWritten(webs_t wp) |
| 2081 | { |
| 2082 | a_assert(websValid(wp)); |
| 2083 | |
| 2084 | return wp->written; |
| 2085 | } |
| 2086 | |
| 2087 | |
| 2088 | char_t *websGetRequestUserName(webs_t wp) |
| 2089 | { |
| 2090 | a_assert(websValid(wp)); |
| 2091 | |
| 2092 | return wp->userName; |
| 2093 | } |
| 2094 | |
| 2095 | void websSetHost(char_t *host) |
| 2096 | { |
| 2097 | gstrncpy(websHost, host, TSZ(websHost)-1); |
| 2098 | } |
| 2099 | |
| 2100 | |
| 2101 | void websSetIpaddr(char_t *ipaddr) |
| 2102 | { |
| 2103 | a_assert(ipaddr && *ipaddr); |
| 2104 | |
| 2105 | gstrncpy(websIpaddr, ipaddr, TSZ(websIpaddr)-1); |
| 2106 | } |
| 2107 | |
| 2108 | void websSetHostUrl(char_t *url) |
| 2109 | { |
| 2110 | a_assert(url && *url); |
| 2111 | |
| 2112 | bfreeSafe(B_L, websHostUrl); |
| 2113 | websHostUrl = gstrdup(B_L, url); |
| 2114 | } |
| 2115 | |
| 2116 | |
| 2117 | void websSetRequestBytes(webs_t wp, int bytes) |
| 2118 | { |
| 2119 | a_assert(websValid(wp)); |
| 2120 | a_assert(bytes >= 0); |
| 2121 | |
| 2122 | wp->numbytes = bytes; |
| 2123 | } |
| 2124 | |
| 2125 | |
| 2126 | void websSetRequestLpath(webs_t wp, char_t *lpath) |
| 2127 | { |
| 2128 | a_assert(websValid(wp)); |
| 2129 | a_assert(lpath && *lpath); |
| 2130 | |
| 2131 | if (wp->lpath) { |
| 2132 | bfree(B_L, wp->lpath); |
| 2133 | } |
| 2134 | wp->lpath = bstrdup(B_L, lpath); |
| 2135 | websSetVar(wp, T("PATH_TRANSLATED"), wp->lpath); |
| 2136 | } |
| 2137 | |
| 2138 | void websSetRequestFlags(webs_t wp, int flags) |
| 2139 | { |
| 2140 | a_assert(websValid(wp)); |
| 2141 | |
| 2142 | wp->flags = flags; |
| 2143 | } |
| 2144 | |
| 2145 | |
| 2146 | void websSetRequestPath(webs_t wp, char_t *dir, char_t *path) |
| 2147 | { |
| 2148 | char_t *tmp; |
| 2149 | |
| 2150 | a_assert(websValid(wp)); |
| 2151 | |
| 2152 | if (dir) { |
| 2153 | tmp = wp->dir; |
| 2154 | wp->dir = bstrdup(B_L, dir); |
| 2155 | if (tmp) { |
| 2156 | bfree(B_L, tmp); |
| 2157 | } |
| 2158 | } |
| 2159 | if (path) { |
| 2160 | tmp = wp->path; |
| 2161 | wp->path = bstrdup(B_L, path); |
| 2162 | websSetVar(wp, T("PATH_INFO"), wp->path); |
| 2163 | if (tmp) { |
| 2164 | bfree(B_L, tmp); |
| 2165 | } |
| 2166 | } |
| 2167 | } |
| 2168 | |
| 2169 | |
| 2170 | void websSetRequestWritten(webs_t wp, int written) |
| 2171 | { |
| 2172 | a_assert(websValid(wp)); |
| 2173 | |
| 2174 | wp->written = written; |
| 2175 | } |
| 2176 | |
| 2177 | |
| 2178 | void websSetRequestSocketHandler(webs_t wp, int mask, void (*fn)(webs_t wp)) |
| 2179 | { |
| 2180 | a_assert(websValid(wp)); |
| 2181 | |
| 2182 | wp->writeSocket = fn; |
| 2183 | socketCreateHandler(wp->sid, SOCKET_WRITABLE, websSocketEvent, (int) wp); |
| 2184 | } |
| 2185 | |
| 2186 | |
| 2187 | char_t *websGetDateString(websStatType *sbuf) |
| 2188 | { |
| 2189 | char_t* cp, *r; |
| 2190 | time_t now; |
| 2191 | |
| 2192 | if (sbuf == NULL) { |
| 2193 | time(&now); |
| 2194 | } else { |
| 2195 | now = sbuf->mtime; |
| 2196 | } |
| 2197 | if ((cp = gctime(&now)) != NULL) { |
| 2198 | cp[gstrlen(cp) - 1] = '\0'; |
| 2199 | r = bstrdup(B_L, cp); |
| 2200 | return r; |
| 2201 | } |
| 2202 | return NULL; |
| 2203 | } |
| 2204 | |
| 2205 | |
| 2206 | int websValid(webs_t wp) |
| 2207 | { |
| 2208 | int wid; |
| 2209 | |
| 2210 | for (wid = 0; wid < websMax; wid++) { |
| 2211 | if (wp == webs[wid]) { |
| 2212 | return 1; |
| 2213 | } |
| 2214 | } |
| 2215 | return 0; |
| 2216 | } |
| 2217 | |
| 2218 | |
| 2219 | void websSetTimeMark(webs_t wp) |
| 2220 | { |
| 2221 | wp->timestamp = get_sys_uptime(); |
| 2222 | } |
| 2223 | |
| 2224 | |
| 2225 | void websSetRealm(char_t *realmName) |
| 2226 | { |
| 2227 | a_assert(realmName); |
| 2228 | |
| 2229 | gstrncpy(websRealm, realmName, TSZ(websRealm)-1); |
| 2230 | } |
| 2231 | |
| 2232 | |
| 2233 | char_t *websGetRealm() |
| 2234 | { |
| 2235 | return websRealm; |
| 2236 | } |
| 2237 | |
| 2238 | |
| 2239 | static int websGetTimeSinceMark(webs_t wp) |
| 2240 | { |
| 2241 | return get_sys_uptime() - wp->timestamp; |
| 2242 | } |
| 2243 | |
| 2244 | void websSetLoginTimemark(webs_t wp) |
| 2245 | { |
| 2246 | |
| 2247 | char_t login_timemark[64] = {0}; |
| 2248 | char_t login_info[20] = {0}; |
| 2249 | char_t nv_ipaddr[40] = {0}; |
| 2250 | char_t *ip_address = NULL; |
| 2251 | zte_topsw_state_e_type status = ZTE_NVIO_MAX; |
| 2252 | long timemark = 0; |
| 2253 | char_t user_login_timemark[64] = {0}; |
| 2254 | long timemark_check = 0; |
| 2255 | long luser_login_timemark = 0; |
| 2256 | |
| 2257 | |
| 2258 | status = zte_web_read(NV_LOGINFO, login_info); |
| 2259 | |
| 2260 | if(0 == strcmp(login_info,"ok")) |
| 2261 | { |
| 2262 | |
| 2263 | zte_web_read("user_login_timemark", user_login_timemark); |
| 2264 | |
| 2265 | luser_login_timemark = atol(user_login_timemark); |
| 2266 | if(luser_login_timemark < 0 || luser_login_timemark > LONG_MAX-1){ |
| 2267 | luser_login_timemark = LONG_MAX; |
| 2268 | } |
| 2269 | |
| 2270 | timemark_check = time(0) - luser_login_timemark; |
| 2271 | if(timemark_check > LOGIN_TIMEOUT) |
| 2272 | { |
| 2273 | (void)zte_web_write(NV_USER_IP_ADDR,""); |
| 2274 | (void)zte_web_write(NV_LOGINFO,"timeout"); |
| 2275 | (void)zte_web_write(NV_COOKIE_ID, ""); |
| 2276 | (void)zte_web_write(NV_USER_LOGIN_TIMEMARK,"0"); |
xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 2277 | slog(MISC_PRINT,SLOG_ERR,"mgmt_login_timemark_check: the login is timeout .\n"); |
lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 2278 | } |
| 2279 | else |
| 2280 | { |
| 2281 | ip_address = websGetRequestIpaddr(wp); |
| 2282 | #if 0 // kw 3 INVARIANT_CONDITION.UNREACH wp->ipaddr is array, address can not be null |
| 2283 | if (NULL == ip_address) |
| 2284 | { |
| 2285 | slog(MISC_PRINT,SLOG_ERR,"websSetLoginTimemark: ip_address is null.\n"); |
| 2286 | return ; |
| 2287 | } |
| 2288 | #endif |
| 2289 | zte_web_read(NV_USER_IP_ADDR, nv_ipaddr); |
| 2290 | |
| 2291 | |
| 2292 | if (0 == strcmp(ip_address,nv_ipaddr)) |
| 2293 | { |
| 2294 | timemark = time(0); |
| 2295 | sprintf(login_timemark,"%ld",timemark); |
| 2296 | (void)zte_web_write(NV_USER_LOGIN_TIMEMARK, login_timemark); |
| 2297 | } |
| 2298 | |
| 2299 | } |
| 2300 | } |
| 2301 | |
| 2302 | } |
| 2303 | |