diff options
Diffstat (limited to 'test/server/test_server.c')
-rw-r--r-- | test/server/test_server.c | 171 |
1 files changed, 104 insertions, 67 deletions
diff --git a/test/server/test_server.c b/test/server/test_server.c index 1ad2c9e..6130d6e 100644 --- a/test/server/test_server.c +++ b/test/server/test_server.c @@ -23,44 +23,6 @@ #include "test_server.h" -struct serv_ctx_t { - /* Pool for resource allocation. */ - apr_pool_t *pool; - - apr_int32_t options; - - /* Array of actions which server will replay when client connected. */ - test_server_action_t *action_list; - /* Size of action_list array. */ - apr_size_t action_count; - /* Index of current action. */ - apr_size_t cur_action; - - /* Array of messages the server will receive from the client. */ - test_server_message_t *message_list; - /* Size of message_list array. */ - apr_size_t message_count; - /* Index of current message. */ - apr_size_t cur_message; - - /* Number of messages received that the server didn't respond to yet. */ - apr_size_t outstanding_responses; - - /* Position in message buffer (incoming messages being read). */ - apr_size_t message_buf_pos; - - /* Position in action buffer. (outgoing messages being sent). */ - apr_size_t action_buf_pos; - - /* Address for server binding. */ - apr_sockaddr_t *serv_addr; - apr_socket_t *serv_sock; - - /* Accepted client socket. NULL if there is no client socket. */ - apr_socket_t *client_sock; - -}; - /* Replay support functions */ static void next_message(serv_ctx_t *servctx) { @@ -73,6 +35,20 @@ static void next_action(serv_ctx_t *servctx) servctx->action_buf_pos = 0; } +static apr_status_t +socket_write(serv_ctx_t *serv_ctx, const char *data, + apr_size_t *len) +{ + return apr_socket_send(serv_ctx->client_sock, data, len); +} + +static apr_status_t +socket_read(serv_ctx_t *serv_ctx, char *data, + apr_size_t *len) +{ + return apr_socket_recv(serv_ctx->client_sock, data, len); +} + /* Verify received requests and take the necessary actions (return a response, kill the connection ...) */ static apr_status_t replay(serv_ctx_t *servctx, @@ -94,7 +70,7 @@ static apr_status_t replay(serv_ctx_t *servctx, char buf[128]; apr_size_t len = sizeof(buf); - status = apr_socket_recv(servctx->client_sock, buf, &len); + status = servctx->read(servctx, buf, &len); if (! APR_STATUS_IS_EAGAIN(status)) { /* we're out of actions! */ printf("Received more requests than expected.\n"); @@ -110,7 +86,7 @@ static apr_status_t replay(serv_ctx_t *servctx, char buf[128]; apr_size_t len = sizeof(buf); - status = apr_socket_recv(servctx->client_sock, buf, &len); + status = servctx->read(servctx, buf, &len); if (status == APR_EOF) { apr_socket_close(servctx->client_sock); @@ -135,7 +111,7 @@ static apr_status_t replay(serv_ctx_t *servctx, if (len > sizeof(buf)) len = sizeof(buf); - status = apr_socket_recv(servctx->client_sock, buf, &len); + status = servctx->read(servctx, buf, &len); if (status != APR_SUCCESS) return status; @@ -176,8 +152,9 @@ static apr_status_t replay(serv_ctx_t *servctx, msg_len = strlen(action->text); len = msg_len - servctx->action_buf_pos; - status = apr_socket_send(servctx->client_sock, - action->text + servctx->action_buf_pos, &len); + status = servctx->send(servctx, + action->text + servctx->action_buf_pos, + &len); if (status != APR_SUCCESS) return status; @@ -219,7 +196,13 @@ apr_status_t test_server_run(serv_ctx_t *servctx, const apr_pollfd_t *desc; /* create a new pollset */ +#ifdef BROKEN_WSAPOLL + status = apr_pollset_create_ex(&pollset, 32, pool, 0, + APR_POLLSET_SELECT); +#else status = apr_pollset_create(&pollset, 32, pool, 0); +#endif + if (status != APR_SUCCESS) return status; @@ -261,6 +244,13 @@ apr_status_t test_server_run(serv_ctx_t *servctx, } if (desc->desc.s == servctx->client_sock) { + if (servctx->handshake) { + status = servctx->handshake(servctx); + } + + if (status) + goto cleanup; + /* Replay data to socket. */ status = replay(servctx, desc->rtnevents, pool); @@ -286,20 +276,20 @@ cleanup: return status; } -/* Start a TCP server on port SERV_PORT in thread THREAD. srv_replay is a array - of action to replay when connection started. replay_count is count of - actions in srv_replay. */ -apr_status_t test_start_server(serv_ctx_t **servctx_p, - apr_sockaddr_t *address, - test_server_message_t *message_list, - apr_size_t message_count, - test_server_action_t *action_list, - apr_size_t action_count, - apr_int32_t options, - apr_pool_t *pool) + +/* Setup the context needed to start a TCP server on adress. + message_list is a list of expected requests. + action_list is the list of responses to be returned in order. + */ +void test_setup_server(serv_ctx_t **servctx_p, + apr_sockaddr_t *address, + test_server_message_t *message_list, + apr_size_t message_count, + test_server_action_t *action_list, + apr_size_t action_count, + apr_int32_t options, + apr_pool_t *pool) { - apr_status_t status; - apr_socket_t *serv_sock; serv_ctx_t *servctx; servctx = apr_pcalloc(pool, sizeof(*servctx)); @@ -313,12 +303,58 @@ apr_status_t test_start_server(serv_ctx_t **servctx_p, servctx->action_list = action_list; servctx->action_count = action_count; + /* Start replay from first action. */ + servctx->cur_action = 0; + servctx->action_buf_pos = 0; + servctx->outstanding_responses = 0; + + servctx->read = socket_read; + servctx->send = socket_write; + + *servctx_p = servctx; +} + +void test_setup_https_server(serv_ctx_t **servctx_p, + apr_sockaddr_t *address, + test_server_message_t *message_list, + apr_size_t message_count, + test_server_action_t *action_list, + apr_size_t action_count, + apr_int32_t options, + const char *keyfile, + const char *certfile, + apr_pool_t *pool) +{ + serv_ctx_t *servctx; + + test_setup_server(servctx_p, address, message_list, + message_count, action_list, action_count, + options, pool); + + servctx = *servctx_p; + + servctx->handshake = ssl_handshake; + /* Override with SSL encrypt/decrypt functions */ + servctx->read = ssl_socket_read; + servctx->send = ssl_socket_write; + + init_ssl_context(servctx, keyfile, certfile); +} + +apr_status_t test_start_server(serv_ctx_t *servctx) +{ + apr_status_t status; + apr_socket_t *serv_sock; + /* create server socket */ #if APR_VERSION_AT_LEAST(1, 0, 0) - status = apr_socket_create(&serv_sock, address->family, SOCK_STREAM, 0, - pool); + status = apr_socket_create(&serv_sock, servctx->serv_addr->family, + SOCK_STREAM, 0, + servctx->pool); #else - status = apr_socket_create(&serv_sock, address->family, SOCK_STREAM, pool); + status = apr_socket_create(&serv_sock, servctx->serv_addr->family, + SOCK_STREAM, + servctx->pool); #endif if (status != APR_SUCCESS) @@ -332,28 +368,29 @@ apr_status_t test_start_server(serv_ctx_t **servctx_p, if (status != APR_SUCCESS) return status; - /* Start replay from first action. */ - servctx->cur_action = 0; - servctx->action_buf_pos = 0; - servctx->outstanding_responses = 0; - /* listen for clients */ - apr_socket_listen(serv_sock, SOMAXCONN); + status = apr_socket_listen(serv_sock, SOMAXCONN); if (status != APR_SUCCESS) return status; servctx->serv_sock = serv_sock; servctx->client_sock = NULL; + return APR_SUCCESS; } apr_status_t test_server_destroy(serv_ctx_t *servctx, apr_pool_t *pool) { - apr_socket_close(servctx->serv_sock); + apr_status_t status; + + status = apr_socket_close(servctx->serv_sock); if (servctx->client_sock) { apr_socket_close(servctx->client_sock); } - return APR_SUCCESS; + if (servctx->ssl_ctx) + cleanup_ssl_context(servctx); + + return status; } |