mirror of
https://github.com/apache/httpd.git
synced 2025-11-05 05:30:39 +03:00
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
This commit is contained in:
8
CHANGES
8
CHANGES
@@ -1,5 +1,13 @@
|
|||||||
Changes with Apache 2.0.29-dev
|
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
|
*) Really reset the MaxClients value in worker and threaded
|
||||||
when the configured value is not a multiple of the number
|
when the configured value is not a multiple of the number
|
||||||
of threads per child. We said we did previously but we
|
of threads per child. We said we did previously but we
|
||||||
|
|||||||
@@ -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(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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -80,6 +80,7 @@
|
|||||||
#include "apr_pools.h"
|
#include "apr_pools.h"
|
||||||
#include "apr_time.h"
|
#include "apr_time.h"
|
||||||
#include "apr_network_io.h"
|
#include "apr_network_io.h"
|
||||||
|
#include "apr_buckets.h"
|
||||||
|
|
||||||
#include "pcreposix.h"
|
#include "pcreposix.h"
|
||||||
|
|
||||||
@@ -327,7 +328,6 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define AP_MAX_SENDFILE 16777216
|
#define AP_MAX_SENDFILE 16777216
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special Apache error codes. These are basically used
|
* Special Apache error codes. These are basically used
|
||||||
* in http_main.c so we can keep track of various errors.
|
* in http_main.c so we can keep track of various errors.
|
||||||
@@ -914,15 +914,11 @@ struct conn_rec {
|
|||||||
|
|
||||||
/* Information about the connection itself */
|
/* Information about the connection itself */
|
||||||
|
|
||||||
/** Connection to the client */
|
|
||||||
apr_socket_t *client_socket;
|
|
||||||
|
|
||||||
/* Who is the client? */
|
|
||||||
|
|
||||||
/** local address */
|
/** local address */
|
||||||
apr_sockaddr_t *local_addr;
|
apr_sockaddr_t *local_addr;
|
||||||
/** remote address */
|
/** remote address */
|
||||||
apr_sockaddr_t *remote_addr;
|
apr_sockaddr_t *remote_addr;
|
||||||
|
|
||||||
/** Client's IP address */
|
/** Client's IP address */
|
||||||
char *remote_ip;
|
char *remote_ip;
|
||||||
/** Client's DNS name, if known. NULL if DNS hasn't been checked,
|
/** Client's DNS name, if known. NULL if DNS hasn't been checked,
|
||||||
@@ -1058,6 +1054,30 @@ struct server_rec {
|
|||||||
int limit_req_fields;
|
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
|
* 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.
|
* it sans any parameters; e.g., strip off any ';charset=foo' and the like.
|
||||||
|
|||||||
@@ -263,13 +263,6 @@ static const char *http_method(const request_rec *r)
|
|||||||
static apr_port_t http_port(const request_rec *r)
|
static apr_port_t http_port(const request_rec *r)
|
||||||
{ return DEFAULT_HTTP_PORT; }
|
{ 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)
|
static int ap_process_http_connection(conn_rec *c)
|
||||||
{
|
{
|
||||||
request_rec *r;
|
request_rec *r;
|
||||||
@@ -315,8 +308,6 @@ static void ap_http_insert_filter(request_rec *r)
|
|||||||
|
|
||||||
static void register_hooks(apr_pool_t *p)
|
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,
|
ap_hook_process_connection(ap_process_http_connection,NULL,NULL,
|
||||||
APR_HOOK_REALLY_LAST);
|
APR_HOOK_REALLY_LAST);
|
||||||
ap_hook_map_to_storage(ap_send_http_trace,NULL,NULL,APR_HOOK_MIDDLE);
|
ap_hook_map_to_storage(ap_send_http_trace,NULL,NULL,APR_HOOK_MIDDLE);
|
||||||
|
|||||||
@@ -76,10 +76,14 @@
|
|||||||
APR_HOOK_STRUCT(
|
APR_HOOK_STRUCT(
|
||||||
APR_HOOK_LINK(pre_connection)
|
APR_HOOK_LINK(pre_connection)
|
||||||
APR_HOOK_LINK(process_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_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(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,
|
* 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_status_t rc;
|
||||||
apr_int32_t timeout;
|
apr_int32_t timeout;
|
||||||
apr_int32_t total_linger_time = 0;
|
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
|
#ifdef NO_LINGCLOSE
|
||||||
ap_flush_conn(c); /* just close it */
|
ap_flush_conn(net->c); /* just close it */
|
||||||
apr_socket_close(c->client_socket);
|
apr_socket_close(net->client_socket);
|
||||||
return;
|
return;
|
||||||
#endif
|
#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 */
|
/* Send any leftover data to the client, but never try to again */
|
||||||
ap_flush_conn(c);
|
ap_flush_conn(net->c);
|
||||||
|
|
||||||
if (c->aborted) {
|
if (net->c->aborted) {
|
||||||
apr_socket_close(c->client_socket);
|
apr_socket_close(net->client_socket);
|
||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shut down the socket for write, which will send a FIN
|
/* Shut down the socket for write, which will send a FIN
|
||||||
* to the peer.
|
* to the peer.
|
||||||
*/
|
*/
|
||||||
|
if (apr_shutdown(net->client_socket, APR_SHUTDOWN_WRITE) != APR_SUCCESS ||
|
||||||
if (apr_shutdown(c->client_socket, APR_SHUTDOWN_WRITE) != APR_SUCCESS ||
|
net->c->aborted) {
|
||||||
c->aborted) {
|
|
||||||
apr_socket_close(c->client_socket);
|
|
||||||
return APR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read all data from the peer until we reach "end-of-file" (FIN
|
/* 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.
|
* which seems to work well), close the connection.
|
||||||
*/
|
*/
|
||||||
timeout = SECONDS_TO_LINGER * APR_USEC_PER_SEC;
|
timeout = SECONDS_TO_LINGER * APR_USEC_PER_SEC;
|
||||||
apr_setsocketopt(c->client_socket, APR_SO_TIMEOUT, timeout);
|
apr_setsocketopt(net->client_socket, APR_SO_TIMEOUT, timeout);
|
||||||
apr_setsocketopt(c->client_socket, APR_INCOMPLETE_READ, 1);
|
apr_setsocketopt(net->client_socket, APR_INCOMPLETE_READ, 1);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nbytes = sizeof(dummybuf);
|
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;
|
if (rc != APR_SUCCESS || nbytes == 0) break;
|
||||||
|
|
||||||
total_linger_time += SECONDS_TO_LINGER;
|
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;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,8 +227,9 @@ AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c)
|
|||||||
structure, but for now...
|
structure, but for now...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AP_CORE_DECLARE(conn_rec *)ap_new_connection(apr_pool_t *p, server_rec *server,
|
AP_CORE_DECLARE(conn_rec *)ap_core_new_connection(apr_pool_t *p,
|
||||||
apr_socket_t *inout, long id)
|
server_rec *server, apr_socket_t *inout,
|
||||||
|
core_net_rec *net, long id)
|
||||||
{
|
{
|
||||||
conn_rec *conn = (conn_rec *) apr_pcalloc(p, sizeof(conn_rec));
|
conn_rec *conn = (conn_rec *) apr_pcalloc(p, sizeof(conn_rec));
|
||||||
apr_status_t rv;
|
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);
|
apr_sockaddr_ip_get(&conn->remote_ip, conn->remote_addr);
|
||||||
conn->base_server = server;
|
conn->base_server = server;
|
||||||
conn->client_socket = inout;
|
net->client_socket = inout;
|
||||||
|
|
||||||
conn->id = id;
|
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;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
#include "scoreboard.h"
|
#include "scoreboard.h"
|
||||||
#include "mod_core.h"
|
#include "mod_core.h"
|
||||||
#include "mod_proxy.h"
|
#include "mod_proxy.h"
|
||||||
|
#include "ap_listen.h"
|
||||||
|
|
||||||
/* LimitXMLRequestBody handling */
|
/* LimitXMLRequestBody handling */
|
||||||
#define AP_LIMIT_UNSET ((long) -1)
|
#define AP_LIMIT_UNSET ((long) -1)
|
||||||
@@ -105,7 +105,6 @@ AP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items,
|
|||||||
(apr_pool_t *p, const char *val, apr_hash_t *ht),
|
(apr_pool_t *p, const char *val, apr_hash_t *ht),
|
||||||
(p, val, ht), OK, DECLINED)
|
(p, val, ht), OK, DECLINED)
|
||||||
|
|
||||||
|
|
||||||
/* Server core module... This module provides support for really basic
|
/* Server core module... This module provides support for really basic
|
||||||
* server operations, including options and commands which control the
|
* server operations, including options and commands which control the
|
||||||
* operation of other modules. Consider this the bureaucracy module.
|
* operation of other modules. Consider this the bureaucracy module.
|
||||||
@@ -639,10 +638,8 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
|
|||||||
&& conn->remote_host == NULL
|
&& conn->remote_host == NULL
|
||||||
&& (type == REMOTE_DOUBLE_REV
|
&& (type == REMOTE_DOUBLE_REV
|
||||||
|| hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
|
|| hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
|
||||||
apr_sockaddr_t *remote_addr;
|
|
||||||
|
|
||||||
apr_socket_addr_get(&remote_addr, APR_REMOTE, conn->client_socket);
|
if (apr_getnameinfo(&conn->remote_host, conn->remote_addr, 0) == APR_SUCCESS) {
|
||||||
if (apr_getnameinfo(&conn->remote_host, remote_addr, 0) == APR_SUCCESS) {
|
|
||||||
ap_str_tolower(conn->remote_host);
|
ap_str_tolower(conn->remote_host);
|
||||||
|
|
||||||
if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
|
if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
|
||||||
@@ -731,10 +728,8 @@ AP_DECLARE(const char *) ap_get_server_name(request_rec *r)
|
|||||||
}
|
}
|
||||||
if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
|
if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
|
||||||
if (conn->local_host == NULL) {
|
if (conn->local_host == NULL) {
|
||||||
apr_sockaddr_t *local_addr;
|
|
||||||
|
|
||||||
apr_socket_addr_get(&local_addr, APR_LOCAL, conn->client_socket);
|
if (apr_getnameinfo(&conn->local_host, conn->local_addr, 0) != APR_SUCCESS)
|
||||||
if (apr_getnameinfo(&conn->local_host, local_addr, 0) != APR_SUCCESS)
|
|
||||||
conn->local_host = apr_pstrdup(conn->pool, r->server->server_hostname);
|
conn->local_host = apr_pstrdup(conn->pool, r->server->server_hostname);
|
||||||
else {
|
else {
|
||||||
ap_str_tolower(conn->local_host);
|
ap_str_tolower(conn->local_host);
|
||||||
@@ -2222,7 +2217,7 @@ static apr_status_t writev_it_all(apr_socket_t *s,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if APR_HAS_SENDFILE
|
#if APR_HAS_SENDFILE
|
||||||
static apr_status_t sendfile_it_all(conn_rec *c,
|
static apr_status_t sendfile_it_all(core_net_rec *c,
|
||||||
apr_file_t *fd,
|
apr_file_t *fd,
|
||||||
apr_hdtr_t *hdtr,
|
apr_hdtr_t *hdtr,
|
||||||
apr_off_t file_offset,
|
apr_off_t file_offset,
|
||||||
@@ -2307,7 +2302,7 @@ static apr_status_t sendfile_it_all(conn_rec *c,
|
|||||||
* to the network. emulate_sendfile will return only when all the bytes have been
|
* 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.
|
* sent (i.e., it handles partial writes) or on a network error condition.
|
||||||
*/
|
*/
|
||||||
static apr_status_t emulate_sendfile(conn_rec *c, apr_file_t *fd,
|
static apr_status_t emulate_sendfile(core_net_rec *c, apr_file_t *fd,
|
||||||
apr_hdtr_t *hdtr, apr_off_t offset,
|
apr_hdtr_t *hdtr, apr_off_t offset,
|
||||||
apr_size_t length, apr_size_t *nbytes)
|
apr_size_t length, apr_size_t *nbytes)
|
||||||
{
|
{
|
||||||
@@ -2785,26 +2780,40 @@ static int default_handler(request_rec *r)
|
|||||||
return ap_pass_brigade(r->output_filters, bb);
|
return ap_pass_brigade(r->output_filters, bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct core_filter_ctx {
|
|
||||||
apr_bucket_brigade *b;
|
|
||||||
} core_ctx_t;
|
|
||||||
|
|
||||||
static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_off_t *readbytes)
|
static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_off_t *readbytes)
|
||||||
{
|
{
|
||||||
apr_bucket *e;
|
apr_bucket *e;
|
||||||
apr_status_t rv;
|
apr_status_t rv;
|
||||||
core_ctx_t *ctx = f->ctx;
|
core_net_rec *net = f->ctx;
|
||||||
|
core_ctx_t *ctx = net->in_ctx;
|
||||||
const char *str;
|
const char *str;
|
||||||
apr_size_t len;
|
apr_size_t len;
|
||||||
|
int keptalive = f->c->keepalive == 1;
|
||||||
|
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
{
|
{
|
||||||
f->ctx = ctx = apr_pcalloc(f->c->pool, sizeof(*ctx));
|
ctx = apr_pcalloc(f->c->pool, sizeof(*ctx));
|
||||||
ctx->b = apr_brigade_create(f->c->pool);
|
ctx->b = apr_brigade_create(f->c->pool);
|
||||||
|
|
||||||
/* seed the brigade with the client socket. */
|
/* seed the brigade with the client socket. */
|
||||||
e = apr_bucket_socket_create(f->c->client_socket);
|
e = apr_bucket_socket_create(net->client_socket);
|
||||||
APR_BRIGADE_INSERT_TAIL(ctx->b, e);
|
APR_BRIGADE_INSERT_TAIL(ctx->b, e);
|
||||||
|
net->in_ctx = ctx;
|
||||||
|
ctx->first_line = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->first_line) {
|
||||||
|
apr_setsocketopt(net->client_socket, APR_SO_TIMEOUT,
|
||||||
|
(int)(keptalive
|
||||||
|
? f->c->base_server->keep_alive_timeout * APR_USEC_PER_SEC
|
||||||
|
: f->c->base_server->timeout * APR_USEC_PER_SEC));
|
||||||
|
ctx->first_line = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (keptalive) {
|
||||||
|
apr_setsocketopt(net->client_socket, APR_SO_TIMEOUT,
|
||||||
|
(int)(f->c->base_server->timeout * APR_USEC_PER_SEC));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ### This is bad. */
|
/* ### This is bad. */
|
||||||
@@ -2964,24 +2973,18 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mod
|
|||||||
* is to send the headers if they haven't already been sent, and then send
|
* is to send the headers if they haven't already been sent, and then send
|
||||||
* the actual data.
|
* the actual data.
|
||||||
*/
|
*/
|
||||||
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;
|
|
||||||
|
|
||||||
#define MAX_IOVEC_TO_WRITE 16
|
#define MAX_IOVEC_TO_WRITE 16
|
||||||
|
|
||||||
static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
||||||
{
|
{
|
||||||
apr_status_t rv;
|
apr_status_t rv;
|
||||||
conn_rec *c = f->c;
|
conn_rec *c = f->c;
|
||||||
core_output_filter_ctx_t *ctx = f->ctx;
|
core_net_rec *net = f->ctx;
|
||||||
|
core_output_filter_ctx_t *ctx = net->out_ctx;
|
||||||
|
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
f->ctx = ctx = apr_pcalloc(c->pool, sizeof(core_output_filter_ctx_t));
|
ctx = apr_pcalloc(c->pool, sizeof(core_output_filter_ctx_t));
|
||||||
|
net->out_ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have a saved brigade, concatenate the new brigade to it */
|
/* If we have a saved brigade, concatenate the new brigade to it */
|
||||||
@@ -3163,7 +3166,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
|||||||
/* Prepare the socket to be reused */
|
/* Prepare the socket to be reused */
|
||||||
flags |= APR_SENDFILE_DISCONNECT_SOCKET;
|
flags |= APR_SENDFILE_DISCONNECT_SOCKET;
|
||||||
}
|
}
|
||||||
rv = sendfile_it_all(c, /* the connection */
|
rv = sendfile_it_all(net, /* the network information */
|
||||||
fd, /* the file to send */
|
fd, /* the file to send */
|
||||||
&hdtr, /* header and trailer iovecs */
|
&hdtr, /* header and trailer iovecs */
|
||||||
foffset, /* offset in the file to begin
|
foffset, /* offset in the file to begin
|
||||||
@@ -3182,7 +3185,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
apr_size_t unused_bytes_sent;
|
apr_size_t unused_bytes_sent;
|
||||||
rv = emulate_sendfile(c, fd, &hdtr, foffset, flen,
|
rv = emulate_sendfile(net, fd, &hdtr, foffset, flen,
|
||||||
&unused_bytes_sent);
|
&unused_bytes_sent);
|
||||||
}
|
}
|
||||||
fd = NULL;
|
fd = NULL;
|
||||||
@@ -3190,7 +3193,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
|||||||
else {
|
else {
|
||||||
apr_size_t unused_bytes_sent;
|
apr_size_t unused_bytes_sent;
|
||||||
|
|
||||||
rv = writev_it_all(c->client_socket,
|
rv = writev_it_all(net->client_socket,
|
||||||
vec, nvec,
|
vec, nvec,
|
||||||
nbytes, &unused_bytes_sent);
|
nbytes, &unused_bytes_sent);
|
||||||
}
|
}
|
||||||
@@ -3273,6 +3276,21 @@ static int core_create_proxy_req(request_rec *r, request_rec *pr)
|
|||||||
return core_create_req(pr);
|
return core_create_req(pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static conn_rec *core_create_conn(apr_pool_t *ptrans, apr_socket_t *csd,
|
||||||
|
int my_child_num)
|
||||||
|
{
|
||||||
|
core_net_rec *net = apr_palloc(ptrans, sizeof(*net));
|
||||||
|
|
||||||
|
net->in_ctx = NULL;
|
||||||
|
net->out_ctx = NULL;
|
||||||
|
net->c = ap_core_new_connection(ptrans, ap_server_conf, csd,
|
||||||
|
net, my_child_num);
|
||||||
|
|
||||||
|
ap_add_input_filter("CORE_IN", net, NULL, net->c);
|
||||||
|
ap_add_output_filter("CORE", net, NULL, net->c);
|
||||||
|
return net->c;
|
||||||
|
}
|
||||||
|
|
||||||
static void register_hooks(apr_pool_t *p)
|
static void register_hooks(apr_pool_t *p)
|
||||||
{
|
{
|
||||||
ap_hook_post_config(core_post_config,NULL,NULL,APR_HOOK_REALLY_FIRST);
|
ap_hook_post_config(core_post_config,NULL,NULL,APR_HOOK_REALLY_FIRST);
|
||||||
@@ -3284,6 +3302,7 @@ static void register_hooks(apr_pool_t *p)
|
|||||||
ap_hook_type_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST);
|
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_fixups(core_override_type,NULL,NULL,APR_HOOK_REALLY_FIRST);
|
||||||
ap_hook_access_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST);
|
ap_hook_access_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST);
|
||||||
|
ap_hook_create_connection(core_create_conn, NULL, NULL, APR_HOOK_REALLY_LAST);
|
||||||
ap_hook_create_request(core_create_req, 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_OPTIONAL_HOOK(proxy, create_req, core_create_proxy_req, NULL, NULL,
|
||||||
APR_HOOK_MIDDLE);
|
APR_HOOK_MIDDLE);
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
|
current_conn = ap_run_create_connection(p, sock, conn_id);
|
||||||
|
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
ap_process_connection(current_conn);
|
ap_process_connection(current_conn);
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id)
|
|||||||
ap_sock_disable_nagle(sock);
|
ap_sock_disable_nagle(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
|
current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id);
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
ap_process_connection(current_conn);
|
ap_process_connection(current_conn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ static void worker_main(void *vpArg)
|
|||||||
rc == 0 && rd.ulData != WORKTYPE_EXIT) {
|
rc == 0 && rd.ulData != WORKTYPE_EXIT) {
|
||||||
pconn = worker_args->pconn;
|
pconn = worker_args->pconn;
|
||||||
ap_sock_disable_nagle(worker_args->conn_sd);
|
ap_sock_disable_nagle(worker_args->conn_sd);
|
||||||
current_conn = ap_new_connection(pconn, ap_server_conf, worker_args->conn_sd, conn_id);
|
current_conn = ap_run_create_connection(pconn, worker_args->conn_sd, conn_id);
|
||||||
|
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
ap_process_connection(current_conn);
|
ap_process_connection(current_conn);
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ got_listener:
|
|||||||
*/
|
*/
|
||||||
ap_sock_disable_nagle(csd);
|
ap_sock_disable_nagle(csd);
|
||||||
|
|
||||||
current_conn = ap_new_connection(ptrans, ap_server_conf, csd, my_worker_num);
|
current_conn = ap_run_create_connection(ptrans, csd, my_worker_num);
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
ap_process_connection(current_conn);
|
ap_process_connection(current_conn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id)
|
|||||||
ap_sock_disable_nagle(sock);
|
ap_sock_disable_nagle(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
|
current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id);
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
ap_process_connection(current_conn);
|
ap_process_connection(current_conn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -789,8 +789,7 @@ static void child_main(int child_num_arg)
|
|||||||
|
|
||||||
ap_sock_disable_nagle(csd);
|
ap_sock_disable_nagle(csd);
|
||||||
|
|
||||||
current_conn = ap_new_connection(ptrans, ap_server_conf, csd,
|
current_conn = ap_run_create_connection(ptrans, csd, my_child_num);
|
||||||
my_child_num);
|
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
ap_process_connection(current_conn);
|
ap_process_connection(current_conn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -680,7 +680,7 @@ static void thread_main(void *thread_num_arg)
|
|||||||
|
|
||||||
ap_sock_disable_nagle(csd);
|
ap_sock_disable_nagle(csd);
|
||||||
|
|
||||||
current_conn = ap_new_connection(ptrans, ap_server_conf, csd,
|
current_conn = ap_run_create_connection(ptrans, csd,
|
||||||
THREAD_GLOBAL(thread_num));
|
THREAD_GLOBAL(thread_num));
|
||||||
|
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
|
|||||||
@@ -475,7 +475,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num,
|
|||||||
|
|
||||||
ap_sock_disable_nagle(sock);
|
ap_sock_disable_nagle(sock);
|
||||||
|
|
||||||
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
|
current_conn = ap_run_create_connection(p, sock, conn_id);
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
ap_process_connection(current_conn);
|
ap_process_connection(current_conn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -893,7 +893,7 @@ static void worker_main(int thread_num)
|
|||||||
/* ### is this correct? Shouldn't be inheritable (at this point) */
|
/* ### is this correct? Shouldn't be inheritable (at this point) */
|
||||||
apr_os_sock_make(&context->sock, &sockinfo, context->ptrans);
|
apr_os_sock_make(&context->sock, &sockinfo, context->ptrans);
|
||||||
|
|
||||||
c = ap_new_connection(context->ptrans, ap_server_conf, context->sock,
|
c = ap_run_create_connection(context->ptrans, context->sock,
|
||||||
thread_num);
|
thread_num);
|
||||||
|
|
||||||
if (c) {
|
if (c) {
|
||||||
|
|||||||
@@ -499,7 +499,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num,
|
|||||||
|
|
||||||
ap_sock_disable_nagle(sock);
|
ap_sock_disable_nagle(sock);
|
||||||
|
|
||||||
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
|
current_conn = ap_run_create_connection(p, sock, conn_id);
|
||||||
if (current_conn) {
|
if (current_conn) {
|
||||||
ap_process_connection(current_conn);
|
ap_process_connection(current_conn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -545,7 +545,7 @@ request_rec *ap_read_request(conn_rec *conn)
|
|||||||
request_rec *r;
|
request_rec *r;
|
||||||
apr_pool_t *p;
|
apr_pool_t *p;
|
||||||
const char *expect;
|
const char *expect;
|
||||||
int access_status, keptalive;
|
int access_status;
|
||||||
|
|
||||||
apr_pool_create(&p, conn->pool);
|
apr_pool_create(&p, conn->pool);
|
||||||
r = apr_pcalloc(p, sizeof(request_rec));
|
r = apr_pcalloc(p, sizeof(request_rec));
|
||||||
@@ -553,7 +553,6 @@ request_rec *ap_read_request(conn_rec *conn)
|
|||||||
r->connection = conn;
|
r->connection = conn;
|
||||||
r->server = conn->base_server;
|
r->server = conn->base_server;
|
||||||
|
|
||||||
keptalive = conn->keepalive == 1;
|
|
||||||
conn->keepalive = 0;
|
conn->keepalive = 0;
|
||||||
|
|
||||||
r->user = NULL;
|
r->user = NULL;
|
||||||
@@ -582,11 +581,6 @@ request_rec *ap_read_request(conn_rec *conn)
|
|||||||
r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
|
r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
|
||||||
r->the_request = NULL;
|
r->the_request = NULL;
|
||||||
|
|
||||||
apr_setsocketopt(conn->client_socket, APR_SO_TIMEOUT,
|
|
||||||
(int)(keptalive
|
|
||||||
? r->server->keep_alive_timeout * APR_USEC_PER_SEC
|
|
||||||
: r->server->timeout * APR_USEC_PER_SEC));
|
|
||||||
|
|
||||||
/* Get the request... */
|
/* Get the request... */
|
||||||
if (!read_request_line(r)) {
|
if (!read_request_line(r)) {
|
||||||
if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
|
if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
|
||||||
@@ -598,10 +592,7 @@ request_rec *ap_read_request(conn_rec *conn)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (keptalive) {
|
|
||||||
apr_setsocketopt(r->connection->client_socket, APR_SO_TIMEOUT,
|
|
||||||
(int)(r->server->timeout * APR_USEC_PER_SEC));
|
|
||||||
}
|
|
||||||
if (!r->assbackwards) {
|
if (!r->assbackwards) {
|
||||||
get_mime_headers(r);
|
get_mime_headers(r);
|
||||||
if (r->status != HTTP_REQUEST_TIME_OUT) {
|
if (r->status != HTTP_REQUEST_TIME_OUT) {
|
||||||
|
|||||||
@@ -173,7 +173,6 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
|
|||||||
const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
|
const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
|
||||||
int i;
|
int i;
|
||||||
apr_port_t rport;
|
apr_port_t rport;
|
||||||
apr_sockaddr_t *remotesa;
|
|
||||||
|
|
||||||
/* use a temporary apr_table_t which we'll overlap onto
|
/* use a temporary apr_table_t which we'll overlap onto
|
||||||
* r->subprocess_env later
|
* r->subprocess_env later
|
||||||
@@ -273,8 +272,7 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
|
|||||||
apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
|
apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
|
||||||
apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
|
apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
|
||||||
|
|
||||||
apr_socket_addr_get(&remotesa, APR_REMOTE, c->client_socket);
|
apr_sockaddr_port_get(&rport, c->remote_addr);
|
||||||
apr_sockaddr_port_get(&rport, remotesa);
|
|
||||||
apr_table_addn(e, "REMOTE_PORT", apr_psprintf(r->pool, "%d", rport));
|
apr_table_addn(e, "REMOTE_PORT", apr_psprintf(r->pool, "%d", rport));
|
||||||
|
|
||||||
if (r->user) {
|
if (r->user) {
|
||||||
|
|||||||
@@ -896,11 +896,10 @@ static void check_hostalias(request_rec *r)
|
|||||||
server_rec *s;
|
server_rec *s;
|
||||||
server_rec *last_s;
|
server_rec *last_s;
|
||||||
name_chain *src;
|
name_chain *src;
|
||||||
apr_sockaddr_t *localsa;
|
|
||||||
|
|
||||||
last_s = NULL;
|
last_s = NULL;
|
||||||
apr_socket_addr_get(&localsa, APR_LOCAL, r->connection->client_socket);
|
|
||||||
apr_sockaddr_port_get(&port, localsa);
|
apr_sockaddr_port_get(&port, r->connection->local_addr);
|
||||||
|
|
||||||
/* Recall that the name_chain is a list of server_addr_recs, some of
|
/* Recall that the name_chain is a list of server_addr_recs, some of
|
||||||
* whose ports may not match. Also each server may appear more than
|
* whose ports may not match. Also each server may appear more than
|
||||||
@@ -955,11 +954,9 @@ static void check_serverpath(request_rec *r)
|
|||||||
server_rec *last_s;
|
server_rec *last_s;
|
||||||
name_chain *src;
|
name_chain *src;
|
||||||
apr_port_t port;
|
apr_port_t port;
|
||||||
apr_sockaddr_t *localsa;
|
|
||||||
|
|
||||||
apr_socket_addr_get(&localsa, APR_LOCAL, r->connection->client_socket);
|
apr_sockaddr_port_get(&port, r->connection->local_addr);
|
||||||
apr_sockaddr_port_get(&port, localsa);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is in conjunction with the ServerPath code in http_core, so we
|
* This is in conjunction with the ServerPath code in http_core, so we
|
||||||
* get the right host attached to a non- Host-sending request.
|
* get the right host attached to a non- Host-sending request.
|
||||||
@@ -1022,6 +1019,7 @@ void ap_update_vhost_given_ip(conn_rec *conn)
|
|||||||
|
|
||||||
/* scan the hash apr_table_t for an exact match first */
|
/* scan the hash apr_table_t for an exact match first */
|
||||||
trav = find_ipaddr(conn->local_addr);
|
trav = find_ipaddr(conn->local_addr);
|
||||||
|
|
||||||
if (trav) {
|
if (trav) {
|
||||||
/* save the name_chain for later in case this is a name-vhost */
|
/* save the name_chain for later in case this is a name-vhost */
|
||||||
conn->vhost_lookup_data = trav->names;
|
conn->vhost_lookup_data = trav->names;
|
||||||
@@ -1033,6 +1031,7 @@ void ap_update_vhost_given_ip(conn_rec *conn)
|
|||||||
* matching this port
|
* matching this port
|
||||||
*/
|
*/
|
||||||
apr_sockaddr_port_get(&port, conn->local_addr);
|
apr_sockaddr_port_get(&port, conn->local_addr);
|
||||||
|
|
||||||
trav = find_default_server(port);
|
trav = find_default_server(port);
|
||||||
if (trav) {
|
if (trav) {
|
||||||
conn->vhost_lookup_data = trav->names;
|
conn->vhost_lookup_data = trav->names;
|
||||||
|
|||||||
Reference in New Issue
Block a user