From: Bill Stoddard Date: Sun, 27 Jan 2002 12:52:08 +0000 (+0000) Subject: Remove the create_connection hook and put the client_socket back into the X-Git-Tag: 2.0.31~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=327e4989d592388c364b7f1e64d3086b54c7ad61;p=apache Remove the create_connection hook and put the client_socket back into the conn_rec. The create_connection_hook has a design flaw that prevents it from making decisions based on vhost information. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93050 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 05ef7ebdff..b3e5ec4d0a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,7 @@ Changes with Apache 2.0.31-dev + *) Add the socket back to the conn_rec and remove the create_connection + hook. The create_connection hook had a design flaw that did not + allow creating connections based on vhost info. [Bill Stoddard] *) Fixed PATH_INFO and QUERY_STRING from mod_negotiation results. Resolves the common case of using negotation to resolve the request diff --git a/include/http_connection.h b/include/http_connection.h index 5cf0ade10f..5cbcb86cd9 100644 --- a/include/http_connection.h +++ b/include/http_connection.h @@ -67,6 +67,17 @@ extern "C" { */ #ifdef CORE_PRIVATE +/** + * Create a new connection. + * @param p Pool to allocate data structures out of + * @param server The server to create the connection for + * @param csd The socket to use for all communication with the client + * @param id ID of this connection; unique at any point in time. + * @param sbh Scoreboard handle + * @return new conn_rec, or NULL if the connection has already been reset + */ +AP_CORE_DECLARE(conn_rec *)ap_new_connection(apr_pool_t *ptrans, server_rec *server, + apr_socket_t *csd, long id, void *sbh); /** * This is the protocol module driver. This calls all of the * pre-connection and connection hooks for all protocol modules. @@ -117,22 +128,6 @@ AP_DECLARE_HOOK(int,pre_connection,(conn_rec *c)) */ AP_DECLARE_HOOK(int,process_connection,(conn_rec *c)) -/** - * This hook allows modules to create connections. After the connection - * has been accepted, the socket is passed to this function to actually - * insert all filters that operate on the network, and create the connection - * record. The first module to create a connection is the last module - * run - * @param p The pool from which to allocate the connection record - * @param csd The socket that has been accepted - * @param conn_id A unique identifier for this connection. The ID only - * needs to be unique at that time, not forever. - * @param sbh A handle to scoreboard information for this connection. - * @return An allocated connection record or NULL. - */ -AP_DECLARE_HOOK(conn_rec *, create_connection, - (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id, void *sbh)) - #ifdef __cplusplus } #endif diff --git a/include/httpd.h b/include/httpd.h index fb1267cfd9..ed0c332e27 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -937,6 +937,9 @@ struct conn_rec { /* Information about the connection itself */ + /** Connection to the client */ + apr_socket_t *client_socket; + /** local address */ apr_sockaddr_t *local_addr; /** remote address */ @@ -1090,17 +1093,6 @@ typedef struct core_output_filter_ctx { typedef struct core_filter_ctx { apr_bucket_brigade *b; } 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 diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 54ce6f772b..b61877b049 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -259,7 +259,12 @@ 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; @@ -306,6 +311,8 @@ 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); diff --git a/modules/proxy/proxy_ftp.c b/modules/proxy/proxy_ftp.c index 6d2c2b8a54..34e16c3179 100644 --- a/modules/proxy/proxy_ftp.c +++ b/modules/proxy/proxy_ftp.c @@ -746,7 +746,7 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, } /* the socket is now open, create a new connection */ - origin = ap_run_create_connection(p, r->server, sock, r->connection->id, r->connection->sbh); + origin = ap_new_connection(p, r->server, sock, r->connection->id, r->connection->sbh); if (!origin) { /* the peer reset the connection already; ap_new_connection() * closed the socket */ @@ -1549,7 +1549,7 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, } /* the transfer socket is now open, create a new connection */ - remote = ap_run_create_connection(p, r->server, remote_sock, r->connection->id, r->connection->sbh); + remote = ap_new_connection(p, r->server, remote_sock, r->connection->id, r->connection->sbh); if (!remote) { /* the peer reset the connection already; ap_new_connection() * closed the socket */ diff --git a/modules/proxy/proxy_http.c b/modules/proxy/proxy_http.c index 4895e05332..ebaf107db8 100644 --- a/modules/proxy/proxy_http.c +++ b/modules/proxy/proxy_http.c @@ -422,8 +422,8 @@ apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r, "proxy: socket is connected"); /* the socket is now open, create a new backend server connection */ - *origin = ap_run_create_connection(c->pool, r->server, p_conn->sock, - r->connection->id, r->connection->sbh); + *origin = ap_new_connection(c->pool, r->server, p_conn->sock, + r->connection->id, r->connection->sbh); if (!origin) { /* the peer reset the connection already; ap_new_connection() * closed the socket diff --git a/server/connection.c b/server/connection.c index 2ca5820a3f..d812bd4d1c 100644 --- a/server/connection.c +++ b/server/connection.c @@ -77,14 +77,10 @@ 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, server_rec *server, apr_socket_t *csd, int conn_id, void *sbh), - (p, server, csd, conn_id, sbh), NULL) /* * More machine-dependent networking gooo... on some systems, @@ -161,7 +157,7 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c) apr_status_t rc; apr_int32_t timeout; apr_int32_t total_linger_time = 0; - apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module); + apr_socket_t *csd = c->client_socket; if (!csd) { return; @@ -230,3 +226,51 @@ AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c) ap_run_process_connection(c); } } +AP_CORE_DECLARE(conn_rec *)ap_new_connection(apr_pool_t *ptrans, server_rec *server, + apr_socket_t *csd, long id, void *sbh) +{ + apr_status_t rv; + conn_rec *c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); + + c->sbh = sbh; + (void) ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *) NULL); + +#ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK + /* BillS says perhaps this should be moved to the MPMs. Some OSes + * allow listening socket attributes to be inherited by the + * accept sockets which means this call only needs to be made + * once on the listener + */ + ap_sock_disable_nagle(csd); +#endif + + /* Got a connection structure, so initialize what fields we can + * (the rest are zeroed out by pcalloc). + */ + c->conn_config=ap_create_conn_config(ptrans); + c->notes = apr_table_make(ptrans, 5); + + c->pool = ptrans; + if ((rv = apr_socket_addr_get(&c->local_addr, APR_LOCAL, csd)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, + "apr_socket_addr_get(APR_LOCAL)"); + apr_socket_close(csd); + return NULL; + } + apr_sockaddr_ip_get(&c->local_ip, c->local_addr); + if ((rv = apr_socket_addr_get(&c->remote_addr, APR_REMOTE, csd)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, + "apr_socket_addr_get(APR_REMOTE)"); + apr_socket_close(csd); + return NULL; + } + apr_sockaddr_ip_get(&c->remote_ip, c->remote_addr); + c->base_server = server; + c->client_socket = csd; + + c->id = id; + + return c; +} diff --git a/server/core.c b/server/core.c index a26d4eb1a1..cdcea13ec0 100644 --- a/server/core.c +++ b/server/core.c @@ -2405,7 +2405,7 @@ static apr_status_t writev_it_all(apr_socket_t *s, */ #if APR_HAS_SENDFILE -static apr_status_t sendfile_it_all(core_net_rec *c, +static apr_status_t sendfile_it_all(conn_rec *c, apr_file_t *fd, apr_hdtr_t *hdtr, apr_off_t file_offset, @@ -2490,7 +2490,7 @@ static apr_status_t sendfile_it_all(core_net_rec *c, * to the network. emulate_sendfile will return only when all the bytes have been * sent (i.e., it handles partial writes) or on a network error condition. */ -static apr_status_t emulate_sendfile(core_net_rec *c, apr_file_t *fd, +static apr_status_t emulate_sendfile(conn_rec *c, apr_file_t *fd, apr_hdtr_t *hdtr, apr_off_t offset, apr_size_t length, apr_size_t *nbytes) { @@ -2994,7 +2994,7 @@ static int net_time_filter(ap_filter_t *f, apr_bucket_brigade *b, apr_off_t readbytes) { int keptalive = f->c->keepalive == 1; - apr_socket_t *csd = ap_get_module_config(f->c->conn_config, &core_module); + apr_socket_t *csd = f->c->client_socket; int *first_line = f->ctx; if (!f->ctx) { @@ -3026,8 +3026,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, { apr_bucket *e; apr_status_t rv; - core_net_rec *net = f->ctx; - core_ctx_t *ctx = net->in_ctx; + core_ctx_t *ctx = f->ctx; const char *str; apr_size_t len; @@ -3047,13 +3046,12 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, if (!ctx) { - ctx = apr_pcalloc(f->c->pool, sizeof(*ctx)); + f->ctx = ctx = apr_pcalloc(f->c->pool, sizeof(*ctx)); ctx->b = apr_brigade_create(f->c->pool); /* seed the brigade with the client socket. */ - e = apr_bucket_socket_create(net->client_socket); + e = apr_bucket_socket_create(f->c->client_socket); APR_BRIGADE_INSERT_TAIL(ctx->b, e); - net->in_ctx = ctx; } else if (APR_BRIGADE_EMPTY(ctx->b)) { /* hit EOF on socket already */ @@ -3202,12 +3200,10 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) { apr_status_t rv; conn_rec *c = f->c; - core_net_rec *net = f->ctx; - core_output_filter_ctx_t *ctx = net->out_ctx; + core_output_filter_ctx_t *ctx = f->ctx; if (ctx == NULL) { - ctx = apr_pcalloc(c->pool, sizeof(core_output_filter_ctx_t)); - net->out_ctx = ctx; + f->ctx = ctx = apr_pcalloc(c->pool, sizeof(*ctx)); } /* If we have a saved brigade, concatenate the new brigade to it */ @@ -3463,7 +3459,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) /* Prepare the socket to be reused */ flags |= APR_SENDFILE_DISCONNECT_SOCKET; } - rv = sendfile_it_all(net, /* the network information */ + rv = sendfile_it_all(c, /* the network information */ fd, /* the file to send */ &hdtr, /* header and trailer iovecs */ foffset, /* offset in the file to begin @@ -3482,7 +3478,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) #endif { apr_size_t unused_bytes_sent; - rv = emulate_sendfile(net, fd, &hdtr, foffset, flen, + rv = emulate_sendfile(c, fd, &hdtr, foffset, flen, &unused_bytes_sent); } fd = NULL; @@ -3490,7 +3486,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) else { apr_size_t unused_bytes_sent; - rv = writev_it_all(net->client_socket, + rv = writev_it_all(c->client_socket, vec, nvec, nbytes, &unused_bytes_sent); } @@ -3612,59 +3608,6 @@ static int core_create_proxy_req(request_rec *r, request_rec *pr) return core_create_req(pr); } -static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, - apr_socket_t *csd, int conn_id, void *sbh) -{ - core_net_rec *net = apr_palloc(ptrans, sizeof(*net)); - apr_status_t rv; - -#ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK - ap_sock_disable_nagle(csd); -#endif - - net->in_ctx = NULL; - net->out_ctx = NULL; - net->c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); - - net->c->sbh = sbh; - (void) ap_update_child_status(net->c->sbh, SERVER_BUSY_READ, (request_rec *) NULL); - - /* Got a connection structure, so initialize what fields we can - * (the rest are zeroed out by pcalloc). - */ - - net->c->conn_config=ap_create_conn_config(ptrans); - net->c->notes = apr_table_make(ptrans, 5); - - net->c->pool = ptrans; - if ((rv = apr_socket_addr_get(&net->c->local_addr, APR_LOCAL, csd)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, - "apr_socket_addr_get(APR_LOCAL)"); - apr_socket_close(csd); - return NULL; - } - apr_sockaddr_ip_get(&net->c->local_ip, net->c->local_addr); - if ((rv = apr_socket_addr_get(&net->c->remote_addr, APR_REMOTE, csd)) - != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, - "apr_socket_addr_get(APR_REMOTE)"); - apr_socket_close(csd); - return NULL; - } - apr_sockaddr_ip_get(&net->c->remote_ip, net->c->remote_addr); - net->c->base_server = server; - net->client_socket = csd; - - net->c->id = conn_id; - - ap_set_module_config(net->c->conn_config, &core_module, csd); - ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL, net->c); - ap_add_output_filter_handle(ap_core_output_filter_handle, - net, NULL, net->c); - return net->c; -} - static void register_hooks(apr_pool_t *p) { ap_hook_post_config(core_post_config,NULL,NULL,APR_HOOK_REALLY_FIRST); @@ -3676,7 +3619,6 @@ static void register_hooks(apr_pool_t *p) ap_hook_type_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST); ap_hook_fixups(core_override_type,NULL,NULL,APR_HOOK_REALLY_FIRST); ap_hook_access_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST); - ap_hook_create_connection(core_create_conn, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_create_request(core_create_req, NULL, NULL, APR_HOOK_MIDDLE); APR_OPTIONAL_HOOK(proxy, create_req, core_create_proxy_req, NULL, NULL, APR_HOOK_MIDDLE); diff --git a/server/mpm/beos/beos.c b/server/mpm/beos/beos.c index af6baf899e..f9800d7b87 100644 --- a/server/mpm/beos/beos.c +++ b/server/mpm/beos/beos.c @@ -346,7 +346,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num) } ap_create_sb_handle(&sbh, p, 0, my_child_num); - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); + current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); diff --git a/server/mpm/experimental/perchild/perchild.c b/server/mpm/experimental/perchild/perchild.c index 9edffedfa1..b02c76be5a 100644 --- a/server/mpm/experimental/perchild/perchild.c +++ b/server/mpm/experimental/perchild/perchild.c @@ -567,7 +567,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) } ap_create_sb_handle(&sbh, p, conn_id / thread_limit, thread_num); - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); + current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); diff --git a/server/mpm/mpmt_os2/mpmt_os2_child.c b/server/mpm/mpmt_os2/mpmt_os2_child.c index 6475fa599a..b1824f0075 100644 --- a/server/mpm/mpmt_os2/mpmt_os2_child.c +++ b/server/mpm/mpmt_os2/mpmt_os2_child.c @@ -430,7 +430,7 @@ static void worker_main(void *vpArg) rc == 0 && rd.ulData != WORKTYPE_EXIT) { pconn = worker_args->pconn; ap_create_sb_handle(&sbh, pconn, child_slot, thread_slot); - current_conn = ap_run_create_connection(pconn, ap_server_conf, worker_args->conn_sd, conn_id, sbh); + current_conn = ap_new_connection(pconn, ap_server_conf, worker_args->conn_sd, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); diff --git a/server/mpm/netware/mpm_netware.c b/server/mpm/netware/mpm_netware.c index be1ff462dc..eed96e7847 100644 --- a/server/mpm/netware/mpm_netware.c +++ b/server/mpm/netware/mpm_netware.c @@ -523,8 +523,8 @@ got_listener: * We now have a connection, so set it up with the appropriate * socket options, file descriptors, and read/write buffers. */ - current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, - my_worker_num, sbh); + current_conn = ap_new_connection(ptrans, ap_server_conf, csd, + my_worker_num, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); diff --git a/server/mpm/perchild/perchild.c b/server/mpm/perchild/perchild.c index 9edffedfa1..b02c76be5a 100644 --- a/server/mpm/perchild/perchild.c +++ b/server/mpm/perchild/perchild.c @@ -567,7 +567,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) } ap_create_sb_handle(&sbh, p, conn_id / thread_limit, thread_num); - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); + current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index b8d1213bd3..3710663180 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -712,7 +712,7 @@ static void child_main(int child_num_arg) * socket options, file descriptors, and read/write buffers. */ - current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh); + current_conn = ap_new_connection(ptrans, ap_server_conf, csd, my_child_num, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index e6cd50767b..4b05832108 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -923,8 +923,8 @@ static void worker_main(int thread_num) apr_os_sock_make(&context->sock, &sockinfo, context->ptrans); ap_create_sb_handle(&sbh, context->ptrans, 0, thread_num); - c = ap_run_create_connection(context->ptrans, ap_server_conf, context->sock, - thread_num, sbh); + c = ap_new_connection(context->ptrans, ap_server_conf, context->sock, + thread_num, sbh); if (c) { ap_process_connection(c); diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index d255290867..137bc4aaa6 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -557,7 +557,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, return; } - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); + current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn);