~ubuntu-branches/ubuntu/trusty/serf/trusty-security

« back to all changes in this revision

Viewing changes to test/server/test_server.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2013-12-31 13:17:16 UTC
  • mfrom: (1.1.8) (3.3.2 sid)
  • Revision ID: package-import@ubuntu.com-20131231131716-s862wc4uwdzxmrr1
Tags: 1.3.3-1
* Add myself to Uploaders.
* Change the watch file to better handle code.google.com.
* New upstream release.  (Closes: #716793)
  + Refresh patches/libtool
  + Update symbols
* Adapt packaging for the upstream switch to SCons.
  + control: + scons, - autotools-dev, autoconf
  + rules: Change configure/make calls to scons
* Rename libserf1 to libserf-1-1, following standard naming conventions.
* Enable hardening flags.
* Strip unnecessary RPATH from libserf.
* Honor DEB_BUILD_OPTIONS=parallel=X

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include <stdlib.h>
21
21
 
22
22
#include "serf.h"
 
23
#include "serf_private.h" /* for serf__log and serf__bucket_stream_create */
23
24
 
24
25
#include "test_server.h"
25
26
 
26
 
struct serv_ctx_t {
27
 
    /* Pool for resource allocation. */
28
 
    apr_pool_t *pool;
29
 
 
30
 
    apr_int32_t options;
31
 
 
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;
38
 
 
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;
45
 
 
46
 
    /* Number of messages received that the server didn't respond to yet. */
47
 
    apr_size_t outstanding_responses;
48
 
 
49
 
    /* Position in message buffer (incoming messages being read). */
50
 
    apr_size_t message_buf_pos;
51
 
 
52
 
    /* Position in action buffer. (outgoing messages being sent). */
53
 
    apr_size_t action_buf_pos;
54
 
 
55
 
    /* Address for server binding. */
56
 
    apr_sockaddr_t *serv_addr;
57
 
    apr_socket_t *serv_sock;
58
 
 
59
 
    /* Accepted client socket. NULL if there is no client socket. */
60
 
    apr_socket_t *client_sock;
61
 
 
62
 
};
 
27
#define BUFSIZE 8192
 
28
 
 
29
/* Cleanup callback for a server. */
 
30
static apr_status_t cleanup_server(void *baton)
 
31
{
 
32
    serv_ctx_t *servctx = baton;
 
33
    apr_status_t status;
 
34
 
 
35
    if (servctx->serv_sock)
 
36
      status = apr_socket_close(servctx->serv_sock);
 
37
    else
 
38
      status = APR_EGENERAL;
 
39
 
 
40
    if (servctx->client_sock) {
 
41
        apr_socket_close(servctx->client_sock);
 
42
    }
 
43
 
 
44
    return status;
 
45
}
63
46
 
64
47
/* Replay support functions */
65
48
static void next_message(serv_ctx_t *servctx)
73
56
    servctx->action_buf_pos = 0;
74
57
}
75
58
 
 
59
static apr_status_t
 
60
socket_write(serv_ctx_t *serv_ctx, const char *data,
 
61
             apr_size_t *len)
 
62
{
 
63
    return apr_socket_send(serv_ctx->client_sock, data, len);
 
64
}
 
65
 
 
66
static apr_status_t
 
67
socket_read(serv_ctx_t *serv_ctx, char *data,
 
68
            apr_size_t *len)
 
69
{
 
70
    return apr_socket_recv(serv_ctx->client_sock, data, len);
 
71
}
 
72
 
 
73
static apr_status_t
 
74
create_client_socket(apr_socket_t **skt,
 
75
                     serv_ctx_t *servctx,
 
76
                     const char *url)
 
