72
75
serf_connection_t *conn = data;
77
serf__log(CONN_VERBOSE, __FILE__, "cleaning up connection 0x%x\n",
74
79
serf_connection_close(conn);
76
81
return APR_SUCCESS;
84
/* Check if there is data waiting to be sent over the socket. This can happen
86
- The connection queue has atleast one request with unwritten data.
87
- All requests are written and the ssl layer wrote some data while reading
88
the response. This can happen when the server triggers a renegotiation,
89
e.g. after the first and only request on that connection was received.
90
Returns 1 if data is pending on CONN, NULL if not.
91
If NEXT_REQ is not NULL, it will be filled in with the next available request
92
with unwritten data. */
94
request_or_data_pending(serf_request_t **next_req, serf_connection_t *conn)
96
serf_request_t *request = conn->requests;
98
while (request != NULL && request->req_bkt == NULL &&
99
request->writing_started)
100
request = request->next;
105
if (request != NULL) {
107
} else if (conn->ostream_head) {
112
status = serf_bucket_peek(conn->ostream_head, &dummy,
114
if (!SERF_BUCKET_READ_ERROR(status) && len) {
115
serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt,
116
"All requests written but still data pending.\n");
79
124
/* Update the pollset for this connection. We tweak the pollset based on
80
125
* whether we want to read and/or write, given conditions within the
81
126
* connection. If the connection is not (yet) in the pollset, then it
104
149
/* Now put it back in with the correct read/write values. */
105
150
desc.reqevents = APR_POLLHUP | APR_POLLERR;
106
if (conn->requests) {
151
if (conn->requests &&
152
conn->state != SERF_CONN_INIT) {
107
153
/* If there are any outstanding events, then we want to read. */
108
154
/* ### not true. we only want to read IF we have sent some data */
109
155
desc.reqevents |= APR_POLLIN;
111
/* If the connection has unwritten data, or there are any requests
112
* that still have buckets to write out, then we want to write.
115
desc.reqevents |= APR_POLLOUT;
117
serf_request_t *request = conn->requests;
119
if ((conn->probable_keepalive_limit &&
120
conn->completed_requests > conn->probable_keepalive_limit) ||
121
(conn->max_outstanding_requests &&
122
conn->completed_requests - conn->completed_responses >=
157
/* Don't write if OpenSSL told us that it needs to read data first. */
158
if (conn->stop_writing != 1) {
160
/* If the connection is not closing down and
161
* has unwritten data or
162
* there are any requests that still have buckets to write out,
163
* then we want to write.
166
conn->state != SERF_CONN_CLOSING)
167
desc.reqevents |= APR_POLLOUT;
170
if ((conn->probable_keepalive_limit &&
171
conn->completed_requests > conn->probable_keepalive_limit) ||
172
(conn->max_outstanding_requests &&
173
conn->completed_requests - conn->completed_responses >=
123
174
conn->max_outstanding_requests)) {
124
/* we wouldn't try to write any way right now. */
127
while (request != NULL && request->req_bkt == NULL &&
129
request = request->next;
175
/* we wouldn't try to write any way right now. */
177
else if (request_or_data_pending(NULL, conn)) {
131
178
desc.reqevents |= APR_POLLOUT;
220
static void destroy_ostream(serf_connection_t *conn)
222
if (conn->ostream_head != NULL) {
223
serf_bucket_destroy(conn->ostream_head);
224
conn->ostream_head = NULL;
225
conn->ostream_tail = NULL;
229
static apr_status_t detect_eof(void *baton, serf_bucket_t *aggregate_bucket)
231
serf_connection_t *conn = baton;
236
static apr_status_t do_conn_setup(serf_connection_t *conn)
239
serf_bucket_t *ostream;
241
if (conn->ostream_head == NULL) {
242
conn->ostream_head = serf_bucket_aggregate_create(conn->allocator);
245
if (conn->ostream_tail == NULL) {
246
conn->ostream_tail = serf__bucket_stream_create(conn->allocator,
251
ostream = conn->ostream_tail;
253
status = (*conn->setup)(conn->skt,
259
/* extra destroy here since it wasn't added to the head bucket yet. */
260
serf_bucket_destroy(conn->ostream_tail);
261
destroy_ostream(conn);
265
serf_bucket_aggregate_append(conn->ostream_head,
271
/* Set up the input and output stream buckets.
272
When a tunnel over an http proxy is needed, create a socket bucket and
273
empty aggregate bucket for sending and receiving unencrypted requests
276
After the tunnel is there, or no tunnel was needed, ask the application
277
to create the input and output buckets, which should take care of the
281
static apr_status_t prepare_conn_streams(serf_connection_t *conn,
282
serf_bucket_t **istream,
283
serf_bucket_t **ostreamt,
284
serf_bucket_t **ostreamh)
288
if (conn->stream == NULL) {
289
conn->latency = apr_time_now() - conn->connect_time;
292
/* Do we need a SSL tunnel first? */
293
if (conn->state == SERF_CONN_CONNECTED) {
294
/* If the connection does not have an associated bucket, then
295
* call the setup callback to get one.
297
if (conn->stream == NULL) {
298
status = do_conn_setup(conn);
303
*ostreamt = conn->ostream_tail;
304
*ostreamh = conn->ostream_head;
305
*istream = conn->stream;
307
/* SSL tunnel needed and not set up yet, get a direct unencrypted
308
stream for this socket */
309
if (conn->stream == NULL) {
310
*istream = serf_bucket_socket_create(conn->skt,
313
/* Don't create the ostream bucket chain including the ssl_encrypt
314
bucket yet. This ensure the CONNECT request is sent unencrypted
316
*ostreamt = *ostreamh = conn->ssltunnel_ostream;
172
322
/* Create and connect sockets for any connections which don't have them
173
323
* yet. This is the core of our lazy-connect behavior.
199
349
apr_pool_clear(conn->skt_pool);
200
350
apr_pool_cleanup_register(conn->skt_pool, conn, clean_skt, clean_skt);
202
/* Do we have to connect to a proxy server? */
203
if (ctx->proxy_address)
204
serv_addr = ctx->proxy_address;
206
serv_addr = conn->address;
208
if ((status = apr_socket_create(&skt, serv_addr->family,
352
status = apr_socket_create(&skt, conn->address->family,
210
354
#if APR_MAJOR_VERSION > 0
213
conn->skt_pool)) != APR_SUCCESS)
358
serf__log(SOCK_VERBOSE, __FILE__,
359
"created socket for conn 0x%x, status %d\n", conn, status);
360
if (status != APR_SUCCESS)
216
363
/* Set the socket to be non-blocking */
225
372
/* Configured. Store it into the connection now. */
375
/* Remember time when we started connecting to server to calculate
377
conn->connect_time = apr_time_now();
228
379
/* Now that the socket is set up, let's connect it. This should
229
380
* return immediately.
231
if ((status = apr_socket_connect(skt,
232
serv_addr)) != APR_SUCCESS) {
382
status = apr_socket_connect(skt, conn->address);
383
serf__log_skt(SOCK_VERBOSE, __FILE__, skt,
384
"connected socket for conn 0x%x, status %d\n",
386
if (status != APR_SUCCESS) {
233
387
if (!APR_STATUS_IS_EINPROGRESS(status))
242
396
prepare this connection (it might be possible to skip some
243
397
part of the handshaking). */
244
398
if (ctx->proxy_address) {
245
if (conn->ctx->proxy_authn_info.scheme)
246
conn->ctx->proxy_authn_info.scheme->init_conn_func(407, conn,
399
authn_info = &ctx->proxy_authn_info;
400
if (authn_info->scheme) {
401
authn_info->scheme->init_conn_func(authn_info->scheme, 407,
250
if (conn->ctx->authn_info.scheme)
251
conn->ctx->authn_info.scheme->init_conn_func(401, conn,
406
authn_info = serf__get_authn_info_for_server(conn);
407
if (authn_info->scheme) {
408
authn_info->scheme->init_conn_func(authn_info->scheme, 401,
254
412
/* Does this connection require a SSL tunnel over the proxy? */
255
413
if (ctx->proxy_address && strcmp(conn->host_info.scheme, "https") == 0)
256
414
serf__ssltunnel_connect(conn);
416
serf_bucket_t *dummy1, *dummy2;
258
418
conn->state = SERF_CONN_CONNECTED;
420
status = prepare_conn_streams(conn, &conn->stream,
261
428
return APR_SUCCESS;
264
static apr_status_t no_more_writes(serf_connection_t *conn,
265
serf_request_t *request)
431
static apr_status_t no_more_writes(serf_connection_t *conn)
267
433
/* Note that we should hold new requests until we open our new socket. */
268
434
conn->state = SERF_CONN_CLOSING;
270
/* We can take the *next* request in our list and assume it hasn't
271
* been written yet and 'save' it for the new socket.
273
conn->hold_requests = request->next;
274
conn->hold_requests_tail = conn->requests_tail;
275
request->next = NULL;
276
conn->requests_tail = request;
435
serf__log(CONN_VERBOSE, __FILE__, "stop writing on conn 0x%x\n",
278
438
/* Clear our iovec. */
279
439
conn->vec_len = 0;
412
563
serf_context_t *ctx = conn->ctx;
413
564
apr_status_t status;
414
serf_request_t *old_reqs, *held_reqs, *held_reqs_tail;
565
serf_request_t *old_reqs;
416
567
conn->probable_keepalive_limit = conn->completed_responses;
417
568
conn->completed_requests = 0;
418
569
conn->completed_responses = 0;
420
571
old_reqs = conn->requests;
421
held_reqs = conn->hold_requests;
422
held_reqs_tail = conn->hold_requests_tail;
424
if (conn->state == SERF_CONN_CLOSING) {
425
conn->hold_requests = NULL;
426
conn->hold_requests_tail = NULL;
429
573
conn->requests = NULL;
430
574
conn->requests_tail = NULL;
576
/* Handle all outstanding requests. These have either not been written yet,
577
or have been written but the expected reply wasn't received yet. */
432
578
while (old_reqs) {
433
579
/* If we haven't started to write the connection, bring it over
434
* unchanged to our new socket. Otherwise, call the cancel function.
580
* unchanged to our new socket.
581
* Do not copy a CONNECT request to the new connection, the ssl tunnel
582
* setup code will create a new CONNECT request already.
436
if (requeue_requests && !old_reqs->written) {
584
if (requeue_requests && !old_reqs->writing_started &&
585
!old_reqs->ssltunnel) {
437
587
serf_request_t *req = old_reqs;
438
588
old_reqs = old_reqs->next;
439
589
req->next = NULL;
440
590
link_requests(&conn->requests, &conn->requests_tail, req);
593
/* Request has been consumed, or we don't want to requeue the
594
request. Either way, inform the application that the request
443
596
cancel_request(old_reqs, &old_reqs, requeue_requests);
447
if (conn->requests_tail) {
448
conn->requests_tail->next = held_reqs;
451
conn->requests = held_reqs;
453
if (held_reqs_tail) {
454
conn->requests_tail = held_reqs_tail;
600
/* Requests queue has been prepared for a new socket, close the old one. */
457
601
if (conn->skt != NULL) {
458
602
remove_connection(ctx, conn);
459
603
status = apr_socket_close(conn->skt);
604
serf__log_skt(SOCK_VERBOSE, __FILE__, conn->skt,
605
"closed socket, status %d\n", status);
460
606
if (conn->closed != NULL) {
461
607
handle_conn_closed(conn, status);
494
642
status = apr_socket_sendv(conn->skt, conn->vec,
495
643
conn->vec_len, &written);
644
if (status && !APR_STATUS_IS_EAGAIN(status))
645
serf__log_skt(SOCK_VERBOSE, __FILE__, conn->skt,
646
"socket_sendv error %d\n", status);
497
648
/* did we write everything? */
499
650
apr_size_t len = 0;
653
serf__log_skt(SOCK_MSG_VERBOSE, __FILE__, conn->skt,
654
"--- socket_sendv:\n");
502
656
for (i = 0; i < conn->vec_len; i++) {
503
657
len += conn->vec[i].iov_len;
504
658
if (written < len) {
659
serf__log_nopref(SOCK_MSG_VERBOSE, "%.*s",
660
conn->vec[i].iov_len - (len - written),
661
conn->vec[i].iov_base);
506
663
memmove(conn->vec, &conn->vec[i],
507
664
sizeof(struct iovec) * (conn->vec_len - i));
510
667
conn->vec[0].iov_base = (char *)conn->vec[0].iov_base + (conn->vec[0].iov_len - (len - written));
511
668
conn->vec[0].iov_len = len - written;
671
serf__log_nopref(SOCK_MSG_VERBOSE, "%.*s",
672
conn->vec[i].iov_len, conn->vec[i].iov_base);
515
675
if (len == written) {
516
676
conn->vec_len = 0;
678
serf__log_nopref(SOCK_MSG_VERBOSE, "-(%d)-\n", written);
519
680
/* Log progress information */
520
681
serf__context_progress_delta(conn->ctx, 0, written);
526
static apr_status_t detect_eof(void *baton, serf_bucket_t *aggregate_bucket)
528
serf_connection_t *conn = baton;
533
static apr_status_t do_conn_setup(serf_connection_t *conn)
687
static apr_status_t setup_request(serf_request_t *request)
689
serf_connection_t *conn = request->conn;
535
690
apr_status_t status;
536
serf_bucket_t *ostream;
538
if (conn->ostream_head == NULL) {
539
conn->ostream_head = serf_bucket_aggregate_create(conn->allocator);
542
if (conn->ostream_tail == NULL) {
543
conn->ostream_tail = serf__bucket_stream_create(conn->allocator,
548
ostream = conn->ostream_tail;
550
status = (*conn->setup)(conn->skt,
556
/* extra destroy here since it wasn't added to the head bucket yet. */
557
serf_bucket_destroy(conn->ostream_tail);
558
destroy_ostream(conn);
562
serf_bucket_aggregate_append(conn->ostream_head,
692
/* Now that we are about to serve the request, allocate a pool. */
693
apr_pool_create(&request->respool, conn->pool);
694
request->allocator = serf_bucket_allocator_create(request->respool,
696
apr_pool_cleanup_register(request->respool, request,
697
clean_resp, clean_resp);
699
/* Fill in the rest of the values for the request. */
700
status = request->setup(request, request->setup_baton,
703
&request->acceptor_baton,
705
&request->handler_baton,
568
/* Set up the input and output stream buckets.
569
When a tunnel over an http proxy is needed, create a socket bucket and
570
empty aggregate bucket for sending and receiving unencrypted requests
573
After the tunnel is there, or no tunnel was needed, ask the application
574
to create the input and output buckets, which should take care of the
578
static apr_status_t prepare_conn_streams(serf_connection_t *conn,
579
serf_bucket_t **istream,
580
serf_bucket_t **ostreamt,
581
serf_bucket_t **ostreamh)
585
/* Do we need a SSL tunnel first? */
586
if (conn->state == SERF_CONN_CONNECTED) {
587
/* If the connection does not have an associated bucket, then
588
* call the setup callback to get one.
590
if (conn->stream == NULL) {
591
status = do_conn_setup(conn);
596
*ostreamt = conn->ostream_tail;
597
*ostreamh = conn->ostream_head;
598
*istream = conn->stream;
600
/* SSL tunnel needed and not set up yet, get a direct unencrypted
601
stream for this socket */
602
if (conn->stream == NULL) {
603
*istream = serf_bucket_socket_create(conn->skt,
606
/* Don't create the ostream bucket chain including the ssl_encrypt
607
bucket yet. This ensure the CONNECT request is sent unencrypted
609
*ostreamt = *ostreamh = conn->ssltunnel_ostream;
615
710
/* write data out to the connection */
616
711
static apr_status_t write_to_connection(serf_connection_t *conn)
618
serf_request_t *request = conn->requests;
620
713
if (conn->probable_keepalive_limit &&
621
714
conn->completed_requests > conn->probable_keepalive_limit) {
627
720
return APR_SUCCESS;
630
/* Find a request that has data which needs to be delivered. */
631
while (request != NULL &&
632
request->req_bkt == NULL && request->written)
633
request = request->next;
635
/* assert: request != NULL || conn->vec_len */
637
723
/* Keep reading and sending until we run out of stuff to read, or
638
724
* writing would block.
727
serf_request_t *request;
641
728
int stop_reading = 0;
642
729
apr_status_t status;
643
730
apr_status_t read_status;
644
serf_bucket_t *ostreamt, *ostreamh;
731
serf_bucket_t *ostreamt;
732
serf_bucket_t *ostreamh;
645
733
int max_outstanding_requests = conn->max_outstanding_requests;
647
735
/* If we're setting up an ssl tunnel, we can't send real requests
679
769
/* We may need to move forward to a request which has something
682
while (request != NULL &&
683
request->req_bkt == NULL && request->written)
684
request = request->next;
686
if (request == NULL) {
772
if (!request_or_data_pending(&request, conn)) {
687
773
/* No more requests (with data) are registered with the
688
* connection. Let's update the pollset so that we don't
689
* try to write to this socket again.
774
* connection, and no data is pending on the outgoing stream.
775
* Let's update the pollset so that we don't try to write to this
691
778
conn->dirty_conn = 1;
692
779
conn->ctx->dirty_pollset = 1;
701
if (request->req_bkt == NULL) {
702
/* Now that we are about to serve the request, allocate a pool. */
703
apr_pool_create(&request->respool, conn->pool);
704
request->allocator = serf_bucket_allocator_create(request->respool,
706
apr_pool_cleanup_register(request->respool, request,
707
clean_resp, clean_resp);
709
/* Fill in the rest of the values for the request. */
710
read_status = request->setup(request, request->setup_baton,
713
&request->acceptor_baton,
715
&request->handler_baton,
719
/* Something bad happened. Propagate any errors. */
723
request->written = 1;
724
serf_bucket_aggregate_append(ostreamt, request->req_bkt);
789
if (request->req_bkt == NULL) {
790
read_status = setup_request(request);
792
/* Something bad happened. Propagate any errors. */
797
if (!request->writing_started) {
798
request->writing_started = 1;
799
serf_bucket_aggregate_append(ostreamt, request->req_bkt);
727
803
/* ### optimize at some point by using read_for_sendfile */
804
/* TODO: now that read_iovec will effectively try to return as much
805
data as available, we probably don't want to read ALL_AVAIL, but
806
a lower number, like the size of one or a few TCP packets, the
807
available TCP buffer size ... */
728
808
read_status = serf_bucket_read_iovec(ostreamh,
729
809
SERF_READ_ALL_AVAIL,
734
814
if (!conn->hit_eof) {
735
if (APR_STATUS_IS_EAGAIN(read_status) ||
736
read_status == SERF_ERROR_WAIT_CONN) {
815
if (APR_STATUS_IS_EAGAIN(read_status)) {
737
816
/* We read some stuff, but should not try to read again. */
738
817
stop_reading = 1;
819
else if (read_status == SERF_ERROR_WAIT_CONN) {
820
/* The bucket told us that it can't provide more data until
821
more data is read from the socket. This normally happens
822
during a SSL handshake.
740
/* ### we should avoid looking for writability for a while so
741
### that (hopefully) something will appear in the bucket so
742
### we can actually write something. otherwise, we could
743
### end up in a CPU spin: socket wants something, but we
744
### don't have anything (and keep returning EAGAIN)
824
We should avoid looking for writability for a while so
825
that (hopefully) something will appear in the bucket so
826
we can actually write something. otherwise, we could
827
end up in a CPU spin: socket wants something, but we
828
don't have anything (and keep returning EAGAIN)
830
conn->stop_writing = 1;
831
conn->dirty_conn = 1;
832
conn->ctx->dirty_pollset = 1;
747
834
else if (read_status && !APR_STATUS_IS_EOF(read_status)) {
748
835
/* Something bad happened. Propagate any errors. */
761
848
if (APR_STATUS_IS_EAGAIN(status))
762
849
return APR_SUCCESS;
763
850
if (APR_STATUS_IS_EPIPE(status))
764
return no_more_writes(conn, request);
765
if (APR_STATUS_IS_ECONNRESET(status)) {
766
return no_more_writes(conn, request);
851
return no_more_writes(conn);
852
if (APR_STATUS_IS_ECONNRESET(status) ||
853
APR_STATUS_IS_ECONNABORTED(status)) {
854
return no_more_writes(conn);
972
serf__provide_credentials(serf_context_t *ctx,
975
serf_request_t *request, void *baton,
976
int code, const char *authn_type,
980
serf_connection_t *conn = request->conn;
981
serf_request_t *authn_req = request;
984
if (request->ssltunnel == 1 &&
985
conn->state == SERF_CONN_SETUP_SSLTUNNEL) {
986
/* This is a CONNECT request to set up an SSL tunnel over a proxy.
987
This request is created by serf, so if the proxy requires
988
authentication, we can't ask the application for credentials with
991
Solution: setup the first request created by the application on
992
this connection, and use that request and its handler_baton to
993
call back to the application. */
995
authn_req = request->next;
996
/* assert: app_request != NULL */
1000
if (!authn_req->req_bkt) {
1001
apr_status_t status;
1003
status = setup_request(authn_req);
1004
/* If we can't setup a request, don't bother setting up the
1011
/* Ask the application. */
1012
status = (*ctx->cred_cb)(username, password,
1013
authn_req, authn_req->handler_baton,
1014
code, authn_type, realm, pool);
879
1021
/* read data from the connection */
880
1022
static apr_status_t read_from_connection(serf_connection_t *conn)
929
1079
* 2) Doing the initial SSL handshake - we'll get EAGAIN
930
1080
* as the SSL buckets will hide the handshake from us
931
1081
* but not return any data.
1082
* 3) When the server sends us an SSL alert.
933
1084
* In these cases, we should not receive any actual user data.
935
* If we see an EOF (due to an expired timeout), we'll reset the
1086
* 4) When the server sends a error response, like 408 Request timeout.
1087
* This response should be passed to the application.
1089
* If we see an EOF (due to either an expired timeout or the server
1090
* sending the SSL 'close notify' shutdown alert), we'll reset the
936
1091
* connection and open a new one.
938
if (request->req_bkt || !request->written) {
1093
if (request->req_bkt || !request->writing_started) {
939
1094
const char *data;
942
status = serf_bucket_read(conn->stream, SERF_READ_ALL_AVAIL,
1097
status = serf_bucket_peek(conn->stream, &data, &len);
945
if (!status && len) {
946
status = APR_EGENERAL;
948
else if (APR_STATUS_IS_EOF(status)) {
1099
if (APR_STATUS_IS_EOF(status)) {
949
1100
reset_connection(conn, 1);
950
1101
status = APR_SUCCESS;
952
else if (APR_STATUS_IS_EAGAIN(status)) {
1104
else if (APR_STATUS_IS_EAGAIN(status) && !len) {
953
1105
status = APR_SUCCESS;
1107
} else if (status && !APR_STATUS_IS_EAGAIN(status)) {
1112
/* Unexpected response from the server */
959
1116
/* If the request doesn't have a response bucket, then call the
969
1126
status = handle_response(request, tmppool);
971
1128
/* Some systems will not generate a HUP poll event so we have to
972
* handle the ECONNRESET issue here.
1129
* handle the ECONNRESET issue and ECONNABORT here.
974
1131
if (APR_STATUS_IS_ECONNRESET(status) ||
1132
APR_STATUS_IS_ECONNABORTED(status) ||
975
1133
status == SERF_ERROR_REQUEST_LOST) {
976
reset_connection(conn, 1);
977
status = APR_SUCCESS;
1134
/* If the connection had ever been good, be optimistic & try again.
1135
* If it has never tried again (incl. a retry), fail.
1137
if (conn->completed_responses) {
1138
reset_connection(conn, 1);
1139
status = APR_SUCCESS;
1141
else if (status == SERF_ERROR_REQUEST_LOST) {
1142
status = SERF_ERROR_ABORTED_CONNECTION;
982
1148
* treat that as a success.
984
1150
if (APR_STATUS_IS_EAGAIN(status)) {
1151
/* It is possible that while reading the response, the ssl layer
1152
has prepared some data to send. If this was the last request,
1153
serf will not check for socket writability, so force this here.
1155
if (request_or_data_pending(&request, conn) && !request) {
1156
conn->dirty_conn = 1;
1157
conn->ctx->dirty_pollset = 1;
985
1159
status = APR_SUCCESS;
1004
/* The request has been fully-delivered, and the response has
1005
* been fully-read. Remove it from our queue and loop to read
1178
/* The response has been fully-read, so that means the request has
1179
* either been fully-delivered (most likely), or that we don't need to
1180
* write the rest of it anymore, e.g. when a 408 Request timeout was
1182
* Remove it from our queue and loop to read another response.
1008
1184
conn->requests = request->next;
1081
1257
if ((events & APR_POLLHUP) != 0) {
1082
1258
/* The connection got reset by the server. On Windows this can happen
1083
1259
when all data is read, so just cleanup the connection and open
1085
return reset_connection(conn, 1);
1261
If we haven't had any successful responses on this connection,
1262
then error out as it is likely a server issue. */
1263
if (conn->completed_responses) {
1264
return reset_connection(conn, 1);
1266
return SERF_ERROR_ABORTED_CONNECTION;
1087
1268
if ((events & APR_POLLERR) != 0) {
1088
1269
/* We might be talking to a buggy HTTP server that doesn't
1095
1276
if (conn->completed_requests && !conn->probable_keepalive_limit) {
1096
1277
return reset_connection(conn, 1);
1280
/* If possible, get the error from the platform's socket layer and
1281
convert it to an APR status code. */
1283
apr_os_sock_t osskt;
1284
if (!apr_os_sock_get(&osskt, conn->skt)) {
1286
apr_socklen_t l = sizeof(error);
1288
if (!getsockopt(osskt, SOL_SOCKET, SO_ERROR, (char*)&error,
1290
status = APR_FROM_OS_ERROR(error);
1292
/* Handle fallback for multi-homed servers.
1294
### Improve algorithm to find better than just 'next'?
1296
Current Windows versions already handle re-ordering for
1297
api users by using statistics on the recently failed
1298
connections to order the list of addresses. */
1299
if (conn->completed_requests == 0
1300
&& conn->address->next != NULL
1301
&& (APR_STATUS_IS_ECONNREFUSED(status)
1302
|| APR_STATUS_IS_TIMEUP(status)
1303
|| APR_STATUS_IS_ENETUNREACH(status))) {
1305
conn->address = conn->address->next;
1306
return reset_connection(conn, 1);
1098
1314
return APR_EGENERAL;
1100
1316
if ((events & APR_POLLOUT) != 0) {
1131
1348
conn->baton.u.conn = conn;
1132
1349
conn->hit_eof = 0;
1133
1350
conn->state = SERF_CONN_INIT;
1351
conn->latency = -1; /* unknown */
1135
1353
/* Create a subpool for our connection. */
1136
1354
apr_pool_create(&conn->skt_pool, conn->pool);
1138
1356
/* register a cleanup */
1139
apr_pool_cleanup_register(conn->pool, conn, clean_conn, apr_pool_cleanup_null);
1357
apr_pool_cleanup_register(conn->pool, conn, clean_conn,
1358
apr_pool_cleanup_null);
1141
1360
/* Add the connection to the context. */
1142
1361
*(serf_connection_t **)apr_array_push(ctx->conns) = conn;
1363
serf__log(CONN_VERBOSE, __FILE__, "created connection 0x%x\n",
1154
1376
void *closed_baton,
1155
1377
apr_pool_t *pool)
1157
apr_status_t status;
1379
apr_status_t status = APR_SUCCESS;
1158
1380
serf_connection_t *c;
1159
apr_sockaddr_t *host_address;
1161
/* Parse the url, store the address of the server. */
1162
status = apr_sockaddr_info_get(&host_address,
1164
APR_UNSPEC, host_info.port, 0, pool);
1381
apr_sockaddr_t *host_address = NULL;
1383
/* Set the port number explicitly, needed to create the socket later. */
1384
if (!host_info.port) {
1385
host_info.port = apr_uri_port_of_scheme(host_info.scheme);
1388
/* Only lookup the address of the server if no proxy server was
1390
if (!ctx->proxy_address) {
1391
status = apr_sockaddr_info_get(&host_address,
1393
APR_UNSPEC, host_info.port, 0, pool);
1168
1398
c = serf_connection_create(ctx, host_address, setup, setup_baton,
1169
1399
closed, closed_baton, pool);
1171
1401
/* We're not interested in the path following the hostname. */
1172
1402
c->host_url = apr_uri_unparse(c->pool,
1174
APR_URI_UNP_OMITPATHINFO);
1175
c->host_info = host_info;
1404
APR_URI_UNP_OMITPATHINFO |
1405
APR_URI_UNP_OMITUSERINFO);
1407
/* Store the host info without the path on the connection. */
1408
(void)apr_uri_parse(c->pool, c->host_url, &(c->host_info));
1409
if (!c->host_info.port) {
1410
c->host_info.port = apr_uri_port_of_scheme(c->host_info.scheme);
1203
1439
if (conn->skt != NULL) {
1204
1440
remove_connection(ctx, conn);
1205
1441
status = apr_socket_close(conn->skt);
1442
serf__log_skt(SOCK_VERBOSE, __FILE__, conn->skt,
1443
"closed socket, status %d\n",
1206
1445
if (conn->closed != NULL) {
1207
1446
handle_conn_closed(conn, status);
1240
1484
serf_connection_t *conn,
1241
1485
unsigned int max_requests)
1487
if (max_requests == 0)
1488
serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt,
1489
"Set max. nr. of outstanding requests for this "
1490
"connection to unlimited.\n");
1492
serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt,
1493
"Limit max. nr. of outstanding requests for this "
1494
"connection to %u.\n", max_requests);
1243
1496
conn->max_outstanding_requests = max_requests;
1258
1511
conn->async_handler_baton = handler_baton;
1514
static serf_request_t *
1515
create_request(serf_connection_t *conn,
1516
serf_request_setup_t setup,
1521
serf_request_t *request;
1523
request = serf_bucket_mem_alloc(conn->allocator, sizeof(*request));
1524
request->conn = conn;
1525
request->setup = setup;
1526
request->setup_baton = setup_baton;
1527
request->handler = NULL;
1528
request->respool = NULL;
1529
request->req_bkt = NULL;
1530
request->resp_bkt = NULL;
1531
request->priority = priority;
1532
request->writing_started = 0;
1533
request->ssltunnel = ssltunnel;
1534
request->next = NULL;
1535
request->auth_baton = NULL;
1262
1540
serf_request_t *serf_connection_request_create(
1263
1541
serf_connection_t *conn,
1267
1545
serf_request_t *request;
1269
request = serf_bucket_mem_alloc(conn->allocator, sizeof(*request));
1270
request->conn = conn;
1271
request->setup = setup;
1272
request->setup_baton = setup_baton;
1273
request->handler = NULL;
1274
request->respool = NULL;
1275
request->req_bkt = NULL;
1276
request->resp_bkt = NULL;
1277
request->priority = 0;
1278
request->written = 0;
1279
request->next = NULL;
1547
request = create_request(conn, setup, setup_baton,
1549
0 /* ssl tunnel */);
1281
1551
/* Link the request to the end of the request chain. */
1282
if (conn->state == SERF_CONN_CLOSING) {
1283
link_requests(&conn->hold_requests, &conn->hold_requests_tail, request);
1286
link_requests(&conn->requests, &conn->requests_tail, request);
1288
/* Ensure our pollset becomes writable in context run */
1289
conn->ctx->dirty_pollset = 1;
1290
conn->dirty_conn = 1;
1552
link_requests(&conn->requests, &conn->requests_tail, request);
1554
/* Ensure our pollset becomes writable in context run */
1555
conn->ctx->dirty_pollset = 1;
1556
conn->dirty_conn = 1;
1293
1558
return request;
1297
serf_request_t *serf_connection_priority_request_create(
1298
serf_connection_t *conn,
1299
serf_request_setup_t setup,
1561
static serf_request_t *
1562
priority_request_create(serf_connection_t *conn,
1564
serf_request_setup_t setup,
1302
1567
serf_request_t *request;
1303
1568
serf_request_t *iter, *prev;
1305
request = serf_bucket_mem_alloc(conn->allocator, sizeof(*request));
1306
request->conn = conn;
1307
request->setup = setup;
1308
request->setup_baton = setup_baton;
1309
request->handler = NULL;
1310
request->respool = NULL;
1311
request->req_bkt = NULL;
1312
request->resp_bkt = NULL;
1313
request->priority = 1;
1314
request->written = 0;
1315
request->next = NULL;
1570
request = create_request(conn, setup, setup_baton,
1317
/* Link the new request after the last written request, but before all
1318
upcoming requests. */
1319
if (conn->state == SERF_CONN_CLOSING) {
1320
iter = conn->hold_requests;
1323
iter = conn->requests;
1574
/* Link the new request after the last written request. */
1575
iter = conn->requests;
1327
1578
/* Find a request that has data which needs to be delivered. */
1328
while (iter != NULL && iter->req_bkt == NULL && iter->written) {
1579
while (iter != NULL && iter->req_bkt == NULL && iter->writing_started) {
1330
1581
iter = iter->next;
1333
/* Advance to next non priority request */
1334
while (iter != NULL && iter->priority) {
1584
/* A CONNECT request to setup an ssltunnel has absolute priority over all
1585
other requests on the connection, so:
1586
a. add it first to the queue
1587
b. ensure that other priority requests are added after the CONNECT
1589
if (!request->ssltunnel) {
1590
/* Advance to next non priority request */
1591
while (iter != NULL && iter->priority) {
1341
1599
prev->next = request;
1343
1601
request->next = iter;
1344
if (conn->state == SERF_CONN_CLOSING) {
1345
conn->hold_requests = request;
1348
conn->requests = request;
1602
conn->requests = request;
1352
if (conn->state != SERF_CONN_CLOSING) {
1353
/* Ensure our pollset becomes writable in context run */
1354
conn->ctx->dirty_pollset = 1;
1355
conn->dirty_conn = 1;
1605
/* Ensure our pollset becomes writable in context run */
1606
conn->ctx->dirty_pollset = 1;
1607
conn->dirty_conn = 1;
1358
1609
return request;
1612
serf_request_t *serf_connection_priority_request_create(
1613
serf_connection_t *conn,
1614
serf_request_setup_t setup,
1617
return priority_request_create(conn,
1618
0, /* not a ssltunnel CONNECT request */
1619
setup, setup_baton);
1622
serf_request_t *serf__ssltunnel_request_create(serf_connection_t *conn,
1623
serf_request_setup_t setup,
1626
return priority_request_create(conn,
1627
1, /* This is a ssltunnel CONNECT request */
1628
setup, setup_baton);
1362
1631
apr_status_t serf_request_cancel(serf_request_t *request)
1364
1633
return cancel_request(request, &request->conn->requests, 0);
1636
apr_status_t serf_request_is_written(serf_request_t *request)
1638
if (request->writing_started && !request->req_bkt)
1368
1644
apr_pool_t *serf_request_get_pool(const serf_request_t *request)
1405
1681
serf_bucket_t *req_bkt, *hdrs_bkt;
1406
1682
serf_connection_t *conn = request->conn;
1407
1683
serf_context_t *ctx = conn->ctx;
1686
ssltunnel = ctx->proxy_address &&
1687
(strcmp(conn->host_info.scheme, "https") == 0);
1409
1689
req_bkt = serf_bucket_request_create(method, uri, body, allocator);
1410
1690
hdrs_bkt = serf_bucket_request_get_headers(req_bkt);
1413
if (ctx->proxy_address && conn->host_url)
1692
/* Use absolute uri's in requests to a proxy. USe relative uri's in
1693
requests directly to a server or sent through an SSL tunnel. */
1694
if (ctx->proxy_address && conn->host_url &&
1695
!(ssltunnel && !request->ssltunnel)) {
1414
1697
serf_bucket_request_set_root(req_bkt, conn->host_url);
1416
1700
if (conn->host_info.hostinfo)
1417
1701
serf_bucket_headers_setn(hdrs_bkt, "Host",
1418
1702
conn->host_info.hostinfo);
1420
/* Setup server authorization headers */
1421
if (ctx->authn_info.scheme)
1422
ctx->authn_info.scheme->setup_request_func(401, conn, method, uri,
1704
/* Setup server authorization headers, unless this is a CONNECT request. */
1705
if (!request->ssltunnel) {
1706
serf__authn_info_t *authn_info;
1707
authn_info = serf__get_authn_info_for_server(conn);
1708
if (authn_info->scheme)
1709
authn_info->scheme->setup_request_func(HOST, 0, conn, request,
1425
/* Setup proxy authorization headers */
1426
if (ctx->proxy_authn_info.scheme)
1427
ctx->proxy_authn_info.scheme->setup_request_func(407, conn, method,
1714
/* Setup proxy authorization headers.
1715
Don't set these headers on the requests to the server if we're using
1716
an SSL tunnel, only on the CONNECT request to setup the tunnel. */
1717
if (ctx->proxy_authn_info.scheme) {
1718
if (strcmp(conn->host_info.scheme, "https") == 0) {
1719
if (request->ssltunnel)
1720
ctx->proxy_authn_info.scheme->setup_request_func(PROXY, 0, conn,
1725
ctx->proxy_authn_info.scheme->setup_request_func(PROXY, 0, conn,
1430
1732
return req_bkt;
1735
apr_interval_time_t serf_connection_get_latency(serf_connection_t *conn)
1737
if (conn->ctx->proxy_address) {
1738
/* Detecting network latency for proxied connection is not implemented
1743
return conn->latency;