Commit 4bcc975b authored by Ryan Bloom's avatar Ryan Bloom
Browse files

Begin to abstract out the underlying transport layer.

The first step is to remove the socket from the conn_rec,
the server now lives in a context that is passed to the
core's input and output filters. This forces us to be very
careful when adding calls that use the socket directly,
because the socket isn't available in most locations.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@91887 13f79535-47bb-0310-9956-ffa450edef68
parent 8c3ce8f6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
Changes with Apache 2.0.29-dev

  *) Begin to abstract out the underlying transport layer.
     The first step is to remove the socket from the conn_rec,
     the server now lives in a context that is passed to the
     core's input and output filters. This forces us to be very
     careful when adding calls that use the socket directly,
     because the socket isn't available in most locations.
     [Ryan Bloom]

  *) Really reset the MaxClients value in worker and threaded
     when the configured value is not a multiple of the number 
     of threads per child.  We said we did previously but we 
+13 −0
Original line number Diff line number Diff line
@@ -128,6 +128,19 @@ AP_DECLARE_HOOK(int,pre_connection,(conn_rec *c))
 */
AP_DECLARE_HOOK(int,process_connection,(conn_rec *c))

/**
 */
AP_DECLARE_HOOK(conn_rec *, create_connection,
                (apr_pool_t *p, apr_socket_t *csd, int child_num))

/* This is NOT staying here.  It is necessary to quiet warnings
 * while I would on the next patch. rbb
 */

AP_CORE_DECLARE(conn_rec *)ap_core_new_connection(apr_pool_t *p,
                            server_rec *server, apr_socket_t *inout,
                            core_net_rec *net, long id);

#ifdef __cplusplus
}
#endif
+26 −6
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@
#include "apr_pools.h"
#include "apr_time.h"
#include "apr_network_io.h"
#include "apr_buckets.h"

#include "pcreposix.h"

@@ -327,7 +328,6 @@ extern "C" {
 */
#define AP_MAX_SENDFILE 16777216


/**
 * Special Apache error codes. These are basically used
 *  in http_main.c so we can keep track of various errors.
@@ -914,15 +914,11 @@ struct conn_rec {

    /* Information about the connection itself */

    /** Connection to the client */
    apr_socket_t *client_socket;

    /* Who is the client? */

    /** local address */
    apr_sockaddr_t *local_addr;
    /** remote address */
    apr_sockaddr_t *remote_addr;

    /** Client's IP address */
    char *remote_ip;
    /** Client's DNS name, if known.  NULL if DNS hasn't been checked,
@@ -1058,6 +1054,30 @@ struct server_rec {
    int limit_req_fields; 
};

typedef struct core_output_filter_ctx {
    apr_bucket_brigade *b;
    apr_pool_t *subpool; /* subpool of c->pool used for data saved after a
                          * request is finished
                          */
    int subpool_has_stuff; /* anything in the subpool? */
} core_output_filter_ctx_t;
 
typedef struct core_filter_ctx {
    apr_bucket_brigade *b;
    int first_line;
} core_ctx_t;
 
typedef struct core_net_rec {
    /** Connection to the client */
    apr_socket_t *client_socket;

    /** connection record */
    conn_rec *c;
 
    core_output_filter_ctx_t *out_ctx;
    core_ctx_t *in_ctx;
} core_net_rec;