77
{
 
78
    apr_sockaddr_t *address;
 
79
    apr_uri_t uri;
 
80
    apr_status_t status;
 
81
 
 
82
    status = apr_uri_parse(servctx->pool, url, &uri);
 
83
    if (status != APR_SUCCESS)
 
84
        return status;
 
85
 
 
86
    status = apr_sockaddr_info_get(&address,
 
87
                                   uri.hostname,
 
88
                                   APR_UNSPEC,
 
89
                                   uri.port,
 
90
                                   0,
 
91
                                   servctx->pool);
 
92
    if (status != APR_SUCCESS)
 
93
        return status;
 
94
 
 
95
    status = apr_socket_create(skt,
 
96
                               address->family,
 
97
                               SOCK_STREAM,
 
98
#if APR_MAJOR_VERSION > 0
 
99
                               APR_PROTO_TCP,
 
100
#endif
 
101
                               servctx->pool);
 
102
    if (status != APR_SUCCESS)
 
103
        return status;
 
104
 
 
105
    /* Set the socket to be non-blocking */
 
106
    status = apr_socket_timeout_set(*skt, 0);
 
107
    if (status != APR_SUCCESS)
 
108
        return status;
 
109
 
 
110
    status = apr_socket_connect(*skt, address);
 
111
    if (status != APR_SUCCESS && !APR_STATUS_IS_EINPROGRESS(status))
 
112
        return status;
 
113
 
 
114
    return APR_SUCCESS;
 
115
}
 
116
 
 
117
static apr_status_t detect_eof(void *baton, serf_bucket_t *aggregate_bucket)
 
118
{
 
119
    return APR_EAGAIN;
 
120
}
 
121
 
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");
89
136
 
90
 
            return APR_EGENERAL;
 
137
            return SERF_ERROR_ISSUE_IN_TESTSUITE;
91
138
        }
92
139
 
93
140
        if (servctx->cur_action >= servctx->action_count) {
94
141
            char buf[128];
95
142
            apr_size_t len = sizeof(buf);
96
143
 
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");
101
149
 
102
 
                return APR_EGENERAL;
 
150
                return SERF_ERROR_ISSUE_IN_TESTSUITE;
103
151
            }
104
152
            return status;
105
153
        }
106
154
 
107
155
        action = &servctx->action_list[servctx->cur_action];
108
156
 
 
157
        serf__log(TEST_VERBOSE, __FILE__,
 
158
                  "POLLIN while replaying action %d, kind: %d.\n",
 
159
                  servctx->cur_action, action->kind);
 
160
 
 
161
        /* Read the remaining data from the client and kill the socket. */
109
162
        if (action->kind == SERVER_IGNORE_AND_KILL_CONNECTION) {
110
163
            char buf[128];
111
164
            apr_size_t len = sizeof(buf);
112
165
 
113
 
            status = apr_socket_recv(servctx->client_sock, buf, &len);
 
166
            status = servctx->read(servctx, buf, &len);
114
167
 
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);
133
188
 
134
 
            len = msg_len - servctx->message_buf_pos;
135
 
            if (len > sizeof(buf))
136
 
                len = sizeof(buf);
137
 
 
138
 
            status = apr_socket_recv(servctx->client_sock, buf, &len);
139
 
            if (status != APR_SUCCESS)
140
 
                return status;
141
 
 
142
 
            if (servctx->options & TEST_SERVER_DUMP)
143
 
                fwrite(buf, len, 1, stdout);
144
 
 
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);
149
 
                printf(")\n");
150
 
                printf("Actual: (\n");
151
 
                fwrite(buf, len, 1, stdout);
152
 
                printf(")\n");
153
 
 
154
 
                return APR_EGENERAL;
155
 
            }
156
 
 
157
 
            servctx->message_buf_pos += len;
158
 
 
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)
 
189
            do
 
