@ -2173,6 +2173,20 @@ pause_chunk_complete_cb (http_parser *p)
return chunk_complete_cb ( p ) ;
}
int
connect_headers_complete_cb ( http_parser * p )
{
headers_complete_cb ( p ) ;
return 1 ;
}
int
connect_message_complete_cb ( http_parser * p )
{
messages [ num_messages ] . should_keep_alive = http_should_keep_alive ( parser ) ;
return message_complete_cb ( p ) ;
}
static http_parser_settings settings_pause =
{ . on_message_begin = pause_message_begin_cb
, . on_header_field = pause_header_field_cb
@ -2212,6 +2226,19 @@ static http_parser_settings settings_count_body =
, . on_chunk_complete = chunk_complete_cb
} ;
static http_parser_settings settings_connect =
{ . on_message_begin = message_begin_cb
, . on_header_field = header_field_cb
, . on_header_value = header_value_cb
, . on_url = request_url_cb
, . on_status = response_status_cb
, . on_body = dontcall_body_cb
, . on_headers_complete = connect_headers_complete_cb
, . on_message_complete = connect_message_complete_cb
, . on_chunk_header = chunk_header_cb
, . on_chunk_complete = chunk_complete_cb
} ;
static http_parser_settings settings_null =
{ . on_message_begin = 0
, . on_header_field = 0
@ -2275,6 +2302,14 @@ size_t parse_pause (const char *buf, size_t len)
return nparsed ;
}
size_t parse_connect ( const char * buf , size_t len )
{
size_t nparsed ;
currently_parsing_eof = ( len = = 0 ) ;
nparsed = http_parser_execute ( parser , & settings_connect , buf , len ) ;
return nparsed ;
}
static inline int
check_str_eq ( const struct message * m ,
const char * prop ,
@ -2331,7 +2366,7 @@ do { \
} while ( 0 )
int
message_eq ( int index , const struct message * expected )
message_eq ( int index , int connect , const struct message * expected )
{
int i ;
struct message * m = & messages [ index ] ;
@ -2346,8 +2381,10 @@ message_eq (int index, const struct message *expected)
MESSAGE_CHECK_STR_EQ ( expected , m , response_status ) ;
}
MESSAGE_CHECK_NUM_EQ ( expected , m , should_keep_alive ) ;
MESSAGE_CHECK_NUM_EQ ( expected , m , message_complete_on_eof ) ;
if ( ! connect ) {
MESSAGE_CHECK_NUM_EQ ( expected , m , should_keep_alive ) ;
MESSAGE_CHECK_NUM_EQ ( expected , m , message_complete_on_eof ) ;
}
assert ( m - > message_begin_cb_called ) ;
assert ( m - > headers_complete_cb_called ) ;
@ -2385,16 +2422,22 @@ message_eq (int index, const struct message *expected)
MESSAGE_CHECK_NUM_EQ ( expected , m , port ) ;
}
if ( expected - > body_size ) {
if ( connect ) {
check_num_eq ( m , " body_size " , 0 , m - > body_size ) ;
} else if ( expected - > body_size ) {
MESSAGE_CHECK_NUM_EQ ( expected , m , body_size ) ;
} else {
MESSAGE_CHECK_STR_EQ ( expected , m , body ) ;
}
assert ( m - > num_chunks = = m - > num_chunks_complete ) ;
MESSAGE_CHECK_NUM_EQ ( expected , m , num_chunks_complete ) ;
for ( i = 0 ; i < m - > num_chunks & & i < MAX_CHUNKS ; i + + ) {
MESSAGE_CHECK_NUM_EQ ( expected , m , chunk_lengths [ i ] ) ;
if ( connect ) {
check_num_eq ( m , " num_chunks_complete " , 0 , m - > num_chunks_complete ) ;
} else {
assert ( m - > num_chunks = = m - > num_chunks_complete ) ;
MESSAGE_CHECK_NUM_EQ ( expected , m , num_chunks_complete ) ;
for ( i = 0 ; i < m - > num_chunks & & i < MAX_CHUNKS ; i + + ) {
MESSAGE_CHECK_NUM_EQ ( expected , m , chunk_lengths [ i ] ) ;
}
}
MESSAGE_CHECK_NUM_EQ ( expected , m , num_headers ) ;
@ -3201,7 +3244,7 @@ test_message (const struct message *message)
abort ( ) ;
}
if ( ! message_eq ( 0 , message ) ) abort ( ) ;
if ( ! message_eq ( 0 , 0 , message ) ) abort ( ) ;
parser_free ( ) ;
}
@ -3238,7 +3281,7 @@ test_message_count_body (const struct message *message)
abort ( ) ;
}
if ( ! message_eq ( 0 , message ) ) abort ( ) ;
if ( ! message_eq ( 0 , 0 , message ) ) abort ( ) ;
parser_free ( ) ;
}
@ -3589,9 +3632,9 @@ test:
abort ( ) ;
}
if ( ! message_eq ( 0 , r1 ) ) abort ( ) ;
if ( message_count > 1 & & ! message_eq ( 1 , r2 ) ) abort ( ) ;
if ( message_count > 2 & & ! message_eq ( 2 , r3 ) ) abort ( ) ;
if ( ! message_eq ( 0 , 0 , r1 ) ) abort ( ) ;
if ( message_count > 1 & & ! message_eq ( 1 , 0 , r2 ) ) abort ( ) ;
if ( message_count > 2 & & ! message_eq ( 2 , 0 , r3 ) ) abort ( ) ;
parser_free ( ) ;
}
@ -3687,17 +3730,17 @@ test:
goto error ;
}
if ( ! message_eq ( 0 , r1 ) ) {
if ( ! message_eq ( 0 , 0 , r1 ) ) {
fprintf ( stderr , " \n \n Error matching messages[0] in test_scan. \n " ) ;
goto error ;
}
if ( message_count > 1 & & ! message_eq ( 1 , r2 ) ) {
if ( message_count > 1 & & ! message_eq ( 1 , 0 , r2 ) ) {
fprintf ( stderr , " \n \n Error matching messages[1] in test_scan. \n " ) ;
goto error ;
}
if ( message_count > 2 & & ! message_eq ( 2 , r3 ) ) {
if ( message_count > 2 & & ! message_eq ( 2 , 0 , r3 ) ) {
fprintf ( stderr , " \n \n Error matching messages[2] in test_scan. \n " ) ;
goto error ;
}
@ -3796,7 +3839,29 @@ test:
abort ( ) ;
}
if ( ! message_eq ( 0 , msg ) ) abort ( ) ;
if ( ! message_eq ( 0 , 0 , msg ) ) abort ( ) ;
parser_free ( ) ;
}
/* Verify that body and next message won't be parsed in responses to CONNECT */
void
test_message_connect ( const struct message * msg )
{
char * buf = ( char * ) msg - > raw ;
size_t buflen = strlen ( msg - > raw ) ;
size_t nread ;
parser_init ( msg - > type ) ;
nread = parse_connect ( buf , buflen ) ;
if ( num_messages ! = 1 ) {
printf ( " \n *** num_messages != 1 after testing '%s' *** \n \n " , msg - > name ) ;
abort ( ) ;
}
if ( ! message_eq ( 0 , 1 , msg ) ) abort ( ) ;
parser_free ( ) ;
}
@ -3867,6 +3932,10 @@ main (void)
test_message_pause ( & responses [ i ] ) ;
}
for ( i = 0 ; i < response_count ; i + + ) {
test_message_connect ( & responses [ i ] ) ;
}
for ( i = 0 ; i < response_count ; i + + ) {
if ( ! responses [ i ] . should_keep_alive ) continue ;
for ( j = 0 ; j < response_count ; j + + ) {