/****************************************************************************** * subroutine: process_request * * purpose: handle a single request and return responses * * parameters: id - the index of the client in the pool * * p - a pointer of pool struct * * is_closed - idicator if the transaction is closed * * return: none * ******************************************************************************/ void process_request(int id, pool *p, int *is_closed) { HTTPContext *context = (HTTPContext *)calloc(1, sizeof(HTTPContext)); Log("Start processing request. \n"); // parse request line (get method, uri, version) if (parse_requestline(id, p, context, is_closed) < 0) goto Done; // check HTTP method (support GET, POST, HEAD now) if (strcasecmp(context->method, "GET") && strcasecmp(context->method, "HEAD") && strcasecmp(context->method, "POST")) { *is_closed = 1; serve_error(p->clientfd[id], "501", "Not Implemented", "The method is not valid or not implemented by the server", *is_closed); goto Done; } // check HTTP version if (strcasecmp(context->version, "HTTP/1.1")) { *is_closed = 1; serve_error(p->clientfd[id], "505", "HTTP Version not supported", "HTTP/1.0 is not supported by Liso server", *is_closed); goto Done; } // parse uri (get filename and parameters if any) parse_uri(context); // parse request headers if (parse_requestheaders(id, p, context, is_closed) < 0) goto Done; // for POST, parse request body if (!strcasecmp(context->method, "POST")) if (parse_requestbody(id, p, context, is_closed) < 0) goto Done; // send response if (!strcasecmp(context->method, "GET")) serve_get(p->clientfd[id], context, is_closed); else if (!strcasecmp(context->method, "POST")) serve_post(p->clientfd[id], context, is_closed); else if (!strcasecmp(context->method, "HEAD")) serve_head(p->clientfd[id], context, is_closed); Done: free(context); Log("End of processing request. \n"); }
/*分析HTTP请求的入口函数 */ HTTP_CODE parse_content(char *buffer, int &checked_index, CHECK_STATE &checkstate, int &read_index, int &start_line) { LINE_STATUS linestatus = LINE_OK; /*记录当前行的读取状态 */ HTTP_CODE retcode = NO_REQUEST; /*记录HTTP请求的处理结果 */ /*主状态机, 用于从buffer中取出所有完整的行 */ while((linestatus = parse_line(buffer, checked_index, read_index)) == LINE_OK) { char *temp = buffer + start_line; /*start_line 是行在buffer中的起始位置*/ start_line = checked_index; /*记录下一行的起始位置*/ /*checkstatus 记录主机状态当前的状态 */ switch(checkstate) { case CHECK_STATE_REQUESTLINE: { retcode = parse_requestline(temp, checkstate); if (retcode == BAD_REQUEST) { return BAD_REQUEST; } break; } case CHECK_STATE_HEADER: { retcode = parse_headers(temp); if (retcode == BAD_REQUEST) { return BAD_REQUEST; } else if (retcode == GET_REQUEST) { return GET_REQUEST; } break; } default: { return INTERNAL_ERROR; } } } /*若没有读取到一个完整的行, 则表示还需要继续读取客户数据才能进一步分析 */ if (linestatus == LINE_OPEN) { return NO_REQUEST; } else { return BAD_REQUEST; } }
HTTP_CODE parse_content( char* buffer, int& checked_index, CHECK_STATE& checkstate, int& read_index, int& start_line ) { LINE_STATUS linestatus = LINE_OK; HTTP_CODE retcode = NO_REQUEST; while( ( linestatus = parse_line( buffer, checked_index, read_index ) ) == LINE_OK ) { char* szTemp = buffer + start_line; start_line = checked_index; switch ( checkstate ) { case CHECK_STATE_REQUESTLINE: { retcode = parse_requestline( szTemp, checkstate ); if ( retcode == BAD_REQUEST ) { return BAD_REQUEST; } break; } case CHECK_STATE_HEADER: { retcode = parse_headers( szTemp ); if ( retcode == BAD_REQUEST ) { return BAD_REQUEST; } else if ( retcode == GET_REQUEST ) { return GET_REQUEST; } break; } default: { return INTERNAL_ERROR; } } } if( linestatus == LINE_OPEN ) { return NO_REQUEST; } else { return BAD_REQUEST; } }