190
            {
 
191
                len = msg_len - servctx->message_buf_pos;
 
192
                if (len > sizeof(buf))
 
193
                    len = sizeof(buf);
 
194
 
 
195
                status = servctx->read(servctx, buf, &len);
 
196
                if (SERF_BUCKET_READ_ERROR(status))
 
197
                    return status;
 
198
 
 
199
                if (status == APR_EOF) {
 
200
                    serf__log(TEST_VERBOSE, __FILE__,
 
201
                              "Server: Client hung up the connection.\n");
 
202
                    break;
 
203
                }
 
204
                if (servctx->options & TEST_SERVER_DUMP)
 
205
                    fwrite(buf, len, 1, stdout);
 
206
 
 
207
                if (strncmp(buf,
 
208
                            message->text + servctx->message_buf_pos,
 
209
                            len) != 0) {
 
210
                    /* ## TODO: Better diagnostics. */
 
211
                    printf("Expected: (\n");
 
212
                    fwrite(message->text + servctx->message_buf_pos, len, 1,
 
213
                           stdout);
 
214
                    printf(")\n");
 
215
                    printf("Actual: (\n");
 
216
                    fwrite(buf, len, 1, stdout);
 
217
                    printf(")\n");
 
218
 
 
219
                    return SERF_ERROR_ISSUE_IN_TESTSUITE;
 
220
                }
 
221
 
 
222
                servctx->message_buf_pos += len;
 
223
 
 
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);
 
231
                    break;
 
232
                }
 
233
            } while (!status);
 
234
        }
 
235
        else if (action->kind == PROXY_FORWARD) {
 
236
            apr_size_t len;
 
237
            char buf[BUFSIZE];
 
238
            serf_bucket_t *tmp;
 
239
 
 
240
            /* Read all incoming data from the client to forward it to the
 
241
               server later. */
 
242
            do
 
243
            {
 
244
                len = BUFSIZE;
 
245
 
 
246
                status = servctx->read(servctx, buf, &len);
 
247
                if (SERF_BUCKET_READ_ERROR(status))
 
248
                    return status;
 
249
 
 
250
                serf__log(TEST_VERBOSE, __FILE__,
 
251
                          "proxy: reading %d bytes %.*s from client with "
 
252
                          "status %d.\n",
 
253
                          len, len, buf, status);
 
254
 
 
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
 
261
                       server. */
165
262
                    next_action(servctx);
166
 
            }
 
263
                }
 
264
                if (!servctx->servstream)
 
265
                    servctx->servstream = serf__bucket_stream_create(
 
266
                                              servctx->allocator,
 
267
                                              detect_eof,servctx);
 
268
                if (len) {
 
269
                    tmp = serf_bucket_simple_copy_create(buf, len,
 
270
                                                         servctx->allocator);
 
271
                    serf_bucket_aggregate_append(servctx->servstream, tmp);
 
272
                }
 
273
            } while (!status);
167
274
        }
168
275
    }
169
276
    if (rtnevents & APR_POLLOUT) {
170
277
        action = &servctx->action_list[servctx->cur_action];
171
278
 
 
279
        serf__log(TEST_VERBOSE, __FILE__,
 
280
                  "POLLOUT when replaying action %d, kind: %d.\n", servctx->cur_action,
 
281
                  action->kind);
 
282
 
172
283
        if (action->kind == SERVER_RESPOND && servctx->outstanding_responses) {
173
284
            apr_size_t msg_len;
174
285
            apr_size_t len;
176
287
            msg_len = strlen(action->text);
177
288
            len = msg_len - servctx->action_buf_pos;
178
289
 
179
 
            status = apr_socket_send(servctx->client_sock,
180
 
                                     action->text + servctx->action_buf_pos, &len);
 
290
            status = servctx->send(servctx,
 
291
                                   action->text + servctx->action_buf_pos,
 
292
                                   &len);
181
293
            if (status != APR_SUCCESS)
182
294
                return status;
183
295
 
193
305
        }
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);
199
313
        }
200
 
    }
201
 
    else if (rtnevents & APR_POLLIN) {
202
 
        /* ignore */
203
 
    }
204
 
    else {
205
 
        printf("Unknown rtnevents: %d\n", rtnevents);
206
 
        abort();
207
 
    }
208
 
 
209
 
    return status;
210
 
}
211
 
 
212
 
