39
39
static apr_status_t clean_resp(void *data)
41
serf_request_t *req = data;
41
serf_request_t *request = data;
43
/* The request's RESPOOL is being cleared. */
45
/* If the response has allocated some buckets, then destroy them (since
46
the bucket may hold resources other than memory in RESPOOL). Also
47
make sure to set their fields to NULL so connection closure does
48
not attempt to free them again. */
49
if (request->resp_bkt) {
50
serf_bucket_destroy(request->resp_bkt);
51
request->resp_bkt = NULL;
53
if (request->req_bkt) {
54
serf_bucket_destroy(request->req_bkt);
55
request->req_bkt = NULL;
58
/* ### should we worry about debug stuff, like that performed in
59
### destroy_request()? should we worry about calling req->handler
60
### to notify this "cancellation" due to pool clearing? */
43
62
/* This pool just got cleared/destroyed. Don't try to destroy the pool
44
* (again) when the request is canceled.
63
(again) when the request is canceled. */
64
request->respool = NULL;
48
66
return APR_SUCCESS;
232
250
if (conn->ctx->authn_info.scheme)
233
251
conn->ctx->authn_info.scheme->init_conn_func(401, conn,
254
/* Does this connection require a SSL tunnel over the proxy? */
255
if (ctx->proxy_address && strcmp(conn->host_info.scheme, "https") == 0)
256
serf__ssltunnel_connect(conn);
258
conn->state = SERF_CONN_CONNECTED;
237
261
return APR_SUCCESS;
241
265
serf_request_t *request)
243
267
/* Note that we should hold new requests until we open our new socket. */
268
conn->state = SERF_CONN_CLOSING;
246
270
/* We can take the *next* request in our list and assume it hasn't
247
271
* been written yet and 'save' it for the new socket.
304
328
if (request->resp_bkt) {
305
329
serf_debug__closed_conn(request->resp_bkt->allocator);
306
330
serf_bucket_destroy(request->resp_bkt);
331
request->resp_bkt = NULL;
308
333
if (request->req_bkt) {
309
334
serf_debug__closed_conn(request->req_bkt->allocator);
310
335
serf_bucket_destroy(request->req_bkt);
336
request->req_bkt = NULL;
313
339
serf_debug__bucket_alloc_check(request->allocator);
314
340
if (request->respool) {
341
/* ### unregister the pool cleanup for self? */
315
342
apr_pool_destroy(request->respool);
394
421
held_reqs = conn->hold_requests;
395
422
held_reqs_tail = conn->hold_requests_tail;
424
if (conn->state == SERF_CONN_CLOSING) {
398
425
conn->hold_requests = NULL;
399
426
conn->hold_requests_tail = NULL;
403
429
conn->requests = NULL;
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;
541
615
/* write data out to the connection */
542
616
static apr_status_t write_to_connection(serf_connection_t *conn)
563
641
int stop_reading = 0;
564
642
apr_status_t status;
565
643
apr_status_t read_status;
567
if (conn->max_outstanding_requests &&
644
serf_bucket_t *ostreamt, *ostreamh;
645
int max_outstanding_requests = conn->max_outstanding_requests;
647
/* If we're setting up an ssl tunnel, we can't send real requests
648
at yet, as they need to be encrypted and our encrypt buckets
649
aren't created yet as we still need to read the unencrypted
650
response of the CONNECT request. */
651
if (conn->state != SERF_CONN_CONNECTED)
652
max_outstanding_requests = 1;
654
if (max_outstanding_requests &&
568
655
conn->completed_requests -
569
conn->completed_responses >= conn->max_outstanding_requests) {
656
conn->completed_responses >= max_outstanding_requests) {
570
657
/* backoff for now. */
571
658
return APR_SUCCESS;
606
693
return APR_SUCCESS;
609
/* If the connection does not have an associated bucket, then
610
* call the setup callback to get one.
612
if (conn->stream == NULL) {
613
status = do_conn_setup(conn);
696
status = prepare_conn_streams(conn, &conn->stream, &ostreamt, &ostreamh);
619
701
if (request->req_bkt == NULL) {
641
723
request->written = 1;
642
serf_bucket_aggregate_append(conn->ostream_tail, request->req_bkt);
724
serf_bucket_aggregate_append(ostreamt, request->req_bkt);
645
727
/* ### optimize at some point by using read_for_sendfile */
646
read_status = serf_bucket_read_iovec(conn->ostream_head,
728
read_status = serf_bucket_read_iovec(ostreamh,
647
729
SERF_READ_ALL_AVAIL,
652
734
if (!conn->hit_eof) {
653
if (APR_STATUS_IS_EAGAIN(read_status)) {
735
if (APR_STATUS_IS_EAGAIN(read_status) ||
736
read_status == SERF_ERROR_WAIT_CONN) {
654
737
/* We read some stuff, but should not try to read again. */
655
738
stop_reading = 1;
690
conn->vec_len == 0) {
772
if (read_status == SERF_ERROR_WAIT_CONN) {
775
else if (read_status && conn->hit_eof && conn->vec_len == 0) {
691
776
/* If we hit the end of the request bucket and all of its data has
692
777
* been written, then clear it out to signify that we're done
693
778
* sending the request. On the next iteration through this loop:
728
814
static apr_status_t handle_response(serf_request_t *request,
729
815
apr_pool_t *pool)
817
apr_status_t status = APR_SUCCESS;
732
818
int consumed_response = 0;
734
820
/* Only enable the new authentication framework if the program has
810
896
/* Invoke response handlers until we have no more work. */
898
serf_bucket_t *dummy1, *dummy2;
812
900
apr_pool_clear(tmppool);
814
/* If the connection does not have an associated bucket, then
815
* call the setup callback to get one.
817
if (conn->stream == NULL) {
818
status = do_conn_setup(conn);
902
/* Only interested in the input stream here. */
903
status = prepare_conn_streams(conn, &conn->stream, &dummy1, &dummy2);
824
908
/* We have a different codepath when we can have async responses. */
935
1019
conn->completed_responses++;
1021
/* We've to rebuild pollset since completed_responses is changed. */
1022
conn->dirty_conn = 1;
1023
conn->ctx->dirty_pollset = 1;
937
1025
/* This means that we're being advised that the connection is done. */
938
1026
if (close_connection == SERF_ERROR_CLOSING) {
939
1027
reset_connection(conn, 1);
993
1081
if ((events & APR_POLLHUP) != 0) {
994
return APR_ECONNRESET;
1082
/* The connection got reset by the server. On Windows this can happen
1083
when all data is read, so just cleanup the connection and open
1085
return reset_connection(conn, 1);
996
1087
if ((events & APR_POLLERR) != 0) {
997
1088
/* We might be talking to a buggy HTTP server that doesn't
1002
1093
* http://issues.apache.org/bugzilla/show_bug.cgi?id=35292
1004
if (!conn->probable_keepalive_limit) {
1095
if (conn->completed_requests && !conn->probable_keepalive_limit) {
1005
1096
return reset_connection(conn, 1);
1007
1098
return APR_EGENERAL;
1039
1130
conn->baton.type = SERF_IO_CONN;
1040
1131
conn->baton.u.conn = conn;
1041
1132
conn->hit_eof = 0;
1133
conn->state = SERF_CONN_INIT;
1043
1135
/* Create a subpool for our connection. */
1044
1136
apr_pool_create(&conn->skt_pool, conn->pool);
1066
1158
serf_connection_t *c;
1067
1159
apr_sockaddr_t *host_address;
1069
/* Support for HTTPS proxies is not implemented yet. */
1070
if (ctx->proxy_address && strcmp(host_info.scheme, "https") == 0)
1071
return APR_ENOTIMPL;
1073
1161
/* Parse the url, store the address of the server. */
1074
1162
status = apr_sockaddr_info_get(&host_address,
1075
1163
host_info.hostname,
1186
1274
request->respool = NULL;
1187
1275
request->req_bkt = NULL;
1188
1276
request->resp_bkt = NULL;
1277
request->priority = 0;
1189
1278
request->written = 0;
1190
1279
request->next = NULL;
1192
1281
/* Link the request to the end of the request chain. */
1193
if (conn->closing) {
1282
if (conn->state == SERF_CONN_CLOSING) {
1194
1283
link_requests(&conn->hold_requests, &conn->hold_requests_tail, request);
1221
1310
request->respool = NULL;
1222
1311
request->req_bkt = NULL;
1223
1312
request->resp_bkt = NULL;
1313
request->priority = 1;
1224
1314
request->written = 0;
1225
1315
request->next = NULL;
1227
1317
/* Link the new request after the last written request, but before all
1228
1318
upcoming requests. */
1229
if (conn->closing) {
1319
if (conn->state == SERF_CONN_CLOSING) {
1230
1320
iter = conn->hold_requests;