20
20
#include <stdlib.h>
23
#include "serf_private.h" /* for serf__log and serf__bucket_stream_create */
24
25
#include "test_server.h"
27
/* Pool for resource allocation. */
32
/* Array of actions which server will replay when client connected. */
33
test_server_action_t *action_list;
34
/* Size of action_list array. */
35
apr_size_t action_count;
36
/* Index of current action. */
37
apr_size_t cur_action;
39
/* Array of messages the server will receive from the client. */
40
test_server_message_t *message_list;
41
/* Size of message_list array. */
42
apr_size_t message_count;
43
/* Index of current message. */
44
apr_size_t cur_message;
46
/* Number of messages received that the server didn't respond to yet. */
47
apr_size_t outstanding_responses;
49
/* Position in message buffer (incoming messages being read). */
50
apr_size_t message_buf_pos;
52
/* Position in action buffer. (outgoing messages being sent). */
53
apr_size_t action_buf_pos;
55
/* Address for server binding. */
56
apr_sockaddr_t *serv_addr;
57
apr_socket_t *serv_sock;
59
/* Accepted client socket. NULL if there is no client socket. */
60
apr_socket_t *client_sock;
29
/* Cleanup callback for a server. */
30
static apr_status_t cleanup_server(void *baton)
32
serv_ctx_t *servctx = baton;
35
if (servctx->serv_sock)
36
status = apr_socket_close(servctx->serv_sock);
38
status = APR_EGENERAL;
40
if (servctx->client_sock) {
41
apr_socket_close(servctx->client_sock);
64
47
/* Replay support functions */
65
48
static void next_message(serv_ctx_t *servctx)
73
56
servctx->action_buf_pos = 0;
60
socket_write(serv_ctx_t *serv_ctx, const char *data,
63
return apr_socket_send(serv_ctx->client_sock, data, len);
67
socket_read(serv_ctx_t *serv_ctx, char *data,
70
return apr_socket_recv(serv_ctx->client_sock, data, len);
74
create_client_socket(apr_socket_t **skt,
78
apr_sockaddr_t *address;
82
status = apr_uri_parse(servctx->pool, url, &uri);
83
if (status != APR_SUCCESS)
86
status = apr_sockaddr_info_get(&address,
92
if (status != APR_SUCCESS)
95
status = apr_socket_create(skt,
98
#if APR_MAJOR_VERSION > 0
102
if (status != APR_SUCCESS)
105
/* Set the socket to be non-blocking */
106
status = apr_socket_timeout_set(*skt, 0);
107
if (status != APR_SUCCESS)
110
status = apr_socket_connect(*skt, address);
111
if (status != APR_SUCCESS && !APR_STATUS_IS_EINPROGRESS(status))
117
static apr_status_t detect_eof(void *baton, serf_bucket_t *aggregate_bucket)
76
122
/* Verify received requests and take the necessary actions
77
123
(return a response, kill the connection ...) */
78
124
static apr_status_t replay(serv_ctx_t *servctx,
85
131
if (rtnevents & APR_POLLIN) {
86
132
if (servctx->message_list == NULL) {
87
133
/* we're not expecting any requests to reach this server! */
88
printf("Received request where none was expected\n");
134
serf__log(TEST_VERBOSE, __FILE__,
135
"Received request where none was expected.\n");
137
return SERF_ERROR_ISSUE_IN_TESTSUITE;
93
140
if (servctx->cur_action >= servctx->action_count) {
95
142
apr_size_t len = sizeof(buf);
97
status = apr_socket_recv(servctx->client_sock, buf, &len);
144
status = servctx->read(servctx, buf, &len);
98
145
if (! APR_STATUS_IS_EAGAIN(status)) {
99
146
/* we're out of actions! */
100
printf("Received more requests than expected.\n");
147
serf__log(TEST_VERBOSE, __FILE__,
148
"Received more requests than expected.\n");
150
return SERF_ERROR_ISSUE_IN_TESTSUITE;
107
155
action = &servctx->action_list[servctx->cur_action];
157
serf__log(TEST_VERBOSE, __FILE__,
158
"POLLIN while replaying action %d, kind: %d.\n",
159
servctx->cur_action, action->kind);
161
/* Read the remaining data from the client and kill the socket. */
109
162
if (action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
111
164
apr_size_t len = sizeof(buf);
113
status = apr_socket_recv(servctx->client_sock, buf, &len);
166
status = servctx->read(servctx, buf, &len);
115
168
if (status == APR_EOF) {
169
serf__log(TEST_VERBOSE, __FILE__,
170
"Killing this connection.\n");
116
171
apr_socket_close(servctx->client_sock);
117
172
servctx->client_sock = NULL;
118
173
next_action(servctx);
131
186
message = &servctx->message_list[servctx->cur_message];
132
187
msg_len = strlen(message->text);
134
len = msg_len - servctx->message_buf_pos;
135
if (len > sizeof(buf))
138
status = apr_socket_recv(servctx->client_sock, buf, &len);
139
if (status != APR_SUCCESS)
142
if (servctx->options & TEST_SERVER_DUMP)
143
fwrite(buf, len, 1, stdout);
145
if (strncmp(buf, message->text + servctx->message_buf_pos, len) != 0) {
146
/* ## TODO: Better diagnostics. */
147
printf("Expected: (\n");
148
fwrite(message->text + servctx->message_buf_pos, len, 1, stdout);
150
printf("Actual: (\n");
151
fwrite(buf, len, 1, stdout);
157
servctx->message_buf_pos += len;
159
if (servctx->message_buf_pos >= msg_len) {
160
next_message(servctx);
161
servctx->message_buf_pos -= msg_len;
162
if (action->kind == SERVER_RESPOND)
163
servctx->outstanding_responses++;
164
if (action->kind == SERVER_RECV)
191
len = msg_len - servctx->message_buf_pos;
192
if (len > sizeof(buf))
195
status = servctx->read(servctx, buf, &len);
196
if (SERF_BUCKET_READ_ERROR(status))
199
if (status == APR_EOF) {
200
serf__log(TEST_VERBOSE, __FILE__,
201
"Server: Client hung up the connection.\n");
204
if (servctx->options & TEST_SERVER_DUMP)
205
fwrite(buf, len, 1, stdout);
208
message->text + servctx->message_buf_pos,
210
/* ## TODO: Better diagnostics. */
211
printf("Expected: (\n");
212
fwrite(message->text + servctx->message_buf_pos, len, 1,
215
printf("Actual: (\n");
216
fwrite(buf, len, 1, stdout);
219
return SERF_ERROR_ISSUE_IN_TESTSUITE;
222
servctx->message_buf_pos += len;
224
if (servctx->message_buf_pos >= msg_len) {
225
next_message(servctx);
226
servctx->message_buf_pos -= msg_len;
227
if (action->kind == SERVER_RESPOND)
228
servctx->outstanding_responses++;
229
if (action->kind == SERVER_RECV)
230
next_action(servctx);
235
else if (action->kind == PROXY_FORWARD) {
240
/* Read all incoming data from the client to forward it to the
246
status = servctx->read(servctx, buf, &len);
247
if (SERF_BUCKET_READ_ERROR(status))
250
serf__log(TEST_VERBOSE, __FILE__,
251
"proxy: reading %d bytes %.*s from client with "
253
len, len, buf, status);
255
if (status == APR_EOF) {
256
serf__log(TEST_VERBOSE, __FILE__,
257
"Proxy: client hung up the connection. Reset the "
258
"connection to the server.\n");
259
/* We have to stop forwarding, if a new connection opens
260
the CONNECT request should not be forwarded to the
165
262
next_action(servctx);
264
if (!servctx->servstream)
265
servctx->servstream = serf__bucket_stream_create(
269
tmp = serf_bucket_simple_copy_create(buf, len,
271
serf_bucket_aggregate_append(servctx->servstream, tmp);
169
276
if (rtnevents & APR_POLLOUT) {
170
277
action = &servctx->action_list[servctx->cur_action];
279
serf__log(TEST_VERBOSE, __FILE__,
280
"POLLOUT when replaying action %d, kind: %d.\n", servctx->cur_action,
172
283
if (action->kind == SERVER_RESPOND && servctx->outstanding_responses) {
173
284
apr_size_t msg_len;
194
306
else if (action->kind == SERVER_KILL_CONNECTION ||
195
307
action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
308
serf__log(TEST_VERBOSE, __FILE__,
309
"Killing this connection.\n");
196
310
apr_socket_close(servctx->client_sock);
197
311
servctx->client_sock = NULL;
198
312
next_action(servctx);
201
else if (rtnevents & APR_POLLIN) {
205
printf("Unknown rtnevents: %d\n", rtnevents);
212
apr_status_t test_server_run(serv_ctx_t *servctx,
314
else if (action->kind == PROXY_FORWARD) {
318
if (!servctx->proxy_client_sock) {
319
serf__log(TEST_VERBOSE, __FILE__, "Proxy: setting up connection "
321
status = create_client_socket(&servctx->proxy_client_sock,
322
servctx, action->text);
323
if (!servctx->clientstream)
324
servctx->clientstream = serf__bucket_stream_create(
329
/* Send all data received from the server to the client. */
336
status = serf_bucket_read(servctx->clientstream, readlen,
338
if (SERF_BUCKET_READ_ERROR(status))
345
serf__log(TEST_VERBOSE, __FILE__,
346
"proxy: sending %d bytes to client.\n", len);
347
status = servctx->send(servctx, buf, &len);
348
if (status != APR_SUCCESS) {
352
if (len != readlen) /* abort for now, return buf to aggregate
353
if not everything could be sent. */
358
else if (rtnevents & APR_POLLIN) {
362
printf("Unknown rtnevents: %d\n", rtnevents);
369
/* Exchange data between proxy and server */
370
static apr_status_t proxy_replay(serv_ctx_t *servctx,
371
apr_int16_t rtnevents,
376
if (rtnevents & APR_POLLIN) {
381
serf__log(TEST_VERBOSE, __FILE__, "proxy_replay: POLLIN\n");
382
/* Read all incoming data from the server to forward it to the
388
status = apr_socket_recv(servctx->proxy_client_sock, buf, &len);
389
if (SERF_BUCKET_READ_ERROR(status))
392
serf__log(TEST_VERBOSE, __FILE__,
393
"proxy: reading %d bytes %.*s from server.\n",
395
tmp = serf_bucket_simple_copy_create(buf, len,
397
serf_bucket_aggregate_append(servctx->clientstream, tmp);
401
if (rtnevents & APR_POLLOUT) {
405
serf__log(TEST_VERBOSE, __FILE__, "proxy_replay: POLLOUT\n");
406
/* Send all data received from the client to the server. */
413
if (!servctx->servstream)
414
servctx->servstream = serf__bucket_stream_create(
417
status = serf_bucket_read(servctx->servstream, BUFSIZE,
419
if (SERF_BUCKET_READ_ERROR(status))
426
serf__log(TEST_VERBOSE, __FILE__,
427
"proxy: sending %d bytes %.*s to server.\n",
429
status = apr_socket_send(servctx->proxy_client_sock, buf, &len);
430
if (status != APR_SUCCESS) {
434
if (len != readlen) /* abort for now */
438
else if (rtnevents & APR_POLLIN) {
442
printf("Unknown rtnevents: %d\n", rtnevents);
449
apr_status_t run_test_server(serv_ctx_t *servctx,
213
450
apr_short_interval_time_t duration,
214
451
apr_pool_t *pool)
219
456
const apr_pollfd_t *desc;
221
458
/* create a new pollset */
459
#ifdef BROKEN_WSAPOLL
460
status = apr_pollset_create_ex(&pollset, 32, pool, 0,
222
463
status = apr_pollset_create(&pollset, 32, pool, 0);
223
466
if (status != APR_SUCCESS)
226
469
/* Don't accept new connection while processing client connection. At
227
470
least for present time.*/
228
471
if (servctx->client_sock) {
229
apr_pollfd_t pfd = { pool, APR_POLL_SOCKET, APR_POLLIN | APR_POLLOUT, 0,
472
apr_pollfd_t pfd = { 0 };
474
pfd.desc_type = APR_POLL_SOCKET;
231
475
pfd.desc.s = servctx->client_sock;
476
pfd.reqevents = APR_POLLIN | APR_POLLOUT;
232
478
status = apr_pollset_add(pollset, &pfd);
233
479
if (status != APR_SUCCESS)
482
if (servctx->proxy_client_sock) {
483
apr_pollfd_t pfd = { 0 };
485
pfd.desc_type = APR_POLL_SOCKET;
486
pfd.desc.s = servctx->proxy_client_sock;
487
pfd.reqevents = APR_POLLIN | APR_POLLOUT;
489
status = apr_pollset_add(pollset, &pfd);
490
if (status != APR_SUCCESS)
237
apr_pollfd_t pfd = { pool, APR_POLL_SOCKET, APR_POLLIN, 0,
495
apr_pollfd_t pfd = { 0 };
497
pfd.desc_type = APR_POLL_SOCKET;
239
498
pfd.desc.s = servctx->serv_sock;
499
pfd.reqevents = APR_POLLIN;
240
501
status = apr_pollset_add(pollset, &pfd);
241
502
if (status != APR_SUCCESS)
263
528
if (desc->desc.s == servctx->client_sock) {
529
if (servctx->handshake) {
530
status = servctx->handshake(servctx);
264
535
/* Replay data to socket. */
265
536
status = replay(servctx, desc->rtnevents, pool);
267
538
if (APR_STATUS_IS_EOF(status)) {
268
539
apr_socket_close(servctx->client_sock);
269
540
servctx->client_sock = NULL;
542
servctx->reset(servctx);
544
/* If this is a proxy and the client closed the connection, also
545
close the connection to the server. */
546
if (servctx->proxy_client_sock) {
547
apr_socket_close(servctx->proxy_client_sock);
548
servctx->proxy_client_sock = NULL;
552
else if (APR_STATUS_IS_EAGAIN(status)) {
553
status = APR_SUCCESS;
555
else if (status != APR_SUCCESS) {
560
if (desc->desc.s == servctx->proxy_client_sock) {
561
/* Replay data to proxy socket. */
562
status = proxy_replay(servctx, desc->rtnevents, pool);
563
if (APR_STATUS_IS_EOF(status)) {
564
apr_socket_close(servctx->proxy_client_sock);
565
servctx->proxy_client_sock = NULL;
271
567
else if (APR_STATUS_IS_EAGAIN(status)) {
272
568
status = APR_SUCCESS;
289
/* Start a TCP server on port SERV_PORT in thread THREAD. srv_replay is a array
290
of action to replay when connection started. replay_count is count of
291
actions in srv_replay. */
292
apr_status_t test_start_server(serv_ctx_t **servctx_p,
293
apr_sockaddr_t *address,
294
test_server_message_t *message_list,
295
apr_size_t message_count,
296
test_server_action_t *action_list,
297
apr_size_t action_count,
586
/* Setup the context needed to start a TCP server on adress.
587
message_list is a list of expected requests.
588
action_list is the list of responses to be returned in order.
590
void setup_test_server(serv_ctx_t **servctx_p,
591
apr_sockaddr_t *address,
592
test_server_message_t *message_list,
593
apr_size_t message_count,
594
test_server_action_t *action_list,
595
apr_size_t action_count,
302
apr_socket_t *serv_sock;
303
599
serv_ctx_t *servctx;
305
601
servctx = apr_pcalloc(pool, sizeof(*servctx));
602
apr_pool_cleanup_register(pool, servctx,
604
apr_pool_cleanup_null);
306
605
*servctx_p = servctx;
308
607
servctx->serv_addr = address;
309
608
servctx->options = options;
310
609
servctx->pool = pool;
610
servctx->allocator = serf_bucket_allocator_create(pool, NULL, NULL);
311
611
servctx->message_list = message_list;
312
612
servctx->message_count = message_count;
313
613
servctx->action_list = action_list;
314
614
servctx->action_count = action_count;
616
/* Start replay from first action. */
617
servctx->cur_action = 0;
618
servctx->action_buf_pos = 0;
619
servctx->outstanding_responses = 0;
621
servctx->read = socket_read;
622
servctx->send = socket_write;
624
*servctx_p = servctx;
627
apr_status_t start_test_server(serv_ctx_t *servctx)
630
apr_socket_t *serv_sock;
316
632
/* create server socket */
317
633
#if APR_VERSION_AT_LEAST(1, 0, 0)
318
status = apr_socket_create(&serv_sock, address->family, SOCK_STREAM, 0,
634
status = apr_socket_create(&serv_sock, servctx->serv_addr->family,
321
status = apr_socket_create(&serv_sock, address->family, SOCK_STREAM, pool);
638
status = apr_socket_create(&serv_sock, servctx->serv_addr->family,
324
643
if (status != APR_SUCCESS)
332
651
if (status != APR_SUCCESS)
335
/* Start replay from first action. */
336
servctx->cur_action = 0;
337
servctx->action_buf_pos = 0;
338
servctx->outstanding_responses = 0;
340
654
/* listen for clients */
341
apr_socket_listen(serv_sock, SOMAXCONN);
655
status = apr_socket_listen(serv_sock, SOMAXCONN);
342
656
if (status != APR_SUCCESS)
345
659
servctx->serv_sock = serv_sock;
346
660
servctx->client_sock = NULL;
350
apr_status_t test_server_destroy(serv_ctx_t *servctx, apr_pool_t *pool)
352
apr_socket_close(servctx->serv_sock);
354
if (servctx->client_sock) {
355
apr_socket_close(servctx->client_sock);
358
662
return APR_SUCCESS;