apr_status_t test_server_run(serv_ctx_t *servctx,
 
314
        else if (action->kind == PROXY_FORWARD) {
 
315
            apr_size_t len;
 
316
            char *buf;
 
317
 
 
318
            if (!servctx->proxy_client_sock) {
 
319
                serf__log(TEST_VERBOSE, __FILE__, "Proxy: setting up connection "
 
320
                          "to server.\n");
 
321
                status = create_client_socket(&servctx->proxy_client_sock,
 
322
                                              servctx, action->text);
 
323
                if (!servctx->clientstream)
 
324
                    servctx->clientstream = serf__bucket_stream_create(
 
325
                                                servctx->allocator,
 
326
                                                detect_eof,servctx);
 
327
            }
 
328
 
 
329
            /* Send all data received from the server to the client. */
 
330
            do
 
331
            {
 
332
                apr_size_t readlen;
 
333
 
 
334
                readlen = BUFSIZE;
 
335
 
 
336
                status = serf_bucket_read(servctx->clientstream, readlen,
 
337
                                          &buf, &readlen);
 
338
                if (SERF_BUCKET_READ_ERROR(status))
 
339
                    return status;
 
340
                if (!readlen)
 
341
                    break;
 
342
 
 
343
                len = readlen;
 
344
 
 
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) {
 
349
                    return status;
 
350
                }
 
351
                
 
352
                if (len != readlen) /* abort for now, return buf to aggregate
 
353
                                       if not everything could be sent. */
 
354
                    return APR_EGENERAL;
 
355
            } while (!status);
 
356
        }
 
357
    }
 
358
    else if (rtnevents & APR_POLLIN) {
 
359
        /* ignore */
 
360
    }
 
361
    else {
 
362
        printf("Unknown rtnevents: %d\n", rtnevents);
 
363
        abort();
 
364
    }
 
365
 
 
366
    return status;
 
367
}
 
368
 
 
369
/* Exchange data between proxy and server */
 
370
static apr_status_t proxy_replay(serv_ctx_t *servctx,
 
371
                                 apr_int16_t rtnevents,
 
372
                                 apr_pool_t *pool)
 
373
{
 
374
    apr_status_t status;
 
375
 
 
376
    if (rtnevents & APR_POLLIN) {
 
377
        apr_size_t len;
 
378
        char buf[BUFSIZE];
 
379
        serf_bucket_t *tmp;
 
380
 
 
381
        serf__log(TEST_VERBOSE, __FILE__, "proxy_replay: POLLIN\n");
 
382
        /* Read all incoming data from the server to forward it to the
 
383
           client later. */
 
384
        do
 
385
        {
 
386
            len = BUFSIZE;
 
387
 
 
388
            status = apr_socket_recv(servctx->proxy_client_sock, buf, &len);
 
389
            if (SERF_BUCKET_READ_ERROR(status))
 
390
                return status;
 
391
 
 
392
            serf__log(TEST_VERBOSE, __FILE__,
 
393
                      "proxy: reading %d bytes %.*s from server.\n",
 
394
                      len, len, buf);
 
395
            tmp = serf_bucket_simple_copy_create(buf, len,
 
396
                                                 servctx->allocator);
 
397
            serf_bucket_aggregate_append(servctx->clientstream, tmp);
 
398
        } while (!status);
 
399
    }
 
400
 
 
401
    if (rtnevents & APR_POLLOUT) {
 
402
        apr_size_t len;
 
403
        char *buf;
 
404
 
 
405
        serf__log(TEST_VERBOSE, __FILE__, "proxy_replay: POLLOUT\n");
 
406
        /* Send all data received from the client to the server. */
 
407
        do
 
408
        {
 
409
            apr_size_t readlen;
 
410
 
 
411
            readlen = BUFSIZE;
 
412
 
 
413
            if (!servctx->servstream)
 
414
                servctx->servstream = serf__bucket_stream_create(
 
415
                                          servctx->allocator,
 
416
                                          detect_eof,servctx);
 
417
            status = serf_bucket_read(servctx->servstream, BUFSIZE,
 
418
                                      &buf, &readlen);
 
419
            if (SERF_BUCKET_READ_ERROR(status))
 
420
                return status;
 
421
            if (!readlen)
 
422
                break;
 
423
 
 
424
            len = readlen;
 
425
 
 
426
            serf__log(TEST_VERBOSE, __FILE__,
 
427
                      "proxy: sending %d bytes %.*s to server.\n",
 
428
                      len, len, buf);
 
429
            status = apr_socket_send(servctx->proxy_client_sock, buf, &len);
 
430
            if (status != APR_SUCCESS) {
 
431
                return status;
 
432
            }
 
433
 
 
434
            if (len != readlen) /* abort for now */
 
435
                return APR_EGENERAL;
 
436
        } while (!status);
 
437
    }
 
438
    else if (rtnevents & APR_POLLIN) {
 
439
        /* ignore */
 
440
    }
 
441
    else {
 
442
        printf("Unknown rtnevents: %d\n", rtnevents);
 
443
        abort();
 
444
    }
 
445
 
 
446
    return status;
 
447
}
 
