test_context.c | test_context.c | |||
---|---|---|---|---|
skipping to change at line 998 | skipping to change at line 998 | |||
/* Check that progress was reported. */ | /* Check that progress was reported. */ | |||
CuAssertTrue(tc, pb->written > 0); | CuAssertTrue(tc, pb->written > 0); | |||
CuAssertTrue(tc, pb->read > 0); | CuAssertTrue(tc, pb->read > 0); | |||
/* Cleanup */ | /* Cleanup */ | |||
test_server_teardown(tb, test_pool); | test_server_teardown(tb, test_pool); | |||
test_teardown(test_pool); | test_teardown(test_pool); | |||
} | } | |||
#undef NUM_REQUESTS | #undef NUM_REQUESTS | |||
/************************************************************************** | ||||
*** | ||||
* Issue #91: test that serf correctly handle an incoming 4xx reponse while | ||||
* the outgoing request wasn't written completely yet. | ||||
************************************************************************** | ||||
***/ | ||||
#define REQUEST_PART1 "PROPFIND / HTTP/1.1" CRLF\ | ||||
"Host: lgo-ubuntu.local" CRLF\ | ||||
"User-Agent: SVN/1.8.0-dev (x86_64-apple-darwin11.4.2) serf/2.0.0" CRLF\ | ||||
"Content-Type: text/xml" CRLF\ | ||||
"Transfer-Encoding: chunked" CRLF \ | ||||
CRLF\ | ||||
"12d" CRLF\ | ||||
"<?xml version=""1.0"" encoding=""utf-8""?><propfind xmlns=""DAV:""><prop>" | ||||
#define REQUEST_PART2 \ | ||||
"<resourcetype xmlns=""DAV:""/><getcontentlength xmlns=""DAV:""/>"\ | ||||
"<deadprop-count xmlns=""http://subversion.tigris.org/xmlns/dav/""/>"\ | ||||
"<version-name xmlns=""DAV:""/><creationdate xmlns=""DAV:""/>"\ | ||||
"<creator-displayname xmlns=""DAV:""/></prop></propfind>" CRLF\ | ||||
"0" CRLF \ | ||||
CRLF | ||||
#define RESPONSE_408 "HTTP/1.1 408 Request Time-out" CRLF\ | ||||
"Date: Wed, 14 Nov 2012 19:50:35 GMT" CRLF\ | ||||
"Server: Apache/2.2.17 (Ubuntu)" CRLF\ | ||||
"Vary: Accept-Encoding" CRLF\ | ||||
"Content-Length: 305" CRLF\ | ||||
"Connection: close" CRLF\ | ||||
"Content-Type: text/html; charset=iso-8859-1" CRLF \ | ||||
CRLF\ | ||||
"<!DOCTYPE HTML PUBLIC ""-//IETF//DTD HTML 2.0//EN""><html><head>"\ | ||||
"<title>408 Request Time-out</title></head><body><h1>Request Time-out</h1>" | ||||
\ | ||||
"<p>Server timeout waiting for the HTTP request from the client.</p><hr>"\ | ||||
"<address>Apache/2.2.17 (Ubuntu) Server at lgo-ubuntu.local Port 80</addres | ||||
s>"\ | ||||
"</body></html>" | ||||
static apr_status_t detect_eof(void *baton, serf_bucket_t *aggregate_bucket | ||||
) | ||||
{ | ||||
serf_bucket_t *body_bkt; | ||||
handler_baton_t *ctx = baton; | ||||
if (ctx->done) { | ||||
body_bkt = serf_bucket_simple_create(REQUEST_PART1, strlen(REQUEST_ | ||||
PART2), | ||||
NULL, NULL, | ||||
ctx->tb->bkt_alloc); | ||||
serf_bucket_aggregate_append(aggregate_bucket, body_bkt); | ||||
} | ||||
return APR_EAGAIN; | ||||
} | ||||
static apr_status_t setup_request_timeout( | ||||
serf_request_t *request, | ||||
void *setup_baton, | ||||
serf_bucket_t **req_bkt, | ||||
serf_response_acceptor_t *acceptor, | ||||
void **acceptor_baton, | ||||
serf_response_handler_t *handler, | ||||
void **handler_baton, | ||||
apr_pool_t *pool) | ||||
{ | ||||
handler_baton_t *ctx = setup_baton; | ||||
serf_bucket_t *body_bkt; | ||||
*req_bkt = serf__bucket_stream_create(serf_request_get_alloc(request), | ||||
detect_eof, | ||||
ctx); | ||||
/* create a simple body text */ | ||||
body_bkt = serf_bucket_simple_create(REQUEST_PART1, strlen(REQUEST_PART | ||||
1), | ||||
NULL, NULL, | ||||
serf_request_get_alloc(request)); | ||||
serf_bucket_aggregate_append(*req_bkt, body_bkt); | ||||
APR_ARRAY_PUSH(ctx->sent_requests, int) = ctx->req_id; | ||||
*acceptor = ctx->acceptor; | ||||
*acceptor_baton = ctx; | ||||
*handler = ctx->handler; | ||||
*handler_baton = ctx; | ||||
return APR_SUCCESS; | ||||
} | ||||
static apr_status_t handle_response_timeout( | ||||
serf_request_t *request, | ||||
serf_bucket_t *response, | ||||
void *handler_baton, | ||||
apr_pool_t *pool) | ||||
{ | ||||
handler_baton_t *ctx = handler_baton; | ||||
serf_status_line sl; | ||||
apr_status_t status; | ||||
if (! response) { | ||||
serf_connection_request_create(ctx->tb->connection, | ||||
setup_request, | ||||
ctx); | ||||
return APR_SUCCESS; | ||||
} | ||||
if (serf_request_is_written(request) != APR_EBUSY) { | ||||
return APR_EGENERAL; | ||||
} | ||||
status = serf_bucket_response_status(response, &sl); | ||||
if (SERF_BUCKET_READ_ERROR(status)) { | ||||
return status; | ||||
} | ||||
if (!sl.version && (APR_STATUS_IS_EOF(status) || | ||||
APR_STATUS_IS_EAGAIN(status))) { | ||||
return status; | ||||
} | ||||
if (sl.code == 408) { | ||||
APR_ARRAY_PUSH(ctx->handled_requests, int) = ctx->req_id; | ||||
ctx->done = TRUE; | ||||
} | ||||
/* discard the rest of the body */ | ||||
while (1) { | ||||
const char *data; | ||||
apr_size_t len; | ||||
status = serf_bucket_read(response, 2048, &data, &len); | ||||
if (SERF_BUCKET_READ_ERROR(status) || | ||||
APR_STATUS_IS_EAGAIN(status) || | ||||
APR_STATUS_IS_EOF(status)) | ||||
return status; | ||||
} | ||||
return APR_SUCCESS; | ||||
} | ||||
#define NUM_REQUESTS 1 | ||||
static void test_serf_request_timeout(CuTest *tc) | ||||
{ | ||||
test_baton_t *tb; | ||||
apr_array_header_t *accepted_requests, *handled_requests, *sent_request | ||||
s; | ||||
apr_status_t status; | ||||
handler_baton_t handler_ctx[NUM_REQUESTS]; | ||||
test_server_message_t message_list[] = { | ||||
{REQUEST_PART1}, | ||||
{REQUEST_PART2}, | ||||
}; | ||||
test_server_action_t action_list[] = { | ||||
{SERVER_RESPOND, RESPONSE_408}, | ||||
}; | ||||
apr_pool_t *test_pool = test_setup(); | ||||
accepted_requests = apr_array_make(test_pool, NUM_REQUESTS, sizeof(int) | ||||
); | ||||
sent_requests = apr_array_make(test_pool, NUM_REQUESTS, sizeof(int)); | ||||
handled_requests = apr_array_make(test_pool, NUM_REQUESTS, sizeof(int)) | ||||
; | ||||
/* Set up a test context with a server. */ | ||||
status = test_server_setup(&tb, | ||||
message_list, 2, | ||||
action_list, 1, 0, | ||||
NULL, test_pool); | ||||
CuAssertIntEquals(tc, APR_SUCCESS, status); | ||||
/* Send some requests on the connection */ | ||||
handler_ctx[0].method = "PROPFIND"; | ||||
handler_ctx[0].path = "/"; | ||||
handler_ctx[0].done = FALSE; | ||||
handler_ctx[0].acceptor = accept_response; | ||||
handler_ctx[0].acceptor_baton = NULL; | ||||
handler_ctx[0].handler = handle_response_timeout; | ||||
handler_ctx[0].req_id = 1; | ||||
handler_ctx[0].accepted_requests = accepted_requests; | ||||
handler_ctx[0].sent_requests = sent_requests; | ||||
handler_ctx[0].handled_requests = handled_requests; | ||||
handler_ctx[0].tb = tb; | ||||
serf_connection_request_create(tb->connection, | ||||
setup_request_timeout, | ||||
&handler_ctx[0]); | ||||
while (1) { | ||||
status = test_server_run(tb->serv_ctx, 0, test_pool); | ||||
if (APR_STATUS_IS_TIMEUP(status)) | ||||
status = APR_SUCCESS; | ||||
CuAssertIntEquals(tc, APR_SUCCESS, status); | ||||
status = serf_context_run(tb->context, 0, test_pool); | ||||
if (APR_STATUS_IS_TIMEUP(status)) | ||||
status = APR_SUCCESS; | ||||
CuAssertIntEquals(tc, APR_SUCCESS, status); | ||||
if (handler_ctx[0].done) { | ||||
break; | ||||
} | ||||
} | ||||
/* Check that all requests were received */ | ||||
CuAssertTrue(tc, sent_requests->nelts >= NUM_REQUESTS); | ||||
CuAssertIntEquals(tc, NUM_REQUESTS, accepted_requests->nelts); | ||||
CuAssertIntEquals(tc, NUM_REQUESTS, handled_requests->nelts); | ||||
/* Cleanup */ | ||||
test_server_teardown(tb, test_pool); | ||||
test_teardown(test_pool); | ||||
} | ||||
CuSuite *test_context(void) | CuSuite *test_context(void) | |||
{ | { | |||
CuSuite *suite = CuSuiteNew(); | CuSuite *suite = CuSuiteNew(); | |||
SUITE_ADD_TEST(suite, test_serf_connection_request_create); | SUITE_ADD_TEST(suite, test_serf_connection_request_create); | |||
SUITE_ADD_TEST(suite, test_serf_connection_priority_request_create); | SUITE_ADD_TEST(suite, test_serf_connection_priority_request_create); | |||
SUITE_ADD_TEST(suite, test_serf_closed_connection); | SUITE_ADD_TEST(suite, test_serf_closed_connection); | |||
SUITE_ADD_TEST(suite, test_serf_setup_proxy); | SUITE_ADD_TEST(suite, test_serf_setup_proxy); | |||
SUITE_ADD_TEST(suite, test_keepalive_limit_one_by_one); | SUITE_ADD_TEST(suite, test_keepalive_limit_one_by_one); | |||
SUITE_ADD_TEST(suite, test_keepalive_limit_one_by_one_and_burst); | SUITE_ADD_TEST(suite, test_keepalive_limit_one_by_one_and_burst); | |||
SUITE_ADD_TEST(suite, test_serf_progress_callback); | SUITE_ADD_TEST(suite, test_serf_progress_callback); | |||
SUITE_ADD_TEST(suite, test_serf_request_timeout); | ||||
return suite; | return suite; | |||
} | } | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 217 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |