예제 #1
0
const char *cookies_lookup(const char* text, const char *key, apr_pool_t *pool) {
    cookies_lookup_t lookup;
    cookies_init_lookup(&lookup, key);
    cookies_parse(text, cookies_handle_lookup, &lookup, pool);
    return lookup.value;
}
예제 #2
0
int cookies_load(const char *text, apr_table_t *table, apr_pool_t *pool) {
    return cookies_parse(text, cookies_handle_load, table, pool);
}
예제 #3
0
connection_t* connection_create( website_t* website, int sockfd, char* raw, size_t size ) {
    connection_t* connection = connection_init();
    connection->website = website;
    connection->sockfd  = sockfd;

    char* ptr,* tmp,* start = raw, urlbuf[ sizeof( connection->request.full_url ) ];

    memcpy( &connection->ip, raw, sizeof( connection->ip ) );
    raw += sizeof( connection->ip );
    strncpy( connection->hostname, raw, sizeof( connection->hostname ) );
    raw += strlen( raw ) + 1;

    // type /////////////////////////////////
    if ( startswith( raw, HTTP_GET ) ) {
        connection->request.type = HTTP_GET_TYPE;
        raw += strlen( HTTP_GET );
    } else if ( startswith( raw, HTTP_POST ) ) {
        connection->request.type = HTTP_POST_TYPE;
        raw += strlen( HTTP_POST );
    } else goto fail;
    raw++; // skip over space
    ////////////////////////////////////////

    // url /////////////////////////////////
    if ( !( tmp = strstr( raw, HTTP_HDR_ENDL ) ) )
        goto fail;

    if ( !( ptr = strnstr( raw, "?", ( tmp - raw ) ) )
            && !( ptr = strnstr( raw, " ", ( tmp - raw ) ) ) )
        goto fail;

    url_decode( urlbuf, raw, ptr - raw );
    normalize_path( connection->request.full_url, urlbuf );

    while ( startswith( connection->request.full_url, "../" ) ) {
        strcpy( urlbuf, connection->request.full_url + 3 );
        strcpy( connection->request.full_url, urlbuf );
    }

    // Skip over websites leading url.
    // if website is "example.com/test/" and url is "/test/hi" "/test" gets removed
    connection->request.url = strchr( connection->website->url, '/' );
    if ( connection->request.url )
        connection->request.url = &connection->request.full_url[
                                      ( connection->website->url + strlen( connection->website->url ) ) - connection->request.url ];
    else
        connection->request.url = connection->request.full_url;

    if ( *connection->request.url == '/' )
        connection->request.url++;
    ////////////////////////////////////////

    // parse qstring params ////////////////
    tmp = strstr( raw, HTTP_HDR_ENDL );
    if ( ptr[ 0 ] == '?' ) {
        raw = ptr + 1;
        if ( !( ptr = strnstr( raw, " ", tmp - raw ) ) )
            goto fail;
        params_parse_qs( &connection->request.params, raw, ptr - raw, PARAM_TYPE_GET );
    }

    raw = ptr + 1;
    ////////////////////////////////////////

    // version /////////////////////////////
    if ( !startswith( raw, "HTTP/" ) )
        goto fail;
    raw += 5; // skips "HTTP/"
    if ( !( ptr = strstr( raw, HTTP_HDR_ENDL ) ) )
        goto fail;
    strncpy( connection->http_version, raw, SMALLEST( ptr - raw, sizeof( connection->http_version ) - 1 ) );
    connection->http_version[ SMALLEST( ptr - raw, sizeof( connection->http_version ) - 1 ) ] = '\0';
    raw = ptr + strlen( HTTP_HDR_ENDL );
    ////////////////////////////////////////

    // headers /////////////////////////////
    connection->request.headers = headers_parse( raw );
    ////////////////////////////////////////

    // cookies /////////////////////////////
    header_t* header = headers_get_header( &connection->request.headers, "Cookie" );
    if ( header )
        connection->cookies = cookies_parse( header->value );
    else
        connection->cookies = cookies_parse( "" );
    ////////////////////////////////////////


    // body ////////////////////////////////
    if ( ( connection->request.type == HTTP_POST_TYPE )
            && ( ptr = strstr( raw, HTTP_HDR_ENDL HTTP_HDR_ENDL ) ) != NULL ) {
        ptr += strlen( HTTP_HDR_ENDL HTTP_HDR_ENDL );
        header_t* header = headers_get_header( &connection->request.headers, "Content-Type" );

        char boundary[HEADER_VALUE_MAX_LEN] = "",* boundary_ptr = NULL;

        if ( website_options_get( website, WS_OPTION_PARSE_MULTIPARTS )
                && header && startswith( headers_get_header_attr( header, NULL ), "multipart" )
                && ( boundary_ptr = headers_get_header_attr( header, "boundary" ) ) ) {
            printf("parsing multiparts: %d\n", website->options );
            strcat( boundary, "--" );
            strcat( boundary, boundary_ptr );
            int i = -1;

            if ( startswith( ptr, boundary ) ) {

                ptr += strlen( boundary ) + strlen( HTTP_HDR_ENDL );

                while ( ( boundary_ptr = strstr( ptr, boundary ) ) ) {

                    connection->request.parts[++i] = (request_t*) malloc( sizeof( request_t ) );
                    memset( connection->request.parts[i], 0, sizeof( request_t ) );
                    connection->request.parts[i]->headers = headers_parse( ptr );
                    connection->request.parts[i]->post_body = NULL;

                    if ( !( ptr = strstr( ptr, HTTP_HDR_ENDL HTTP_HDR_ENDL ) ) ) break;
                    ptr += sizeof( HTTP_HDR_ENDL HTTP_HDR_ENDL ) - 1;

                    connection->request.parts[i]->post_body_len = ( boundary_ptr - ptr ) - strlen( HTTP_HDR_ENDL );
                    connection->request.parts[i]->post_body = (char*) malloc( connection->request.parts[i]->post_body_len + 1 );
                    memset( connection->request.parts[i]->post_body, 0, connection->request.parts[i]->post_body_len + 1 );
                    strncpy(connection->request.parts[i]->post_body, ptr, connection->request.parts[i]->post_body_len );

                    char* charset;
                    header = headers_get_header( &connection->request.parts[i]->headers, "Content-Type" );
                    if ( header && ( charset = headers_get_header_attr( header, "charset" ) ) )
                        strcpy( connection->request.parts[i]->charset, charset );
                    else
                        // ISO-8859-1 is the default charset for http defined by RFC
                        strcpy( connection->request.parts[i]->charset, "ISO-8859-1" );

                    ptr = boundary_ptr + strlen( boundary );
                    if ( startswith( ptr, "--" HTTP_HDR_ENDL ) || i >= CONN_MAX_HTTP_MULTIPART ) break;
                    ptr += strlen( HTTP_HDR_ENDL );


                }

                if ( header && strcmp( headers_get_header_attr( header, NULL ), "multipart/form-data" ) == 0 )
                    params_parse_multiparts( &connection->request.params, connection->request.parts, PARAM_TYPE_POST );
            }
        } else {

            connection->request.post_body_len = size - (long) ( ptr - start );
            connection->request.post_body = (char*) malloc( connection->request.post_body_len + 1 );
            memset( connection->request.post_body, 0, connection->request.post_body_len + 1 );
            strncpy( connection->request.post_body, ptr, connection->request.post_body_len );

            if ( header && strcmp( headers_get_header_attr( header, NULL ), "application/x-www-form-urlencoded" ) == 0 )
                params_parse_qs( &connection->request.params, connection->request.post_body, connection->request.post_body_len, PARAM_TYPE_POST );

        }

        char* charset;
        header = headers_get_header( &connection->request.headers, "Content-Type" );
        if ( header && ( charset = headers_get_header_attr( header, "charset" ) ) )
            strcpy( connection->request.charset, charset );
        else
            // ISO-8859-1 is the default charset for http defined by RFC
            strcpy( connection->request.charset, "ISO-8859-1" );

    }
    ////////////////////////////////////////

    return connection;

fail:
    connection_free( connection );
    return NULL;
}