/**
 * Examine a field value (such as a media-/content-type) string and return
 * it sans any parameters; e.g., strip off any ';charset=foo' and the like.
+0 −9
Original line number Diff line number Diff line
@@ -263,13 +263,6 @@ static const char *http_method(const request_rec *r)
static apr_port_t http_port(const request_rec *r)
    { return DEFAULT_HTTP_PORT; }

static int ap_pre_http_connection(conn_rec *c)
{
    ap_add_input_filter("CORE_IN", NULL, NULL, c);
    ap_add_output_filter("CORE", NULL, NULL, c);
    return OK;
}
 
static int ap_process_http_connection(conn_rec *c)
{
    request_rec *r;
@@ -315,8 +308,6 @@ static void ap_http_insert_filter(request_rec *r)

static void register_hooks(apr_pool_t *p)
{
    ap_hook_pre_connection(ap_pre_http_connection,NULL,NULL,
			       APR_HOOK_REALLY_LAST);
    ap_hook_process_connection(ap_process_http_connection,NULL,NULL,
			       APR_HOOK_REALLY_LAST);
    ap_hook_map_to_storage(ap_send_http_trace,NULL,NULL,APR_HOOK_MIDDLE);
+22 −20
Original line number Diff line number Diff line
@@ -76,10 +76,14 @@
APR_HOOK_STRUCT(
	    APR_HOOK_LINK(pre_connection)
	    APR_HOOK_LINK(process_connection)
            APR_HOOK_LINK(create_connection)
)

AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c),(c),OK,DECLINED)
AP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED)
AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection,
                     (apr_pool_t *p, apr_socket_t *csd, int my_child_num),
                     (p, csd, my_child_num), NULL)

/*
 * More machine-dependent networking gooo... on some systems,
@@ -156,13 +160,13 @@ apr_status_t ap_lingering_close(void *dummy)
    apr_status_t rc;
    apr_int32_t timeout;
    apr_int32_t total_linger_time = 0;
    conn_rec *c = dummy;
    core_net_rec *net = dummy;

    ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_CLOSING, NULL);
    ap_update_child_status(AP_CHILD_THREAD_FROM_ID(net->c->id), SERVER_CLOSING, NULL);

#ifdef NO_LINGCLOSE
    ap_flush_conn(c);	/* just close it */
    apr_socket_close(c->client_socket);
    ap_flush_conn(net->c);	/* just close it */
    apr_socket_close(net->client_socket);
    return;
#endif

@@ -172,21 +176,18 @@ apr_status_t ap_lingering_close(void *dummy)
     */

    /* Send any leftover data to the client, but never try to again */
    ap_flush_conn(c);
    ap_flush_conn(net->c);

    if (c->aborted) {
        apr_socket_close(c->client_socket);
    if (net->c->aborted) {
        apr_socket_close(net->client_socket);
        return APR_SUCCESS;
    }

    /* Shut down the socket for write, which will send a FIN
     * to the peer.
     */
    
    if (apr_shutdown(c->client_socket, APR_SHUTDOWN_WRITE) != APR_SUCCESS || 
        c->aborted) {
        apr_socket_close(c->client_socket);
        return APR_SUCCESS;
    if (apr_shutdown(net->client_socket, APR_SHUTDOWN_WRITE) != APR_SUCCESS || 
        net->c->aborted) {
    }

    /* Read all data from the peer until we reach "end-of-file" (FIN
@@ -195,11 +196,11 @@ apr_status_t ap_lingering_close(void *dummy)
     * which seems to work well), close the connection.
     */
    timeout = SECONDS_TO_LINGER * APR_USEC_PER_SEC;
    apr_setsocketopt(c->client_socket, APR_SO_TIMEOUT, timeout);
    apr_setsocketopt(c->client_socket, APR_INCOMPLETE_READ, 1);
    apr_setsocketopt(net->client_socket, APR_SO_TIMEOUT, timeout);
    apr_setsocketopt(net->client_socket, APR_INCOMPLETE_READ, 1);
    for (;;) {
        nbytes = sizeof(dummybuf);
        rc = apr_recv(c->client_socket, dummybuf, &nbytes);
        rc = apr_recv(net->client_socket, dummybuf, &nbytes);
        if (rc != APR_SUCCESS || nbytes == 0) break;

        total_linger_time += SECONDS_TO_LINGER;
@@ -208,7 +209,7 @@ apr_status_t ap_lingering_close(void *dummy)
        }
    }

    apr_socket_close(c->client_socket);
    apr_socket_close(net->client_socket);
    return APR_SUCCESS;
}

@@ -226,8 +227,9 @@ AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c)
   structure, but for now...
*/

AP_CORE_DECLARE(conn_rec *)ap_new_connection(apr_pool_t *p, server_rec *server, 
                            apr_socket_t *inout, long id)
AP_CORE_DECLARE(conn_rec *)ap_core_new_connection(apr_pool_t *p, 
                            server_rec *server, apr_socket_t *inout, 
                            core_net_rec *net, long id)
{
    conn_rec *conn = (conn_rec *) apr_pcalloc(p, sizeof(conn_rec));
    apr_status_t rv;
@@ -260,11 +262,11 @@ AP_CORE_DECLARE(conn_rec *)ap_new_connection(apr_pool_t *p, server_rec *server,
    }
    apr_sockaddr_ip_get(&conn->remote_ip, conn->remote_addr);
    conn->base_server = server;
    conn->client_socket = inout;
    net->client_socket = inout;

    conn->id = id;

    apr_pool_cleanup_register(p, conn, ap_lingering_close, apr_pool_cleanup_null);
    apr_pool_cleanup_register(p, net, ap_lingering_close, apr_pool_cleanup_null);

    return conn;
}
Loading