1178431Sscf/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein 2178431Sscf * 3178431Sscf * Licensed under the Apache License, Version 2.0 (the "License"); 4178431Sscf * you may not use this file except in compliance with the License. 5178431Sscf * You may obtain a copy of the License at 6178431Sscf * 7178431Sscf * http://www.apache.org/licenses/LICENSE-2.0 8178431Sscf * 9178431Sscf * Unless required by applicable law or agreed to in writing, software 10178431Sscf * distributed under the License is distributed on an "AS IS" BASIS, 11178431Sscf * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12178431Sscf * See the License for the specific language governing permissions and 13178431Sscf * limitations under the License. 14178431Sscf */ 15178431Sscf 16178431Sscf#include <apr_pools.h> 17178431Sscf#include <apr_poll.h> 18178431Sscf#include <apr_version.h> 19178431Sscf#include <apr_portable.h> 20178431Sscf 21178431Sscf#include "serf.h" 22178431Sscf#include "serf_bucket_util.h" 23178431Sscf 24178431Sscf#include "serf_private.h" 25178431Sscf 26178431Sscf/* cleanup for sockets */ 27178431Sscfstatic apr_status_t clean_skt(void *data) 28178431Sscf{ 29178431Sscf serf_connection_t *conn = data; 30178431Sscf apr_status_t status = APR_SUCCESS; 31228545Sbapt 32228545Sbapt if (conn->skt) { 33184831Sscf serf__log_skt(SOCK_VERBOSE, __FILE__, conn->skt, "cleanup - "); 34228545Sbapt status = apr_socket_close(conn->skt); 35228545Sbapt conn->skt = NULL; 36228545Sbapt serf__log_nopref(SOCK_VERBOSE, "closed socket, status %d\n", status); 37178431Sscf } 38178431Sscf 39184831Sscf return status; 40228545Sbapt} 41178431Sscf 42178431Sscfstatic apr_status_t clean_resp(void *data) 43178431Sscf{ 44178431Sscf serf_request_t *request = data; 45228545Sbapt 46178431Sscf /* The request's RESPOOL is being cleared. */ 47228545Sbapt 48228545Sbapt /* If the response has allocated some buckets, then destroy them (since 49228545Sbapt the bucket may hold resources other than memory in RESPOOL). Also 50228545Sbapt make sure to set their fields to NULL so connection closure does 51228545Sbapt not attempt to free them again. */ 52247919Sdb if (request->resp_bkt) { 53248102Sdb serf_bucket_destroy(request->resp_bkt); 54228545Sbapt request->resp_bkt = NULL; 55178431Sscf } 56228545Sbapt if (request->req_bkt) { 57228545Sbapt serf_bucket_destroy(request->req_bkt); 58228545Sbapt request->req_bkt = NULL; 59228545Sbapt } 60228545Sbapt 61242319Sbapt /* ### should we worry about debug stuff, like that performed in 62228545Sbapt ### destroy_request()? should we worry about calling req->handler 63228545Sbapt ### to notify this "cancellation" due to pool clearing? */ 64228545Sbapt 65228545Sbapt /* This pool just got cleared/destroyed. Don't try to destroy the pool 66228545Sbapt (again) when the request is canceled. */ 67228545Sbapt request->respool = NULL; 68228545Sbapt 69228545Sbapt return APR_SUCCESS; 70228545Sbapt} 71228545Sbapt 72228545Sbapt/* cleanup for conns */ 73228545Sbaptstatic apr_status_t clean_conn(void *data) 74228545Sbapt{ 75228545Sbapt serf_connection_t *conn = data; 76228545Sbapt 77228545Sbapt serf__log(CONN_VERBOSE, __FILE__, "cleaning up connection 0x%x\n", 78228545Sbapt conn); 79228545Sbapt serf_connection_close(conn); 80228545Sbapt 81228545Sbapt return APR_SUCCESS; 82228545Sbapt} 83228545Sbapt 84228545Sbapt/* Check if there is data waiting to be sent over the socket. This can happen 85228545Sbapt in two situations: 86228545Sbapt - The connection queue has atleast one request with unwritten data. 87242319Sbapt - All requests are written and the ssl layer wrote some data while reading 88228545Sbapt the response. This can happen when the server triggers a renegotiation, 89228545Sbapt e.g. after the first and only request on that connection was received. 90228545Sbapt Returns 1 if data is pending on CONN, NULL if not. 91228545Sbapt If NEXT_REQ is not NULL, it will be filled in with the next available request 92228545Sbapt with unwritten data. */ 93228545Sbaptstatic int 94228545Sbaptrequest_or_data_pending(serf_request_t **next_req, serf_connection_t *conn) 95228545Sbapt{ 96228545Sbapt serf_request_t *request = conn->requests; 97228545Sbapt 98228545Sbapt while (request != NULL && request->req_bkt == NULL && 99228545Sbapt request->writing_started) 100228545Sbapt request = request->next; 101228545Sbapt 102228545Sbapt if (next_req) 103228545Sbapt *next_req = request; 104244744Sbapt 105244735Sbapt if (request != NULL) { 106228545Sbapt return 1; 107228545Sbapt } else if (conn->ostream_head) { 108228545Sbapt const char *dummy; 109228545Sbapt apr_size_t len; 110228545Sbapt apr_status_t status; 111228545Sbapt 112228545Sbapt status = serf_bucket_peek(conn->ostream_head, &dummy, 113228545Sbapt &len); 114228545Sbapt if (!SERF_BUCKET_READ_ERROR(status) && len) { 115228545Sbapt serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt, 116228545Sbapt "All requests written but still data pending.\n"); 117228545Sbapt return 1; 118228545Sbapt } 119228545Sbapt } 120228545Sbapt 121228545Sbapt return 0; 122228545Sbapt} 123228545Sbapt 124228545Sbapt/* Update the pollset for this connection. We tweak the pollset based on 125228545Sbapt * whether we want to read and/or write, given conditions within the 126228545Sbapt * connection. If the connection is not (yet) in the pollset, then it 127228545Sbapt * will be added. 128228545Sbapt */ 129228545Sbaptapr_status_t serf__conn_update_pollset(serf_connection_t *conn) 130228545Sbapt{ 131228545Sbapt serf_context_t *ctx = conn->ctx; 132228545Sbapt apr_status_t status; 133228545Sbapt apr_pollfd_t desc = { 0 }; 134228545Sbapt 135228545Sbapt if (!conn->skt) { 136228545Sbapt return APR_SUCCESS; 137228545Sbapt } 138228545Sbapt 139228545Sbapt /* Remove the socket from the poll set. */ 140228545Sbapt desc.desc_type = APR_POLL_SOCKET; 141228545Sbapt desc.desc.s = conn->skt; 142228545Sbapt desc.reqevents = conn->reqevents; 143228545Sbapt 144310173Sasomers status = ctx->pollset_rm(ctx->pollset_baton, 145228545Sbapt &desc, conn); 146228545Sbapt if (status && !APR_STATUS_IS_NOTFOUND(status)) 147228545Sbapt return status; 148228545Sbapt 149228545Sbapt /* Now put it back in with the correct read/write values. */ 150228545Sbapt desc.reqevents = APR_POLLHUP | APR_POLLERR; 151228545Sbapt if (conn->requests && 152228545Sbapt conn->state != SERF_CONN_INIT) { 153228545Sbapt /* If there are any outstanding events, then we want to read. */ 154228545Sbapt /* ### not true. we only want to read IF we have sent some data */ 155228545Sbapt desc.reqevents |= APR_POLLIN; 156228545Sbapt 157228545Sbapt /* Don't write if OpenSSL told us that it needs to read data first. */ 158228545Sbapt if (conn->stop_writing != 1) { 159228545Sbapt 160228545Sbapt /* If the connection is not closing down and 161228545Sbapt * has unwritten data or 162228545Sbapt * there are any requests that still have buckets to write out, 163228545Sbapt * then we want to write. 164228545Sbapt */ 165228545Sbapt if (conn->vec_len && 166228545Sbapt conn->state != SERF_CONN_CLOSING) 167310480Sdes desc.reqevents |= APR_POLLOUT; 168228545Sbapt else { 169228545Sbapt 170310480Sdes if ((conn->probable_keepalive_limit && 171228545Sbapt conn->completed_requests > conn->probable_keepalive_limit) || 172310480Sdes (conn->max_outstanding_requests && 173228545Sbapt conn->completed_requests - conn->completed_responses >= 174274082Sbapt conn->max_outstanding_requests)) { 175274082Sbapt /* we wouldn't try to write any way right now. */ 176274082Sbapt } 177274082Sbapt else if (request_or_data_pending(NULL, conn)) { 178274082Sbapt desc.reqevents |= APR_POLLOUT; 179228545Sbapt } 180228545Sbapt } 181274082Sbapt } 182274082Sbapt } 183228545Sbapt 184274082Sbapt /* If we can have async responses, always look for something to read. */ 185228545Sbapt if (conn->async_responses) { 186274082Sbapt desc.reqevents |= APR_POLLIN; 187274082Sbapt } 188274082Sbapt 189274082Sbapt /* save our reqevents, so we can pass it in to remove later. */ 190310480Sdes conn->reqevents = desc.reqevents; 191310480Sdes 192310480Sdes /* Note: even if we don't want to read/write this socket, we still 193310480Sdes * want to poll it for hangups and errors. 194228545Sbapt */ 195228545Sbapt return ctx->pollset_add(ctx->pollset_baton, 196228545Sbapt &desc, &conn->baton); 197228545Sbapt} 198228545Sbapt 199228545Sbapt#ifdef SERF_DEBUG_BUCKET_USE 200228545Sbapt 201228545Sbapt/* Make sure all response buckets were drained. */ 202228545Sbaptstatic void check_buckets_drained(serf_connection_t *conn) 203228545Sbapt{ 204228545Sbapt serf_request_t *request = conn->requests; 205228545Sbapt 206228545Sbapt for ( ; request ; request = request->next ) { 207310480Sdes if (request->resp_bkt != NULL) { 208310480Sdes /* ### crap. can't do this. this allocator may have un-drained 209310480Sdes * ### REQUEST buckets. 210310480Sdes */ 211310480Sdes /* serf_debug__entered_loop(request->resp_bkt->allocator); */ 212310480Sdes /* ### for now, pretend we closed the conn (resets the tracking) */ 213310480Sdes serf_debug__closed_conn(request->resp_bkt->allocator); 214310480Sdes } 215310480Sdes } 216310480Sdes} 217228545Sbapt 218228545Sbapt#endif 219228545Sbapt 220228545Sbaptstatic void destroy_ostream(serf_connection_t *conn) 221228545Sbapt{ 222228545Sbapt if (conn->ostream_head != NULL) { 223228545Sbapt serf_bucket_destroy(conn->ostream_head); 224310480Sdes conn->ostream_head = NULL; 225228545Sbapt conn->ostream_tail = NULL; 226228545Sbapt } 227228545Sbapt} 228228545Sbapt 229228545Sbaptstatic apr_status_t detect_eof(void *baton, serf_bucket_t *aggregate_bucket) 230228545Sbapt{ 231228545Sbapt serf_connection_t *conn = baton; 232228545Sbapt conn->hit_eof = 1; 233310480Sdes return APR_EAGAIN; 234228545Sbapt} 235228545Sbapt 236228545Sbaptstatic apr_status_t do_conn_setup(serf_connection_t *conn) 237228545Sbapt{ 238228545Sbapt apr_status_t status; 239228545Sbapt serf_bucket_t *ostream; 240228545Sbapt 241228545Sbapt if (conn->ostream_head == NULL) { 242228545Sbapt conn->ostream_head = serf_bucket_aggregate_create(conn->allocator); 243228545Sbapt } 244228545Sbapt 245228545Sbapt if (conn->ostream_tail == NULL) { 246228545Sbapt conn->ostream_tail = serf__bucket_stream_create(conn->allocator, 247228545Sbapt detect_eof, 248228545Sbapt conn); 249228545Sbapt } 250228545Sbapt 251228545Sbapt ostream = conn->ostream_tail; 252228545Sbapt 253228545Sbapt status = (*conn->setup)(conn->skt, 254228545Sbapt &conn->stream, 255228545Sbapt &ostream, 256228545Sbapt conn->setup_baton, 257228545Sbapt conn->pool); 258228545Sbapt if (status) { 259228545Sbapt /* extra destroy here since it wasn't added to the head bucket yet. */ 260228545Sbapt serf_bucket_destroy(conn->ostream_tail); 261228545Sbapt destroy_ostream(conn); 262228545Sbapt return status; 263228545Sbapt } 264228545Sbapt 265228545Sbapt serf_bucket_aggregate_append(conn->ostream_head, 266228545Sbapt ostream); 267228545Sbapt 268228545Sbapt return status; 269228545Sbapt} 270228545Sbapt 271228545Sbapt/* Set up the input and output stream buckets. 272228545Sbapt When a tunnel over an http proxy is needed, create a socket bucket and 273228545Sbapt empty aggregate bucket for sending and receiving unencrypted requests 274228545Sbapt over the socket. 275228545Sbapt 276228545Sbapt After the tunnel is there, or no tunnel was needed, ask the application 277228545Sbapt to create the input and output buckets, which should take care of the 278228545Sbapt [en/de]cryption. 279228545Sbapt */ 280228545Sbapt 281228545Sbaptstatic apr_status_t prepare_conn_streams(serf_connection_t *conn, 282228545Sbapt serf_bucket_t **istream, 283228545Sbapt serf_bucket_t **ostreamt, 284228545Sbapt serf_bucket_t **ostreamh) 285228545Sbapt{ 286228545Sbapt apr_status_t status; 287228545Sbapt 288228545Sbapt if (conn->stream == NULL) { 289228545Sbapt conn->latency = apr_time_now() - conn->connect_time; 290228545Sbapt } 291228545Sbapt 292228545Sbapt /* Do we need a SSL tunnel first? */ 293228545Sbapt if (conn->state == SERF_CONN_CONNECTED) { 294228545Sbapt /* If the connection does not have an associated bucket, then 295310480Sdes * call the setup callback to get one. 296228545Sbapt */ 297228545Sbapt if (conn->stream == NULL) { 298228545Sbapt status = do_conn_setup(conn); 299228545Sbapt if (status) { 300228545Sbapt return status; 301228545Sbapt } 302228545Sbapt } 303228545Sbapt *ostreamt = conn->ostream_tail; 304228545Sbapt *ostreamh = conn->ostream_head; 305228545Sbapt *istream = conn->stream; 306228545Sbapt } else { 307228545Sbapt /* SSL tunnel needed and not set up yet, get a direct unencrypted 308228545Sbapt stream for this socket */ 309228545Sbapt if (conn->stream == NULL) { 310228545Sbapt *istream = serf_bucket_socket_create(conn->skt, 311228545Sbapt conn->allocator); 312228545Sbapt } 313228545Sbapt /* Don't create the ostream bucket chain including the ssl_encrypt 314228545Sbapt bucket yet. This ensure the CONNECT request is sent unencrypted 315228545Sbapt to the proxy. */ 316228545Sbapt *ostreamt = *ostreamh = conn->ssltunnel_ostream; 317310480Sdes } 318310480Sdes 319228545Sbapt return APR_SUCCESS; 320228545Sbapt} 321310480Sdes 322310480Sdes/* Create and connect sockets for any connections which don't have them 323228545Sbapt * yet. This is the core of our lazy-connect behavior. 324228545Sbapt */ 325228545Sbaptapr_status_t serf__open_connections(serf_context_t *ctx) 326228545Sbapt{ 327228545Sbapt int i; 328228545Sbapt 329228545Sbapt for (i = ctx->conns->nelts; i--; ) { 330228545Sbapt serf_connection_t *conn = GET_CONN(ctx, i); 331228545Sbapt serf__authn_info_t *authn_info; 332285205Sgarga apr_status_t status; 333285205Sgarga apr_socket_t *skt; 334243334Sbapt 335243334Sbapt conn->seen_in_pollset = 0; 336243328Sbapt 337285205Sgarga if (conn->skt != NULL) { 338285205Sgarga#ifdef SERF_DEBUG_BUCKET_USE 339285205Sgarga check_buckets_drained(conn); 340285205Sgarga#endif 341285205Sgarga continue; 342285205Sgarga } 343285205Sgarga 344285205Sgarga /* Delay opening until we have something to deliver! */ 345285205Sgarga if (conn->requests == NULL) { 346285205Sgarga continue; 347285205Sgarga } 348285205Sgarga 349285205Sgarga apr_pool_clear(conn->skt_pool); 350285205Sgarga apr_pool_cleanup_register(conn->skt_pool, conn, clean_skt, clean_skt); 351285205Sgarga 352285205Sgarga status = apr_socket_create(&skt, conn->address->family, 353285205Sgarga SOCK_STREAM, 354228545Sbapt#if APR_MAJOR_VERSION > 0 355228545Sbapt APR_PROTO_TCP, 356228545Sbapt#endif 357245390Smjg conn->skt_pool); 358228545Sbapt serf__log(SOCK_VERBOSE, __FILE__, 359228545Sbapt "created socket for conn 0x%x, status %d\n", conn, status); 360228545Sbapt if (status != APR_SUCCESS) 361228545Sbapt return status; 362228545Sbapt 363228545Sbapt /* Set the socket to be non-blocking */ 364228545Sbapt if ((status = apr_socket_timeout_set(skt, 0)) != APR_SUCCESS) 365228545Sbapt return status; 366228545Sbapt 367228545Sbapt /* Disable Nagle's algorithm */ 368228545Sbapt if ((status = apr_socket_opt_set(skt, 369228545Sbapt APR_TCP_NODELAY, 1)) != APR_SUCCESS) 370228545Sbapt return status; 371228545Sbapt 372228545Sbapt /* Configured. Store it into the connection now. */ 373228545Sbapt conn->skt = skt; 374228545Sbapt 375228545Sbapt /* Remember time when we started connecting to server to calculate 376228545Sbapt network latency. */ 377228545Sbapt conn->connect_time = apr_time_now(); 378178431Sscf 379178431Sscf /* Now that the socket is set up, let's connect it. This should 380178431Sscf * return immediately. 381178431Sscf */ 382178431Sscf status = apr_socket_connect(skt, conn->address); 383185237Sscf serf__log_skt(SOCK_VERBOSE, __FILE__, skt, 384185237Sscf "connected socket for conn 0x%x, status %d\n", 385178431Sscf conn, status); 386178431Sscf if (status != APR_SUCCESS) { 387185237Sscf if (!APR_STATUS_IS_EINPROGRESS(status)) 388185237Sscf return status; 389185237Sscf } 390185237Sscf 391185237Sscf /* Flag our pollset as dirty now that we have a new socket. */ 392185237Sscf conn->dirty_conn = 1; 393185237Sscf ctx->dirty_pollset = 1; 394185237Sscf 395185237Sscf /* If the authentication was already started on another connection, 396185237Sscf prepare this connection (it might be possible to skip some 397185237Sscf part of the handshaking). */ 398185237Sscf if (ctx->proxy_address) { 399178431Sscf authn_info = &ctx->proxy_authn_info; 400248102Sdb if (authn_info->scheme) { 401248102Sdb authn_info->scheme->init_conn_func(authn_info->scheme, 407, 402248102Sdb conn, conn->pool); 403248102Sdb } 404248102Sdb } 405248102Sdb 406248102Sdb authn_info = serf__get_authn_info_for_server(conn); 407248102Sdb if (authn_info->scheme) { 408248102Sdb authn_info->scheme->init_conn_func(authn_info->scheme, 401, 409248102Sdb conn, conn->pool); 410248102Sdb } 411178431Sscf 412178431Sscf /* Does this connection require a SSL tunnel over the proxy? */ 413248102Sdb if (ctx->proxy_address && strcmp(conn->host_info.scheme, "https") == 0) 414248102Sdb serf__ssltunnel_connect(conn); 415248102Sdb else { 416248102Sdb serf_bucket_t *dummy1, *dummy2; 417248102Sdb 418248102Sdb conn->state = SERF_CONN_CONNECTED; 419248102Sdb 420248102Sdb status = prepare_conn_streams(conn, &conn->stream, 421248102Sdb &dummy1, &dummy2); 422248102Sdb if (status) { 423248102Sdb return status; 424178431Sscf } 425185237Sscf } 426178431Sscf } 427178431Sscf 428178431Sscf return APR_SUCCESS; 429178431Sscf} 430178431Sscf 431178431Sscfstatic apr_status_t no_more_writes(serf_connection_t *conn) 432178431Sscf{ 433178431Sscf /* Note that we should hold new requests until we open our new socket. */ 434245386Smjg conn->state = SERF_CONN_CLOSING; 435245387Smjg serf__log_skt(CONN_VERBOSE, __FILE__, conn->skt, 436178431Sscf "stop writing on conn 0x%x\n", conn); 437245387Smjg 438185237Sscf /* Clear our iovec. */ 439178431Sscf conn->vec_len = 0; 440178431Sscf 441178431Sscf /* Update the pollset to know we don't want to write on this socket any 442185237Sscf * more. 443178431Sscf */ 444185237Sscf conn->dirty_conn = 1; 445185237Sscf conn->ctx->dirty_pollset = 1; 446185237Sscf return APR_SUCCESS; 447185237Sscf} 448185237Sscf 449185237Sscf/* Read the 'Connection' header from the response. Return SERF_ERROR_CLOSING if 450178431Sscf * the header contains value 'close' indicating the server is closing the 451178431Sscf * connection right after this response. 452245387Smjg * Otherwise returns APR_SUCCESS. 453178431Sscf */ 454245387Smjgstatic apr_status_t is_conn_closing(serf_bucket_t *response) 455200423Sscf{ 456245387Smjg serf_bucket_t *hdrs; 457245387Smjg const char *val; 458185237Sscf 459245387Smjg hdrs = serf_bucket_response_get_headers(response); 460245387Smjg val = serf_bucket_headers_get(hdrs, "Connection"); 461245387Smjg if (val && strcasecmp("close", val) == 0) 462185237Sscf { 463245387Smjg return SERF_ERROR_CLOSING; 464178431Sscf } 465178431Sscf 466178431Sscf return APR_SUCCESS; 467178431Sscf} 468178431Sscf 469178431Sscfstatic void link_requests(serf_request_t **list, serf_request_t **tail, 470178431Sscf serf_request_t *request) 471178431Sscf{ 472178431Sscf if (*list == NULL) { 473178431Sscf *list = request; 474247919Sdb *tail = request; 475247919Sdb } 476247919Sdb else { 477247919Sdb (*tail)->next = request; 478247919Sdb *tail = request; 479247919Sdb } 480247919Sdb} 481247919Sdb 482248102Sdbstatic apr_status_t destroy_request(serf_request_t *request) 483184831Sscf{ 484185237Sscf serf_connection_t *conn = request->conn; 485178431Sscf 486247919Sdb /* The request and response buckets are no longer needed, 487247919Sdb nor is the request's pool. */ 488178431Sscf if (request->resp_bkt) { 489248102Sdb serf_debug__closed_conn(request->resp_bkt->allocator); 490178431Sscf serf_bucket_destroy(request->resp_bkt); 491248102Sdb request->resp_bkt = NULL; 492247919Sdb } 493247919Sdb if (request->req_bkt) { 494247919Sdb serf_debug__closed_conn(request->req_bkt->allocator); 495248102Sdb serf_bucket_destroy(request->req_bkt); 496248102Sdb request->req_bkt = NULL; 497247919Sdb } 498247919Sdb 499247919Sdb serf_debug__bucket_alloc_check(request->allocator); 500247919Sdb if (request->respool) { 501247919Sdb /* ### unregister the pool cleanup for self? */ 502247919Sdb apr_pool_destroy(request->respool); 503247919Sdb } 504247919Sdb 505247919Sdb serf_bucket_mem_free(conn->allocator, request); 506247919Sdb 507247919Sdb return APR_SUCCESS; 508247919Sdb} 509247919Sdb 510247919Sdbstatic apr_status_t cancel_request(serf_request_t *request, 511247919Sdb serf_request_t **list, 512247919Sdb int notify_request) 513247919Sdb{ 514247919Sdb /* If we haven't run setup, then we won't have a handler to call. */ 515247919Sdb if (request->handler && notify_request) { 516247919Sdb /* We actually don't care what the handler returns. 517248102Sdb * We have bigger matters at hand. 518247919Sdb */ 519247919Sdb (*request->handler)(request, NULL, request->handler_baton, 520248102Sdb request->respool); 521247919Sdb } 522247919Sdb 523248102Sdb if (*list == request) { 524247919Sdb *list = request->next; 525248102Sdb } 526248102Sdb else { 527248102Sdb serf_request_t *scan = *list; 528248102Sdb 529248102Sdb while (scan->next && scan->next != request) 530248102Sdb scan = scan->next; 531244742Sbapt 532178431Sscf if (scan->next) { 533244742Sbapt scan->next = scan->next->next; 534244742Sbapt } 535247919Sdb } 536244777Sbapt 537178431Sscf return destroy_request(request); 538244742Sbapt} 539244742Sbapt 540247919Sdbstatic apr_status_t remove_connection(serf_context_t *ctx, 541244777Sbapt serf_connection_t *conn) 542244742Sbapt{ 543248102Sdb apr_pollfd_t desc = { 0 }; 544248102Sdb 545248102Sdb desc.desc_type = APR_POLL_SOCKET; 546248102Sdb desc.desc.s = conn->skt; 547247919Sdb desc.reqevents = conn->reqevents; 548247919Sdb 549178431Sscf return ctx->pollset_rm(ctx->pollset_baton, 550248102Sdb &desc, conn); 551248102Sdb} 552248102Sdb 553248102Sdb/* A socket was closed, inform the application. */ 554248102Sdbstatic void handle_conn_closed(serf_connection_t *conn, apr_status_t status) 555248102Sdb{ 556248102Sdb (*conn->closed)(conn, conn->closed_baton, status, 557248102Sdb conn->pool); 558247919Sdb} 559248102Sdb 560244742Sbaptstatic apr_status_t reset_connection(serf_connection_t *conn, 561178431Sscf int requeue_requests) 562178431Sscf{ 563178431Sscf serf_context_t *ctx = conn->ctx; 564247919Sdb apr_status_t status; 565244736Sbapt serf_request_t *old_reqs; 566247919Sdb 567247919Sdb conn->probable_keepalive_limit = conn->completed_responses; 568244736Sbapt conn->completed_requests = 0; 569247919Sdb conn->completed_responses = 0; 570247919Sdb 571244736Sbapt old_reqs = conn->requests; 572247919Sdb 573247919Sdb conn->requests = NULL; 574247919Sdb conn->requests_tail = NULL; 575247919Sdb 576247919Sdb /* Handle all outstanding requests. These have either not been written yet, 577247919Sdb or have been written but the expected reply wasn't received yet. */ 578247919Sdb while (old_reqs) { 579247919Sdb /* If we haven't started to write the connection, bring it over 580248102Sdb * unchanged to our new socket. 581244736Sbapt * Do not copy a CONNECT request to the new connection, the ssl tunnel 582248102Sdb * setup code will create a new CONNECT request already. 583247919Sdb */ 584247919Sdb if (requeue_requests && !old_reqs->writing_started && 585244736Sbapt !old_reqs->ssltunnel) { 586244736Sbapt 587247919Sdb serf_request_t *req = old_reqs; 588248102Sdb old_reqs = old_reqs->next; 589247919Sdb req->next = NULL; 590248102Sdb link_requests(&conn->requests, &conn->requests_tail, req); 591247919Sdb } 592248102Sdb else { 593248102Sdb /* Request has been consumed, or we don't want to requeue the 594248102Sdb request. Either way, inform the application that the request 595248102Sdb is cancelled. */ 596247919Sdb cancel_request(old_reqs, &old_reqs, requeue_requests); 597244736Sbapt } 598244736Sbapt } 599244736Sbapt 600178431Sscf /* Requests queue has been prepared for a new socket, close the old one. */ 601178431Sscf if (conn->skt != NULL) { 602178431Sscf remove_connection(ctx, conn); 603178431Sscf status = apr_socket_close(conn->skt); 604178431Sscf serf__log_skt(SOCK_VERBOSE, __FILE__, conn->skt, 605178431Sscf "closed socket, status %d\n", status); 606178431Sscf if (conn->closed != NULL) { 607178431Sscf handle_conn_closed(conn, status); 608178431Sscf } 609178431Sscf conn->skt = NULL; 610178431Sscf } 611178431Sscf 612178431Sscf if (conn->stream != NULL) { 613178431Sscf serf_bucket_destroy(conn->stream); 614184831Sscf conn->stream = NULL; 615184831Sscf } 616178431Sscf 617178431Sscf destroy_ostream(conn); 618178431Sscf 619178431Sscf /* Don't try to resume any writes */ 620178431Sscf conn->vec_len = 0; 621184831Sscf 622178431Sscf conn->dirty_conn = 1; 623178431Sscf conn->ctx->dirty_pollset = 1; 624178431Sscf conn->state = SERF_CONN_INIT; 625178431Sscf 626178431Sscf serf__log(CONN_VERBOSE, __FILE__, "reset connection 0x%x\n", conn); 627178431Sscf 628178431Sscf conn->status = APR_SUCCESS; 629185237Sscf 630185237Sscf /* Let our context know that we've 'reset' the socket already. */ 631185237Sscf conn->seen_in_pollset |= APR_POLLHUP; 632185237Sscf 633185237Sscf /* Found the connection. Closed it. All done. */ 634185237Sscf return APR_SUCCESS; 635185237Sscf} 636185237Sscf 637178431Sscfstatic apr_status_t socket_writev(serf_connection_t *conn) 638178431Sscf{ 639185237Sscf apr_size_t written; 640185237Sscf apr_status_t status; 641178431Sscf 642178431Sscf status = apr_socket_sendv(conn->skt, conn->vec, 643178431Sscf conn->vec_len, &written); 644178431Sscf if (status && !APR_STATUS_IS_EAGAIN(status)) 645178431Sscf serf__log_skt(SOCK_VERBOSE, __FILE__, conn->skt, 646178431Sscf "socket_sendv error %d\n", status); 647178431Sscf 648178431Sscf /* did we write everything? */ 649178431Sscf if (written) { 650178431Sscf apr_size_t len = 0; 651184831Sscf int i; 652185237Sscf 653185237Sscf serf__log_skt(SOCK_MSG_VERBOSE, __FILE__, conn->skt, 654178431Sscf "--- socket_sendv:\n"); 655185237Sscf 656178431Sscf for (i = 0; i < conn->vec_len; i++) { 657185237Sscf len += conn->vec[i].iov_len; 658185237Sscf if (written < len) { 659178431Sscf serf__log_nopref(SOCK_MSG_VERBOSE, "%.*s", 660178431Sscf conn->vec[i].iov_len - (len - written), 661185237Sscf conn->vec[i].iov_base); 662185237Sscf if (i) { 663178431Sscf memmove(conn->vec, &conn->vec[i], 664178431Sscf sizeof(struct iovec) * (conn->vec_len - i)); 665178431Sscf conn->vec_len -= i; 666185237Sscf } 667178431Sscf conn->vec[0].iov_base = (char *)conn->vec[0].iov_base + (conn->vec[0].iov_len - (len - written)); 668 conn->vec[0].iov_len = len - written; 669 break; 670 } else { 671 serf__log_nopref(SOCK_MSG_VERBOSE, "%.*s", 672 conn->vec[i].iov_len, conn->vec[i].iov_base); 673 } 674 } 675 if (len == written) { 676 conn->vec_len = 0; 677 } 678 serf__log_nopref(SOCK_MSG_VERBOSE, "-(%d)-\n", written); 679 680 /* Log progress information */ 681 serf__context_progress_delta(conn->ctx, 0, written); 682 } 683 684 return status; 685} 686 687static apr_status_t setup_request(serf_request_t *request) 688{ 689 serf_connection_t *conn = request->conn; 690 apr_status_t status; 691 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, 695 NULL, NULL); 696 apr_pool_cleanup_register(request->respool, request, 697 clean_resp, clean_resp); 698 699 /* Fill in the rest of the values for the request. */ 700 status = request->setup(request, request->setup_baton, 701 &request->req_bkt, 702 &request->acceptor, 703 &request->acceptor_baton, 704 &request->handler, 705 &request->handler_baton, 706 request->respool); 707 return status; 708} 709 710/* write data out to the connection */ 711static apr_status_t write_to_connection(serf_connection_t *conn) 712{ 713 if (conn->probable_keepalive_limit && 714 conn->completed_requests > conn->probable_keepalive_limit) { 715 716 conn->dirty_conn = 1; 717 conn->ctx->dirty_pollset = 1; 718 719 /* backoff for now. */ 720 return APR_SUCCESS; 721 } 722 723 /* Keep reading and sending until we run out of stuff to read, or 724 * writing would block. 725 */ 726 while (1) { 727 serf_request_t *request; 728 int stop_reading = 0; 729 apr_status_t status; 730 apr_status_t read_status; 731 serf_bucket_t *ostreamt; 732 serf_bucket_t *ostreamh; 733 int max_outstanding_requests = conn->max_outstanding_requests; 734 735 /* If we're setting up an ssl tunnel, we can't send real requests 736 at yet, as they need to be encrypted and our encrypt buckets 737 aren't created yet as we still need to read the unencrypted 738 response of the CONNECT request. */ 739 if (conn->state != SERF_CONN_CONNECTED) 740 max_outstanding_requests = 1; 741 742 if (max_outstanding_requests && 743 conn->completed_requests - 744 conn->completed_responses >= max_outstanding_requests) { 745 /* backoff for now. */ 746 return APR_SUCCESS; 747 } 748 749 /* If we have unwritten data, then write what we can. */ 750 while (conn->vec_len) { 751 status = socket_writev(conn); 752 753 /* If the write would have blocked, then we're done. Don't try 754 * to write anything else to the socket. 755 */ 756 if (APR_STATUS_IS_EAGAIN(status)) 757 return APR_SUCCESS; 758 if (APR_STATUS_IS_EPIPE(status) || 759 APR_STATUS_IS_ECONNRESET(status) || 760 APR_STATUS_IS_ECONNABORTED(status)) 761 return no_more_writes(conn); 762 if (status) 763 return status; 764 } 765 /* ### can we have a short write, yet no EAGAIN? a short write 766 ### would imply unwritten_len > 0 ... */ 767 /* assert: unwritten_len == 0. */ 768 769 /* We may need to move forward to a request which has something 770 * to write. 771 */ 772 if (!request_or_data_pending(&request, conn)) { 773 /* No more requests (with data) are registered with the 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 776 * socket again. 777 */ 778 conn->dirty_conn = 1; 779 conn->ctx->dirty_pollset = 1; 780 return APR_SUCCESS; 781 } 782 783 status = prepare_conn_streams(conn, &conn->stream, &ostreamt, &ostreamh); 784 if (status) { 785 return status; 786 } 787 788 if (request) { 789 if (request->req_bkt == NULL) { 790 read_status = setup_request(request); 791 if (read_status) { 792 /* Something bad happened. Propagate any errors. */ 793 return read_status; 794 } 795 } 796 797 if (!request->writing_started) { 798 request->writing_started = 1; 799 serf_bucket_aggregate_append(ostreamt, request->req_bkt); 800 } 801 } 802 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 ... */ 808 read_status = serf_bucket_read_iovec(ostreamh, 809 SERF_READ_ALL_AVAIL, 810 IOV_MAX, 811 conn->vec, 812 &conn->vec_len); 813 814 if (!conn->hit_eof) { 815 if (APR_STATUS_IS_EAGAIN(read_status)) { 816 /* We read some stuff, but should not try to read again. */ 817 stop_reading = 1; 818 } 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. 823 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) 829 */ 830 conn->stop_writing = 1; 831 conn->dirty_conn = 1; 832 conn->ctx->dirty_pollset = 1; 833 } 834 else if (read_status && !APR_STATUS_IS_EOF(read_status)) { 835 /* Something bad happened. Propagate any errors. */ 836 return read_status; 837 } 838 } 839 840 /* If we got some data, then deliver it. */ 841 /* ### what to do if we got no data?? is that a problem? */ 842 if (conn->vec_len > 0) { 843 status = socket_writev(conn); 844 845 /* If we can't write any more, or an error occurred, then 846 * we're done here. 847 */ 848 if (APR_STATUS_IS_EAGAIN(status)) 849 return APR_SUCCESS; 850 if (APR_STATUS_IS_EPIPE(status)) 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); 855 } 856 if (status) 857 return status; 858 } 859 860 if (read_status == SERF_ERROR_WAIT_CONN) { 861 stop_reading = 1; 862 conn->stop_writing = 1; 863 conn->dirty_conn = 1; 864 conn->ctx->dirty_pollset = 1; 865 } 866 else if (request && read_status && conn->hit_eof && 867 conn->vec_len == 0) { 868 /* If we hit the end of the request bucket and all of its data has 869 * been written, then clear it out to signify that we're done 870 * sending the request. On the next iteration through this loop: 871 * - if there are remaining bytes they will be written, and as the 872 * request bucket will be completely read it will be destroyed then. 873 * - we'll see if there are other requests that need to be sent 874 * ("pipelining"). 875 */ 876 conn->hit_eof = 0; 877 serf_bucket_destroy(request->req_bkt); 878 request->req_bkt = NULL; 879 880 /* If our connection has async responses enabled, we're not 881 * going to get a reply back, so kill the request. 882 */ 883 if (conn->async_responses) { 884 conn->requests = request->next; 885 destroy_request(request); 886 } 887 888 conn->completed_requests++; 889 890 if (conn->probable_keepalive_limit && 891 conn->completed_requests > conn->probable_keepalive_limit) { 892 /* backoff for now. */ 893 stop_reading = 1; 894 } 895 } 896 897 if (stop_reading) { 898 return APR_SUCCESS; 899 } 900 } 901 /* NOTREACHED */ 902} 903 904/* A response message was received from the server, so call 905 the handler as specified on the original request. */ 906static apr_status_t handle_response(serf_request_t *request, 907 apr_pool_t *pool) 908{ 909 apr_status_t status = APR_SUCCESS; 910 int consumed_response = 0; 911 912 /* Only enable the new authentication framework if the program has 913 * registered an authentication credential callback. 914 * 915 * This permits older Serf apps to still handle authentication 916 * themselves by not registering credential callbacks. 917 */ 918 if (request->conn->ctx->cred_cb) { 919 status = serf__handle_auth_response(&consumed_response, 920 request, 921 request->resp_bkt, 922 request->handler_baton, 923 pool); 924 925 /* If there was an error reading the response (maybe there wasn't 926 enough data available), don't bother passing the response to the 927 application. 928 929 If the authentication was tried, but failed, pass the response 930 to the application, maybe it can do better. */ 931 if (status) { 932 return status; 933 } 934 } 935 936 if (!consumed_response) { 937 return (*request->handler)(request, 938 request->resp_bkt, 939 request->handler_baton, 940 pool); 941 } 942 943 return status; 944} 945 946/* An async response message was received from the server. */ 947static apr_status_t handle_async_response(serf_connection_t *conn, 948 apr_pool_t *pool) 949{ 950 apr_status_t status; 951 952 if (conn->current_async_response == NULL) { 953 conn->current_async_response = 954 (*conn->async_acceptor)(NULL, conn->stream, 955 conn->async_acceptor_baton, pool); 956 } 957 958 status = (*conn->async_handler)(NULL, conn->current_async_response, 959 conn->async_handler_baton, pool); 960 961 if (APR_STATUS_IS_EOF(status)) { 962 serf_bucket_destroy(conn->current_async_response); 963 conn->current_async_response = NULL; 964 status = APR_SUCCESS; 965 } 966 967 return status; 968} 969 970 971apr_status_t 972serf__provide_credentials(serf_context_t *ctx, 973 char **username, 974 char **password, 975 serf_request_t *request, void *baton, 976 int code, const char *authn_type, 977 const char *realm, 978 apr_pool_t *pool) 979{ 980 serf_connection_t *conn = request->conn; 981 serf_request_t *authn_req = request; 982 apr_status_t status; 983 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 989 this request. 990 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. */ 994 995 authn_req = request->next; 996 /* assert: app_request != NULL */ 997 if (!authn_req) 998 return APR_EGENERAL; 999 1000 if (!authn_req->req_bkt) { 1001 apr_status_t status; 1002 1003 status = setup_request(authn_req); 1004 /* If we can't setup a request, don't bother setting up the 1005 ssl tunnel. */ 1006 if (status) 1007 return status; 1008 } 1009 } 1010 1011 /* Ask the application. */ 1012 status = (*ctx->cred_cb)(username, password, 1013 authn_req, authn_req->handler_baton, 1014 code, authn_type, realm, pool); 1015 if (status) 1016 return status; 1017 1018 return APR_SUCCESS; 1019} 1020 1021/* read data from the connection */ 1022static apr_status_t read_from_connection(serf_connection_t *conn) 1023{ 1024 apr_status_t status; 1025 apr_pool_t *tmppool; 1026 int close_connection = FALSE; 1027 1028 /* Whatever is coming in on the socket corresponds to the first request 1029 * on our chain. 1030 */ 1031 serf_request_t *request = conn->requests; 1032 1033 /* If the stop_writing flag was set on the connection, reset it now because 1034 there is some data to read. */ 1035 if (conn->stop_writing) { 1036 conn->stop_writing = 0; 1037 conn->dirty_conn = 1; 1038 conn->ctx->dirty_pollset = 1; 1039 } 1040 1041 /* assert: request != NULL */ 1042 1043 if ((status = apr_pool_create(&tmppool, conn->pool)) != APR_SUCCESS) 1044 goto error; 1045 1046 /* Invoke response handlers until we have no more work. */ 1047 while (1) { 1048 serf_bucket_t *dummy1, *dummy2; 1049 1050 apr_pool_clear(tmppool); 1051 1052 /* Only interested in the input stream here. */ 1053 status = prepare_conn_streams(conn, &conn->stream, &dummy1, &dummy2); 1054 if (status) { 1055 goto error; 1056 } 1057 1058 /* We have a different codepath when we can have async responses. */ 1059 if (conn->async_responses) { 1060 /* TODO What about socket errors? */ 1061 status = handle_async_response(conn, tmppool); 1062 if (APR_STATUS_IS_EAGAIN(status)) { 1063 status = APR_SUCCESS; 1064 goto error; 1065 } 1066 if (status) { 1067 goto error; 1068 } 1069 continue; 1070 } 1071 1072 /* We are reading a response for a request we haven't 1073 * written yet! 1074 * 1075 * This shouldn't normally happen EXCEPT: 1076 * 1077 * 1) when the other end has closed the socket and we're 1078 * pending an EOF return. 1079 * 2) Doing the initial SSL handshake - we'll get EAGAIN 1080 * as the SSL buckets will hide the handshake from us 1081 * but not return any data. 1082 * 3) When the server sends us an SSL alert. 1083 * 1084 * In these cases, we should not receive any actual user data. 1085 * 1086 * 4) When the server sends a error response, like 408 Request timeout. 1087 * This response should be passed to the application. 1088 * 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 1091 * connection and open a new one. 1092 */ 1093 if (request->req_bkt || !request->writing_started) { 1094 const char *data; 1095 apr_size_t len; 1096 1097 status = serf_bucket_peek(conn->stream, &data, &len); 1098 1099 if (APR_STATUS_IS_EOF(status)) { 1100 reset_connection(conn, 1); 1101 status = APR_SUCCESS; 1102 goto error; 1103 } 1104 else if (APR_STATUS_IS_EAGAIN(status) && !len) { 1105 status = APR_SUCCESS; 1106 goto error; 1107 } else if (status && !APR_STATUS_IS_EAGAIN(status)) { 1108 /* Read error */ 1109 goto error; 1110 } 1111 1112 /* Unexpected response from the server */ 1113 1114 } 1115 1116 /* If the request doesn't have a response bucket, then call the 1117 * acceptor to get one created. 1118 */ 1119 if (request->resp_bkt == NULL) { 1120 request->resp_bkt = (*request->acceptor)(request, conn->stream, 1121 request->acceptor_baton, 1122 tmppool); 1123 apr_pool_clear(tmppool); 1124 } 1125 1126 status = handle_response(request, tmppool); 1127 1128 /* Some systems will not generate a HUP poll event so we have to 1129 * handle the ECONNRESET issue and ECONNABORT here. 1130 */ 1131 if (APR_STATUS_IS_ECONNRESET(status) || 1132 APR_STATUS_IS_ECONNABORTED(status) || 1133 status == SERF_ERROR_REQUEST_LOST) { 1134 /* If the connection had ever been good, be optimistic & try again. 1135 * If it has never tried again (incl. a retry), fail. 1136 */ 1137 if (conn->completed_responses) { 1138 reset_connection(conn, 1); 1139 status = APR_SUCCESS; 1140 } 1141 else if (status == SERF_ERROR_REQUEST_LOST) { 1142 status = SERF_ERROR_ABORTED_CONNECTION; 1143 } 1144 goto error; 1145 } 1146 1147 /* If our response handler says it can't do anything more, we now 1148 * treat that as a success. 1149 */ 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. 1154 */ 1155 if (request_or_data_pending(&request, conn) && !request) { 1156 conn->dirty_conn = 1; 1157 conn->ctx->dirty_pollset = 1; 1158 } 1159 status = APR_SUCCESS; 1160 goto error; 1161 } 1162 1163 /* If we received APR_SUCCESS, run this loop again. */ 1164 if (!status) { 1165 continue; 1166 } 1167 1168 close_connection = is_conn_closing(request->resp_bkt); 1169 1170 if (!APR_STATUS_IS_EOF(status) && 1171 close_connection != SERF_ERROR_CLOSING) { 1172 /* Whether success, or an error, there is no more to do unless 1173 * this request has been completed. 1174 */ 1175 goto error; 1176 } 1177 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 1181 $ received. 1182 * Remove it from our queue and loop to read another response. 1183 */ 1184 conn->requests = request->next; 1185 1186 destroy_request(request); 1187 1188 request = conn->requests; 1189 1190 /* If we're truly empty, update our tail. */ 1191 if (request == NULL) { 1192 conn->requests_tail = NULL; 1193 } 1194 1195 conn->completed_responses++; 1196 1197 /* We've to rebuild pollset since completed_responses is changed. */ 1198 conn->dirty_conn = 1; 1199 conn->ctx->dirty_pollset = 1; 1200 1201 /* This means that we're being advised that the connection is done. */ 1202 if (close_connection == SERF_ERROR_CLOSING) { 1203 reset_connection(conn, 1); 1204 if (APR_STATUS_IS_EOF(status)) 1205 status = APR_SUCCESS; 1206 goto error; 1207 } 1208 1209 /* The server is suddenly deciding to serve more responses than we've 1210 * seen before. 1211 * 1212 * Let our requests go. 1213 */ 1214 if (conn->probable_keepalive_limit && 1215 conn->completed_responses > conn->probable_keepalive_limit) { 1216 conn->probable_keepalive_limit = 0; 1217 } 1218 1219 /* If we just ran out of requests or have unwritten requests, then 1220 * update the pollset. We don't want to read from this socket any 1221 * more. We are definitely done with this loop, too. 1222 */ 1223 if (request == NULL || !request->writing_started) { 1224 conn->dirty_conn = 1; 1225 conn->ctx->dirty_pollset = 1; 1226 status = APR_SUCCESS; 1227 goto error; 1228 } 1229 } 1230 1231error: 1232 apr_pool_destroy(tmppool); 1233 return status; 1234} 1235 1236/* process all events on the connection */ 1237apr_status_t serf__process_connection(serf_connection_t *conn, 1238 apr_int16_t events) 1239{ 1240 apr_status_t status; 1241 1242 /* POLLHUP/ERR should come after POLLIN so if there's an error message or 1243 * the like sitting on the connection, we give the app a chance to read 1244 * it before we trigger a reset condition. 1245 */ 1246 if ((events & APR_POLLIN) != 0) { 1247 if ((status = read_from_connection(conn)) != APR_SUCCESS) 1248 return status; 1249 1250 /* If we decided to reset our connection, return now as we don't 1251 * want to write. 1252 */ 1253 if ((conn->seen_in_pollset & APR_POLLHUP) != 0) { 1254 return APR_SUCCESS; 1255 } 1256 } 1257 if ((events & APR_POLLHUP) != 0) { 1258 /* The connection got reset by the server. On Windows this can happen 1259 when all data is read, so just cleanup the connection and open 1260 a new one. 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); 1265 } 1266 return SERF_ERROR_ABORTED_CONNECTION; 1267 } 1268 if ((events & APR_POLLERR) != 0) { 1269 /* We might be talking to a buggy HTTP server that doesn't 1270 * do lingering-close. (httpd < 2.1.8 does this.) 1271 * 1272 * See: 1273 * 1274 * http://issues.apache.org/bugzilla/show_bug.cgi?id=35292 1275 */ 1276 if (conn->completed_requests && !conn->probable_keepalive_limit) { 1277 return reset_connection(conn, 1); 1278 } 1279#ifdef SO_ERROR 1280 /* If possible, get the error from the platform's socket layer and 1281 convert it to an APR status code. */ 1282 { 1283 apr_os_sock_t osskt; 1284 if (!apr_os_sock_get(&osskt, conn->skt)) { 1285 int error; 1286 apr_socklen_t l = sizeof(error); 1287 1288 if (!getsockopt(osskt, SOL_SOCKET, SO_ERROR, (char*)&error, 1289 &l)) { 1290 status = APR_FROM_OS_ERROR(error); 1291 1292 /* Handle fallback for multi-homed servers. 1293 1294 ### Improve algorithm to find better than just 'next'? 1295 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))) { 1304 1305 conn->address = conn->address->next; 1306 return reset_connection(conn, 1); 1307 } 1308 1309 return status; 1310 } 1311 } 1312 } 1313#endif 1314 return APR_EGENERAL; 1315 } 1316 if ((events & APR_POLLOUT) != 0) { 1317 if ((status = write_to_connection(conn)) != APR_SUCCESS) 1318 return status; 1319 } 1320 return APR_SUCCESS; 1321} 1322 1323serf_connection_t *serf_connection_create( 1324 serf_context_t *ctx, 1325 apr_sockaddr_t *address, 1326 serf_connection_setup_t setup, 1327 void *setup_baton, 1328 serf_connection_closed_t closed, 1329 void *closed_baton, 1330 apr_pool_t *pool) 1331{ 1332 serf_connection_t *conn = apr_pcalloc(pool, sizeof(*conn)); 1333 1334 conn->ctx = ctx; 1335 conn->status = APR_SUCCESS; 1336 /* Ignore server address if proxy was specified. */ 1337 conn->address = ctx->proxy_address ? ctx->proxy_address : address; 1338 conn->setup = setup; 1339 conn->setup_baton = setup_baton; 1340 conn->closed = closed; 1341 conn->closed_baton = closed_baton; 1342 conn->pool = pool; 1343 conn->allocator = serf_bucket_allocator_create(pool, NULL, NULL); 1344 conn->stream = NULL; 1345 conn->ostream_head = NULL; 1346 conn->ostream_tail = NULL; 1347 conn->baton.type = SERF_IO_CONN; 1348 conn->baton.u.conn = conn; 1349 conn->hit_eof = 0; 1350 conn->state = SERF_CONN_INIT; 1351 conn->latency = -1; /* unknown */ 1352 1353 /* Create a subpool for our connection. */ 1354 apr_pool_create(&conn->skt_pool, conn->pool); 1355 1356 /* register a cleanup */ 1357 apr_pool_cleanup_register(conn->pool, conn, clean_conn, 1358 apr_pool_cleanup_null); 1359 1360 /* Add the connection to the context. */ 1361 *(serf_connection_t **)apr_array_push(ctx->conns) = conn; 1362 1363 serf__log(CONN_VERBOSE, __FILE__, "created connection 0x%x\n", 1364 conn); 1365 1366 return conn; 1367} 1368 1369apr_status_t serf_connection_create2( 1370 serf_connection_t **conn, 1371 serf_context_t *ctx, 1372 apr_uri_t host_info, 1373 serf_connection_setup_t setup, 1374 void *setup_baton, 1375 serf_connection_closed_t closed, 1376 void *closed_baton, 1377 apr_pool_t *pool) 1378{ 1379 apr_status_t status = APR_SUCCESS; 1380 serf_connection_t *c; 1381 apr_sockaddr_t *host_address = NULL; 1382 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); 1386 } 1387 1388 /* Only lookup the address of the server if no proxy server was 1389 configured. */ 1390 if (!ctx->proxy_address) { 1391 status = apr_sockaddr_info_get(&host_address, 1392 host_info.hostname, 1393 APR_UNSPEC, host_info.port, 0, pool); 1394 if (status) 1395 return status; 1396 } 1397 1398 c = serf_connection_create(ctx, host_address, setup, setup_baton, 1399 closed, closed_baton, pool); 1400 1401 /* We're not interested in the path following the hostname. */ 1402 c->host_url = apr_uri_unparse(c->pool, 1403 &host_info, 1404 APR_URI_UNP_OMITPATHINFO | 1405 APR_URI_UNP_OMITUSERINFO); 1406 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); 1411 } 1412 1413 *conn = c; 1414 1415 return status; 1416} 1417 1418apr_status_t serf_connection_reset( 1419 serf_connection_t *conn) 1420{ 1421 return reset_connection(conn, 0); 1422} 1423 1424 1425apr_status_t serf_connection_close( 1426 serf_connection_t *conn) 1427{ 1428 int i; 1429 serf_context_t *ctx = conn->ctx; 1430 apr_status_t status; 1431 1432 for (i = ctx->conns->nelts; i--; ) { 1433 serf_connection_t *conn_seq = GET_CONN(ctx, i); 1434 1435 if (conn_seq == conn) { 1436 while (conn->requests) { 1437 serf_request_cancel(conn->requests); 1438 } 1439 if (conn->skt != NULL) { 1440 remove_connection(ctx, conn); 1441 status = apr_socket_close(conn->skt); 1442 serf__log_skt(SOCK_VERBOSE, __FILE__, conn->skt, 1443 "closed socket, status %d\n", 1444 status); 1445 if (conn->closed != NULL) { 1446 handle_conn_closed(conn, status); 1447 } 1448 conn->skt = NULL; 1449 } 1450 if (conn->stream != NULL) { 1451 serf_bucket_destroy(conn->stream); 1452 conn->stream = NULL; 1453 } 1454 1455 destroy_ostream(conn); 1456 1457 /* Remove the connection from the context. We don't want to 1458 * deal with it any more. 1459 */ 1460 if (i < ctx->conns->nelts - 1) { 1461 /* move later connections over this one. */ 1462 memmove( 1463 &GET_CONN(ctx, i), 1464 &GET_CONN(ctx, i + 1), 1465 (ctx->conns->nelts - i - 1) * sizeof(serf_connection_t *)); 1466 } 1467 --ctx->conns->nelts; 1468 1469 serf__log(CONN_VERBOSE, __FILE__, "closed connection 0x%x\n", 1470 conn); 1471 1472 /* Found the connection. Closed it. All done. */ 1473 return APR_SUCCESS; 1474 } 1475 } 1476 1477 /* We didn't find the specified connection. */ 1478 /* ### doc talks about this w.r.t poll structures. use something else? */ 1479 return APR_NOTFOUND; 1480} 1481 1482 1483void serf_connection_set_max_outstanding_requests( 1484 serf_connection_t *conn, 1485 unsigned int max_requests) 1486{ 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"); 1491 else 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); 1495 1496 conn->max_outstanding_requests = max_requests; 1497} 1498 1499 1500void serf_connection_set_async_responses( 1501 serf_connection_t *conn, 1502 serf_response_acceptor_t acceptor, 1503 void *acceptor_baton, 1504 serf_response_handler_t handler, 1505 void *handler_baton) 1506{ 1507 conn->async_responses = 1; 1508 conn->async_acceptor = acceptor; 1509 conn->async_acceptor_baton = acceptor_baton; 1510 conn->async_handler = handler; 1511 conn->async_handler_baton = handler_baton; 1512} 1513 1514static serf_request_t * 1515create_request(serf_connection_t *conn, 1516 serf_request_setup_t setup, 1517 void *setup_baton, 1518 int priority, 1519 int ssltunnel) 1520{ 1521 serf_request_t *request; 1522 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; 1536 1537 return request; 1538} 1539 1540serf_request_t *serf_connection_request_create( 1541 serf_connection_t *conn, 1542 serf_request_setup_t setup, 1543 void *setup_baton) 1544{ 1545 serf_request_t *request; 1546 1547 request = create_request(conn, setup, setup_baton, 1548 0, /* priority */ 1549 0 /* ssl tunnel */); 1550 1551 /* Link the request to the end of the request chain. */ 1552 link_requests(&conn->requests, &conn->requests_tail, request); 1553 1554 /* Ensure our pollset becomes writable in context run */ 1555 conn->ctx->dirty_pollset = 1; 1556 conn->dirty_conn = 1; 1557 1558 return request; 1559} 1560 1561static serf_request_t * 1562priority_request_create(serf_connection_t *conn, 1563 int ssltunnelreq, 1564 serf_request_setup_t setup, 1565 void *setup_baton) 1566{ 1567 serf_request_t *request; 1568 serf_request_t *iter, *prev; 1569 1570 request = create_request(conn, setup, setup_baton, 1571 1, /* priority */ 1572 ssltunnelreq); 1573 1574 /* Link the new request after the last written request. */ 1575 iter = conn->requests; 1576 prev = NULL; 1577 1578 /* Find a request that has data which needs to be delivered. */ 1579 while (iter != NULL && iter->req_bkt == NULL && iter->writing_started) { 1580 prev = iter; 1581 iter = iter->next; 1582 } 1583 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 1588 request */ 1589 if (!request->ssltunnel) { 1590 /* Advance to next non priority request */ 1591 while (iter != NULL && iter->priority) { 1592 prev = iter; 1593 iter = iter->next; 1594 } 1595 } 1596 1597 if (prev) { 1598 request->next = iter; 1599 prev->next = request; 1600 } else { 1601 request->next = iter; 1602 conn->requests = request; 1603 } 1604 1605 /* Ensure our pollset becomes writable in context run */ 1606 conn->ctx->dirty_pollset = 1; 1607 conn->dirty_conn = 1; 1608 1609 return request; 1610} 1611 1612serf_request_t *serf_connection_priority_request_create( 1613 serf_connection_t *conn, 1614 serf_request_setup_t setup, 1615 void *setup_baton) 1616{ 1617 return priority_request_create(conn, 1618 0, /* not a ssltunnel CONNECT request */ 1619 setup, setup_baton); 1620} 1621 1622serf_request_t *serf__ssltunnel_request_create(serf_connection_t *conn, 1623 serf_request_setup_t setup, 1624 void *setup_baton) 1625{ 1626 return priority_request_create(conn, 1627 1, /* This is a ssltunnel CONNECT request */ 1628 setup, setup_baton); 1629} 1630 1631apr_status_t serf_request_cancel(serf_request_t *request) 1632{ 1633 return cancel_request(request, &request->conn->requests, 0); 1634} 1635 1636apr_status_t serf_request_is_written(serf_request_t *request) 1637{ 1638 if (request->writing_started && !request->req_bkt) 1639 return APR_SUCCESS; 1640 1641 return APR_EBUSY; 1642} 1643 1644apr_pool_t *serf_request_get_pool(const serf_request_t *request) 1645{ 1646 return request->respool; 1647} 1648 1649 1650serf_bucket_alloc_t *serf_request_get_alloc( 1651 const serf_request_t *request) 1652{ 1653 return request->allocator; 1654} 1655 1656 1657serf_connection_t *serf_request_get_conn( 1658 const serf_request_t *request) 1659{ 1660 return request->conn; 1661} 1662 1663 1664void serf_request_set_handler( 1665 serf_request_t *request, 1666 const serf_response_handler_t handler, 1667 const void **handler_baton) 1668{ 1669 request->handler = handler; 1670 request->handler_baton = handler_baton; 1671} 1672 1673 1674serf_bucket_t *serf_request_bucket_request_create( 1675 serf_request_t *request, 1676 const char *method, 1677 const char *uri, 1678 serf_bucket_t *body, 1679 serf_bucket_alloc_t *allocator) 1680{ 1681 serf_bucket_t *req_bkt, *hdrs_bkt; 1682 serf_connection_t *conn = request->conn; 1683 serf_context_t *ctx = conn->ctx; 1684 int ssltunnel; 1685 1686 ssltunnel = ctx->proxy_address && 1687 (strcmp(conn->host_info.scheme, "https") == 0); 1688 1689 req_bkt = serf_bucket_request_create(method, uri, body, allocator); 1690 hdrs_bkt = serf_bucket_request_get_headers(req_bkt); 1691 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)) { 1696 1697 serf_bucket_request_set_root(req_bkt, conn->host_url); 1698 } 1699 1700 if (conn->host_info.hostinfo) 1701 serf_bucket_headers_setn(hdrs_bkt, "Host", 1702 conn->host_info.hostinfo); 1703 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, 1710 method, uri, 1711 hdrs_bkt); 1712 } 1713 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, 1721 request, 1722 method, uri, 1723 hdrs_bkt); 1724 } else { 1725 ctx->proxy_authn_info.scheme->setup_request_func(PROXY, 0, conn, 1726 request, 1727 method, uri, 1728 hdrs_bkt); 1729 } 1730 } 1731 1732 return req_bkt; 1733} 1734 1735apr_interval_time_t serf_connection_get_latency(serf_connection_t *conn) 1736{ 1737 if (conn->ctx->proxy_address) { 1738 /* Detecting network latency for proxied connection is not implemented 1739 yet. */ 1740 return -1; 1741 } 1742 1743 return conn->latency; 1744} 1745