448
 
 
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)
215
452
{
219
456
    const apr_pollfd_t *desc;
220
457
 
221
458
    /* create a new pollset */
 
459
#ifdef BROKEN_WSAPOLL
 
460
    status = apr_pollset_create_ex(&pollset, 32, pool, 0,
 
461
                                 APR_POLLSET_SELECT);
 
462
#else
222
463
    status = apr_pollset_create(&pollset, 32, pool, 0);
 
464
#endif
 
465
 
223
466
    if (status != APR_SUCCESS)
224
467
        return status;
225
468
 
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,
230
 
                             { NULL }, NULL };
 
472
        apr_pollfd_t pfd = { 0 };
 
473
 
 
474
        pfd.desc_type = APR_POLL_SOCKET;
231
475
        pfd.desc.s = servctx->client_sock;
 
476
        pfd.reqevents = APR_POLLIN | APR_POLLOUT;
 
477
 
232
478
        status = apr_pollset_add(pollset, &pfd);
233
479
        if (status != APR_SUCCESS)
234
480
            goto cleanup;
 
481
 
 
482
        if (servctx->proxy_client_sock) {
 
483
            apr_pollfd_t pfd = { 0 };
 
484
 
 
485
            pfd.desc_type = APR_POLL_SOCKET;
 
486
            pfd.desc.s = servctx->proxy_client_sock;
 
487
            pfd.reqevents = APR_POLLIN | APR_POLLOUT;
 
488
 
 
489
            status = apr_pollset_add(pollset, &pfd);
 
490
            if (status != APR_SUCCESS)
 
491
                goto cleanup;
 
492
        }
235
493
    }
236
494
    else {
237
 
        apr_pollfd_t pfd = { pool, APR_POLL_SOCKET, APR_POLLIN, 0,
238
 
                             { NULL }, NULL };
 
495
        apr_pollfd_t pfd = { 0 };
 
496
 
 
497
        pfd.desc_type = APR_POLL_SOCKET;
239
498
        pfd.desc.s = servctx->serv_sock;
 
499
        pfd.reqevents = APR_POLLIN;
 
500
 
240
501
        status = apr_pollset_add(pollset, &pfd);
241
502
        if (status != APR_SUCCESS)
242
503
            goto cleanup;
253
514
            if (status != APR_SUCCESS)
254
515
                goto cleanup;
255
516
 
 
517
            serf__log_skt(TEST_VERBOSE, __FILE__, servctx->client_sock,
 
518
                          "server/proxy accepted incoming connection.\n");
 
519
 
 
520
 
256
521
            apr_socket_opt_set(servctx->client_sock, APR_SO_NONBLOCK, 1);
257
522
            apr_socket_timeout_set(servctx->client_sock, 0);
258
523
 
261
526
        }
262
527
 
