void requestHandler(void *s) { SOCKET sock = *((SOCKET*)s); char recvBuf[MAX_HEADER_SIZE + 8]; char pool[512]; static const char *skipBrake = " \n\n:\n\n"; ExHttp httpInfo; ++ExContext.threadCnt; httpInfo.sock = sock; ex_mpool_init(&httpInfo.mp, pool, sizeof(pool)); do { if (ExContext.quitFlag == 1) break; httpInfo.recvLen = ex_read_head(sock, recvBuf, MAX_HEADER_SIZE); if (httpInfo.recvLen <= 0) break; httpInfo.curPos = recvBuf; recvBuf[httpInfo.recvLen] = '\0'; strcat(recvBuf + httpInfo.recvLen , skipBrake); /* if method is not implemented */ if (checkmethod(&httpInfo) < 0) { DBG("len: %d %s\n", httpInfo.method); ex_error_reply(&httpInfo, 501); break; } if (parseURL(&httpInfo) < 0) { ex_error_reply(&httpInfo, 400); errorLog(&httpInfo, "parseURL error"); break; } /* if parse head error */ if (parseHeader(&httpInfo) < 0) { ex_error_reply(&httpInfo, 400); /* bad Request */ errorLog(&httpInfo, "parse head error"); clearHttp(&httpInfo); break; } /* if reply error */ if (replyHandler(&httpInfo) < 0) { break; } } while (1); closesocket(sock); --ExContext.threadCnt; }
int parseRequest(const char * requeststr,struct requestHeader * header) { /* The format of Request(RFC2616) Request = Request-Line ; Section 5.1 *(( general-header ; Section 4.5 | request-header ; Section 5.3 | entity-header ) CRLF) ; Section 7.1 CRLF [ message-body ] ; Section 4.3 general-header = Cache-Control ; Section 14.9 | Connection ; Section 14.10 | Date ; Section 14.18 | Pragma ; Section 14.32 | Trailer ; Section 14.40 | Transfer-Encoding ; Section 14.41 | Upgrade ; Section 14.42 | Via ; Section 14.45 | Warning ; Section 14.46 request-header = Accept ; Section 14.1 | Accept-Charset ; Section 14.2 | Accept-Encoding ; Section 14.3 | Accept-Language ; Section 14.4 | Authorization ; Section 14.8 | Expect ; Section 14.20 | From ; Section 14.22 | Host ; Section 14.23 | If-Match ; Section 14.24 | If-Modified-Since ; Section 14.25 | If-None-Match ; Section 14.26 | If-Range ; Section 14.27 | If-Unmodified-Since ; Section 14.28 | Max-Forwards ; Section 14.31 | Proxy-Authorization ; Section 14.34 | Range ; Section 14.35 | Referer ; Section 14.36 | TE ; Section 14.39 | User-Agent ; Section 14.43 Request-Line = Method SP Request-URI SP HTTP-Version CRLF Method = "OPTIONS" ; Section 9.2 | "GET" ; Section 9.3 | "HEAD" ; Section 9.4 | "POST" ; Section 9.5 | "PUT" ; Section 9.6 | "DELETE" ; Section 9.7 | "TRACE" ; Section 9.8 | "CONNECT" ; Section 9.9 | extension-method extension-method = token Request-URI = "*" | absoluteURI | abs_path | authority */ char * line, * split, * headend, * hostptr; char optionkey[SHORTSTRLEN]; char optionval[SHORTSTRLEN]; int portlen; if(requeststr == NULL || header == NULL) return -1; headend = strstr(requeststr, "\r\n\r\n"); if(headend == NULL) return -1; if(sscanf(requeststr,"%s%s%s",header->method,header->uri,header->version) != 3){ printf("invalid http header!\n"); return HTTP_INVALID_HEADER; } if(checkmethod(header->method) != 0){ printf("unsupport http method.\n"); return HTTP_UNSUPPORT_METHOD; } if((line = strstr(requeststr,"\r\n")) == NULL) return -1; else line += 2; hostptr = strstr(line, "Host:"); if(hostptr == NULL) { printf("invalid http header!\n"); return HTTP_INVALID_HEADER; } if(sscanf(hostptr,"%s%s",optionkey,header->host) != 2){ printf("invalid http header!\n"); return HTTP_INVALID_HEADER; } if((split = strchr(header->host, ':')) != NULL){ header->port = atoi(split + 1); *split = '\0'; } else header->port = DEFHTTPPORT; header->length = headend - requeststr + 4; if(strcasecmp(header->method, "POST") == 0){ if((line = (char *)strcasestr(requeststr,"Content-Length")) != NULL){ if(sscanf(line,"%s%s",optionkey, optionval) != 2){ printf("invalid http header!\n"); return HTTP_INVALID_HEADER; } header->length += atoi(optionval); } } header->parsePass = 1; return 0; }
void requestHandler(void * s) { SOCKET sock = ( SOCKET ) s ; char recvBuf[MAX_HEADER_SIZE] ; char pool[512] ; /* int recvlen ; */ ExHttp httpInfo ; ++ExContext.threadCnt ; httpInfo.sock = sock ; ex_mpool_init( &httpInfo.mp, pool, sizeof (pool) ) ; do { if ( ExContext.quitFlag ) break ; httpInfo.recvLen = ex_read_head( sock, recvBuf, MAX_HEADER_SIZE ) ; if ( httpInfo.recvLen<=0 ) break ; httpInfo.curPos = recvBuf ; recvBuf[httpInfo.recvLen] = '\0' ; printf( "%s", recvBuf ) ; // strcat(recvBuf + httpInfo.recvLen , skipBrake); /* if method is not implemented */ if ( checkmethod( &httpInfo )<0 ) { DBG( "len: %s", httpInfo.method ) ; ex_error_reply( &httpInfo, 400 ) ; errorLog( &httpInfo, "parseURL error" ) ; break ; // ex_error_reply( &httpInfo, 501 ) ; // break ; } if ( parseURL( &httpInfo )<0 ) { DBG( "url: %s protocol %s", httpInfo.url, httpInfo.protocol ) ; ex_error_reply( &httpInfo, 400 ) ; errorLog( &httpInfo, "parseURL error" ) ; break ; } if ( strcmp( httpInfo.protocol, "HTTP/1.1" )!=0 ) { ex_error_reply( &httpInfo, 505 ) ; errorLog( &httpInfo, "HTTP Version Not Supported" ) ; break ; } /* if parse head error */ if ( parseHeader( &httpInfo )<0 ) { ex_error_reply( &httpInfo, 400 ) ; /* bad Request */ errorLog( &httpInfo, "parse head error" ) ; clearHttp( &httpInfo ) ; break ; } if ( strcmp( httpInfo.url, "/index.jsp" )==0 ) { ex_error_reply( &httpInfo, 301 ) ; const char * method = httpInfo.method ; char * message = "Location: http://127.0.0.1/index.html" ; size_t size = strlen( message ) ; if ( *method=='G'|| *method=='H' ) { ex_sock_nwrite( httpInfo.sock, message, size ) ; } errorLog( &httpInfo, "Moved Permanently" ) ; break ; } /* if reply error */ if ( replyHandler( &httpInfo )<0 ) { break ; } } while ( 1 ) ; closesocket( sock ) ; --ExContext.threadCnt ; }