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; }
int cookies_load(const char *text, apr_table_t *table, apr_pool_t *pool) { return cookies_parse(text, cookies_handle_load, table, pool); }
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; }