263
528
        if (desc->desc.s == servctx->client_sock) {
 
529
            if (servctx->handshake) {
 
530
                status = servctx->handshake(servctx);
 
531
                if (status)
 
532
                    goto cleanup;
 
533
            }
 
534
 
264
535
            /* Replay data to socket. */
265
536
            status = replay(servctx, desc->rtnevents, pool);
266
537
 
267
538
            if (APR_STATUS_IS_EOF(status)) {
268
539
                apr_socket_close(servctx->client_sock);
269
540
                servctx->client_sock = NULL;
 
541
                if (servctx->reset)
 
542
                    servctx->reset(servctx);
 
543
 
 
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;
 
549
                    goto cleanup;
 
550
                }
 
551
            }
 
552
            else if (APR_STATUS_IS_EAGAIN(status)) {
 
553
                status = APR_SUCCESS;
 
554
            }
 
555
            else if (status != APR_SUCCESS) {
 
556
                /* Real error. */
 
557
                goto cleanup;
 
558
            }
 
559
        }
 
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;
270
566
            }
271
567
            else if (APR_STATUS_IS_EAGAIN(status)) {
272
568
                status = APR_SUCCESS;
286
582
    return status;
287
583
}
288
584
 
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,
298
 
                               apr_int32_t options,
299
 
                               apr_pool_t *pool)
 
585
 
 
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.
 
589
 */
 
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,
 
596
                       apr_int32_t options,
 
597
                       apr_pool_t *pool)
300
598
{
301
 
    apr_status_t status;
302
 
    apr_socket_t *serv_sock;
303
599
    serv_ctx_t *servctx;
304
600
 
305
601
    servctx = apr_pcalloc(pool, sizeof(*servctx));
 
602
    apr_pool_cleanup_register(pool, servctx,
 
603
                              cleanup_server,
 
604
                              apr_pool_cleanup_null);
306
605
    *servctx_p = servctx;
307
606
 
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;
315
615
 
 
616
    /* Start replay from first action. */
 
617
    servctx->cur_action = 0;
 
618
    servctx->action_buf_pos = 0;
 
619
    servctx->outstanding_responses = 0;
 
620
 
 
621
    servctx->read = socket_read;
 
622
    servctx->send = socket_write;
 
623
 
 
624
    *servctx_p = servctx;
 
625
}
 
626
 
 
627
apr_status_t start_test_server(serv_ctx_t *servctx)
 
628
{
 
629
    apr_status_t status;
 
630
    apr_socket_t *serv_sock;
 
631
 
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,
319
 
                               pool);
 
634
    status = apr_socket_create(&serv_sock, servctx->serv_addr->family,
 
635
                               SOCK_STREAM, 0,
 
636
                               servctx->pool);
320
637
#else
321
 
    status = apr_socket_create(&serv_sock, address->family, SOCK_STREAM, pool);
 
638
    status = apr_socket_create(&serv_sock, servctx->serv_addr->family,
 
639
                               SOCK_STREAM,
 
640
                               servctx->pool);
322
641
#endif
323
642
 
324
643
    if (status != APR_SUCCESS)
332
651
    if (status != APR_SUCCESS)
333
652
        return status;
334
653
 
335
 
    /* Start replay from first action. */
336
 
    servctx->cur_action = 0;
337
 
    servctx->action_buf_pos = 0;
338
 
    servctx->outstanding_responses = 0;
339
 
 
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)
343
657
        return status;
344
658
 
345
659
    servctx->serv_sock = serv_sock;
346
660
    servctx->client_sock = NULL;
347
 
    return APR_SUCCESS;
348
 
}
349
 
 
350
 
apr_status_t test_server_destroy(serv_ctx_t *servctx, apr_pool_t *pool)
351
 
{
352
 
    apr_socket_close(servctx->serv_sock);
353
 
 
354
 
    if (servctx->client_sock) {
355
 
        apr_socket_close(servctx->client_sock);
356
 
    }
357
661
 
358
662
    return APR_SUCCESS;
359
663
}