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
*/
#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.
*/
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
/* Information about the connection itself */
+ /** Connection to the client */
+ apr_socket_t *client_socket;
+
/** local address */
apr_sockaddr_t *local_addr;
/** remote address */
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
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;
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);
}
/* 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 */
}
/* 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 */
"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
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,
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;
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;
+}
*/
#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,
* 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)
{
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) {
{
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;
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 */
{
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 */
/* 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
#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;
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);
}
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);
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);
}
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);
}
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);
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);
* 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);
}
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);
* 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);
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);
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);