Example #1
0
/******************************************************************************
* 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;
    }
}
Example #3
0
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;
    }
}