mirror of
https://github.com/apache/httpd.git
synced 2025-08-07 04:02:58 +03:00
creating ap_array_index in util, forwarding scheme into request processing, enabling SSL vars only when scheme is not http:, delayed connection creation until task worker assignment
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1696428 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -2408,7 +2408,7 @@ AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p,
|
||||
* @param s the string to find
|
||||
* @return index of string in array or -1
|
||||
*/
|
||||
AP_DECLARE(int) ap_array_index(apr_array_header_t *array, const char *s);
|
||||
AP_DECLARE(int) ap_array_index(const apr_array_header_t *array, const char *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -351,27 +351,21 @@ conn_rec *h2_conn_create(conn_rec *master, apr_pool_t *pool)
|
||||
*/
|
||||
socket = ap_get_module_config(master->conn_config, &core_module);
|
||||
c = ap_run_create_connection(pool, master->base_server,
|
||||
socket,
|
||||
master->id^((long)pool),
|
||||
master->sbh,
|
||||
master->bucket_alloc);
|
||||
socket,
|
||||
master->id^((long)pool),
|
||||
master->sbh,
|
||||
master->bucket_alloc);
|
||||
if (c == NULL) {
|
||||
ap_log_perror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, pool,
|
||||
APLOGNO(02913) "h2_task: creating conn");
|
||||
return NULL;
|
||||
}
|
||||
/* TODO: we simulate that we had already a request on this connection.
|
||||
* This keeps the mod_ssl SNI vs. Host name matcher from answering
|
||||
* 400 Bad Request
|
||||
* when names do not match. We prefer a predictable 421 status.
|
||||
*/
|
||||
c->keepalives = 1;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
apr_status_t h2_conn_prep(h2_task_env *env, conn_rec *master, h2_worker *worker)
|
||||
apr_status_t h2_conn_setup(h2_task_env *env, struct h2_worker *worker)
|
||||
{
|
||||
conn_rec *master = env->mplx->c;
|
||||
h2_config *cfg = h2_config_get(master);
|
||||
|
||||
ap_log_perror(APLOG_MARK, APLOG_TRACE3, 0, env->pool,
|
||||
@@ -393,7 +387,10 @@ apr_status_t h2_conn_prep(h2_task_env *env, conn_rec *master, h2_worker *worker)
|
||||
ap_set_module_config(env->c.conn_config, &core_module,
|
||||
h2_worker_get_socket(worker));
|
||||
|
||||
if (ssl_module) {
|
||||
/* If we serve http:// requests over a TLS connection, we do
|
||||
* not want any mod_ssl vars to be visible.
|
||||
*/
|
||||
if (ssl_module && (!env->scheme || strcmp("http", env->scheme))) {
|
||||
/* See #19, there is a range of SSL variables to be gotten from
|
||||
* the main connection that should be available in request handlers
|
||||
*/
|
||||
@@ -419,62 +416,12 @@ apr_status_t h2_conn_prep(h2_task_env *env, conn_rec *master, h2_worker *worker)
|
||||
break;
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
apr_status_t h2_conn_setup(struct h2_task_env *env, struct h2_worker *worker)
|
||||
{
|
||||
return h2_conn_prep(env, env->mplx->c, worker);
|
||||
}
|
||||
|
||||
apr_status_t h2_conn_init(struct h2_task_env *env, struct h2_worker *worker)
|
||||
{
|
||||
conn_rec *master = env->mplx->c;
|
||||
h2_config *cfg = h2_config_get(master);
|
||||
|
||||
apr_socket_t *socket = ap_get_module_config(master->conn_config,
|
||||
&core_module);
|
||||
conn_rec *c = ap_run_create_connection(env->pool, master->base_server,
|
||||
socket,
|
||||
master->id^((long)env->pool),
|
||||
master->sbh,
|
||||
master->bucket_alloc);
|
||||
if (c == NULL) {
|
||||
ap_log_perror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, env->pool,
|
||||
APLOGNO(02914) "h2_task: creating conn");
|
||||
return APR_ENOMEM;
|
||||
}
|
||||
|
||||
env->c = *c;
|
||||
env->c.bucket_alloc = h2_worker_get_bucket_alloc(worker);
|
||||
env->c.current_thread = h2_worker_get_thread(worker);
|
||||
|
||||
ap_set_module_config(env->c.conn_config, &core_module, socket);
|
||||
if (ssl_module) {
|
||||
/* See #19, there is a range of SSL variables to be gotten from
|
||||
* the main connection that should be available in request handlers
|
||||
*/
|
||||
void *sslcfg = ap_get_module_config(master->conn_config, ssl_module);
|
||||
if (sslcfg) {
|
||||
ap_set_module_config(env->c.conn_config, ssl_module, sslcfg);
|
||||
}
|
||||
}
|
||||
|
||||
/* This works for mpm_worker so far. Other mpm modules have
|
||||
* different needs, unfortunately. The most interesting one
|
||||
* being mpm_event...
|
||||
/* TODO: we simulate that we had already a request on this connection.
|
||||
* This keeps the mod_ssl SNI vs. Host name matcher from answering
|
||||
* 400 Bad Request
|
||||
* when names do not match. We prefer a predictable 421 status.
|
||||
*/
|
||||
switch (h2_conn_mpm_type()) {
|
||||
case H2_MPM_WORKER:
|
||||
/* all fine */
|
||||
break;
|
||||
case H2_MPM_EVENT:
|
||||
fix_event_conn(&env->c, master);
|
||||
break;
|
||||
default:
|
||||
/* fingers crossed */
|
||||
break;
|
||||
}
|
||||
env->c.keepalives = 1;
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
@@ -46,23 +46,13 @@ typedef enum {
|
||||
H2_MPM_PREFORK,
|
||||
} h2_mpm_type_t;
|
||||
|
||||
h2_mpm_type_t h2_conn_mpm_type();
|
||||
module *h2_conn_mpm_module();
|
||||
|
||||
/* Returns the type of MPM module detected */
|
||||
h2_mpm_type_t h2_conn_mpm_type(void);
|
||||
|
||||
/* Gives the detected module itself or NULL if unknown */
|
||||
module *h2_conn_mpm_module(void);
|
||||
|
||||
|
||||
conn_rec *h2_conn_create(conn_rec *master, apr_pool_t *stream_pool);
|
||||
|
||||
apr_status_t h2_conn_init(struct h2_task_env *env, struct h2_worker *worker);
|
||||
|
||||
apr_status_t h2_conn_setup(struct h2_task_env *env, struct h2_worker *worker);
|
||||
apr_status_t h2_conn_prep(struct h2_task_env *env, conn_rec *master,
|
||||
struct h2_worker *worker);
|
||||
apr_status_t h2_conn_post(conn_rec *c, struct h2_worker *worker);
|
||||
|
||||
apr_status_t h2_conn_process(conn_rec *c, apr_socket_t *socket);
|
||||
|
@@ -30,6 +30,7 @@ h2_io *h2_io_create(int id, apr_pool_t *pool, apr_bucket_alloc_t *bucket_alloc)
|
||||
h2_io *io = apr_pcalloc(pool, sizeof(*io));
|
||||
if (io) {
|
||||
io->id = id;
|
||||
io->pool = pool;
|
||||
io->bbin = NULL;
|
||||
io->bbout = apr_brigade_create(pool, bucket_alloc);
|
||||
io->response = apr_pcalloc(pool, sizeof(h2_response));
|
||||
|
@@ -29,6 +29,7 @@ typedef struct h2_io h2_io;
|
||||
|
||||
struct h2_io {
|
||||
int id; /* stream identifier */
|
||||
apr_pool_t *pool; /* stream pool */
|
||||
apr_bucket_brigade *bbin; /* input data for stream */
|
||||
int eos_in;
|
||||
int task_done;
|
||||
|
@@ -67,8 +67,11 @@ h2_io *h2_io_set_get(h2_io_set *sp, int stream_id)
|
||||
/* we keep the array sorted by id, so lookup can be done
|
||||
* by bsearch.
|
||||
*/
|
||||
h2_io key = { stream_id, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, 0 };
|
||||
h2_io key;
|
||||
h2_io *pkey = &key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.id = stream_id;
|
||||
h2_io **ps = bsearch(&pkey, sp->list->elts, sp->list->nelts,
|
||||
sp->list->elt_size, h2_stream_id_cmp);
|
||||
return ps? *ps : NULL;
|
||||
|
@@ -765,6 +765,10 @@ h2_task *h2_mplx_pop_task(h2_mplx *m, int *has_more)
|
||||
if (APR_SUCCESS == status) {
|
||||
task = h2_tq_pop_first(m->q);
|
||||
if (task) {
|
||||
h2_io *io = h2_io_set_get(m->stream_ios, task->stream_id);
|
||||
if (io) {
|
||||
task->c = h2_conn_create(m->c, io->pool);
|
||||
}
|
||||
h2_task_set_started(task);
|
||||
}
|
||||
*has_more = !h2_tq_empty(m->q);
|
||||
@@ -782,16 +786,8 @@ apr_status_t h2_mplx_create_task(h2_mplx *m, struct h2_stream *stream)
|
||||
}
|
||||
status = apr_thread_mutex_lock(m->lock);
|
||||
if (APR_SUCCESS == status) {
|
||||
|
||||
conn_rec *c = h2_conn_create(m->c, stream->pool);
|
||||
if (c == NULL) {
|
||||
ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, m->c,
|
||||
APLOGNO(02916) "h2_mplx(%ld-%d): start stream",
|
||||
m->id, stream->id);
|
||||
return APR_ENOMEM;
|
||||
}
|
||||
stream->task = h2_task_create(m->id, stream->id,
|
||||
stream->pool, m, c);
|
||||
stream->pool, m, NULL);
|
||||
|
||||
apr_thread_mutex_unlock(m->lock);
|
||||
}
|
||||
|
@@ -56,8 +56,8 @@ apr_status_t h2_request_rwrite(h2_request *req, request_rec *r, h2_mplx *m)
|
||||
{
|
||||
apr_status_t status;
|
||||
req->method = r->method;
|
||||
req->path = r->uri;
|
||||
req->authority = r->hostname;
|
||||
req->path = r->uri;
|
||||
if (!strchr(req->authority, ':') && r->parsed_uri.port_str) {
|
||||
req->authority = apr_psprintf(req->pool, "%s:%s", req->authority,
|
||||
r->parsed_uri.port_str);
|
||||
@@ -168,7 +168,10 @@ apr_status_t h2_request_close(h2_request *req)
|
||||
static apr_status_t insert_request_line(h2_request *req, h2_mplx *m)
|
||||
{
|
||||
req->to_h1 = h2_to_h1_create(req->id, req->pool, req->bucket_alloc,
|
||||
req->method, req->path, req->authority, m);
|
||||
req->method,
|
||||
req->scheme,
|
||||
req->authority,
|
||||
req->path, m);
|
||||
return req->to_h1? APR_SUCCESS : APR_ENOMEM;
|
||||
}
|
||||
|
||||
|
@@ -37,9 +37,9 @@ struct h2_request {
|
||||
|
||||
/* pseudo header values, see ch. 8.1.2.3 */
|
||||
const char *method;
|
||||
const char *path;
|
||||
const char *authority;
|
||||
const char *scheme;
|
||||
const char *authority;
|
||||
const char *path;
|
||||
};
|
||||
|
||||
h2_request *h2_request_create(int id, apr_pool_t *pool,
|
||||
|
@@ -182,12 +182,16 @@ h2_task *h2_task_create(long session_id,
|
||||
}
|
||||
|
||||
void h2_task_set_request(h2_task *task,
|
||||
const char *method, const char *path,
|
||||
const char *authority, apr_table_t *headers, int eos)
|
||||
const char *method,
|
||||
const char *scheme,
|
||||
const char *authority,
|
||||
const char *path,
|
||||
apr_table_t *headers, int eos)
|
||||
{
|
||||
task->method = method;
|
||||
task->path = path;
|
||||
task->scheme = scheme;
|
||||
task->authority = authority;
|
||||
task->path = path;
|
||||
task->headers = headers;
|
||||
task->input_eos = eos;
|
||||
}
|
||||
@@ -227,19 +231,15 @@ apr_status_t h2_task_do(h2_task *task, h2_worker *worker)
|
||||
|
||||
/* Clone fields, so that lifetimes become (more) independent. */
|
||||
env.method = apr_pstrdup(env.pool, task->method);
|
||||
env.path = apr_pstrdup(env.pool, task->path);
|
||||
env.scheme = apr_pstrdup(env.pool, task->scheme);
|
||||
env.authority = apr_pstrdup(env.pool, task->authority);
|
||||
env.path = apr_pstrdup(env.pool, task->path);
|
||||
env.headers = apr_table_clone(env.pool, task->headers);
|
||||
|
||||
/* Setup the pseudo connection to use our own pool and bucket_alloc */
|
||||
if (task->c) {
|
||||
env.c = *task->c;
|
||||
task->c = NULL;
|
||||
status = h2_conn_setup(&env, worker);
|
||||
}
|
||||
else {
|
||||
status = h2_conn_init(&env, worker);
|
||||
}
|
||||
env.c = *task->c;
|
||||
task->c = NULL;
|
||||
status = h2_conn_setup(&env, worker);
|
||||
|
||||
/* save in connection that this one is a pseudo connection, prevents
|
||||
* other hooks from messing with it. */
|
||||
|
@@ -56,8 +56,9 @@ struct h2_task {
|
||||
volatile apr_uint32_t has_finished;
|
||||
|
||||
const char *method;
|
||||
const char *path;
|
||||
const char *scheme;
|
||||
const char *authority;
|
||||
const char *path;
|
||||
apr_table_t *headers;
|
||||
int input_eos;
|
||||
|
||||
@@ -75,8 +76,9 @@ struct h2_task_env {
|
||||
apr_bucket_alloc_t *bucket_alloc;
|
||||
|
||||
const char *method;
|
||||
const char *path;
|
||||
const char *scheme;
|
||||
const char *authority;
|
||||
const char *path;
|
||||
apr_table_t *headers;
|
||||
int input_eos;
|
||||
|
||||
@@ -163,8 +165,12 @@ h2_task *h2_task_create(long session_id, int stream_id,
|
||||
|
||||
apr_status_t h2_task_destroy(h2_task *task);
|
||||
|
||||
void h2_task_set_request(h2_task *task, const char *method, const char *path,
|
||||
const char *authority, apr_table_t *headers, int eos);
|
||||
void h2_task_set_request(h2_task *task,
|
||||
const char *method,
|
||||
const char *scheme,
|
||||
const char *authority,
|
||||
const char *path,
|
||||
apr_table_t *headers, int eos);
|
||||
|
||||
|
||||
apr_status_t h2_task_do(h2_task *task, struct h2_worker *worker);
|
||||
|
@@ -74,6 +74,9 @@ h2_task_input *h2_task_input_create(h2_task_env *env, apr_pool_t *pool,
|
||||
if (input->bb) {
|
||||
apr_brigade_flatten(input->bb, buffer, &len);
|
||||
}
|
||||
else {
|
||||
len = 0;
|
||||
}
|
||||
buffer[len] = 0;
|
||||
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, &env->c,
|
||||
"h2_task_input(%s): request is: %s",
|
||||
|
@@ -33,8 +33,11 @@
|
||||
|
||||
h2_to_h1 *h2_to_h1_create(int stream_id, apr_pool_t *pool,
|
||||
apr_bucket_alloc_t *bucket_alloc,
|
||||
const char *method, const char *path,
|
||||
const char *authority, struct h2_mplx *m)
|
||||
const char *method,
|
||||
const char *scheme,
|
||||
const char *authority,
|
||||
const char *path,
|
||||
struct h2_mplx *m)
|
||||
{
|
||||
h2_to_h1 *to_h1;
|
||||
if (!method) {
|
||||
@@ -55,8 +58,9 @@ h2_to_h1 *h2_to_h1_create(int stream_id, apr_pool_t *pool,
|
||||
to_h1->stream_id = stream_id;
|
||||
to_h1->pool = pool;
|
||||
to_h1->method = method;
|
||||
to_h1->path = path;
|
||||
to_h1->scheme = scheme;
|
||||
to_h1->authority = authority;
|
||||
to_h1->path = path;
|
||||
to_h1->m = m;
|
||||
to_h1->headers = apr_table_make(to_h1->pool, 10);
|
||||
to_h1->bb = apr_brigade_create(pool, bucket_alloc);
|
||||
@@ -183,8 +187,11 @@ apr_status_t h2_to_h1_end_headers(h2_to_h1 *to_h1, h2_task *task, int eos)
|
||||
apr_table_mergen(to_h1->headers, "Transfer-Encoding", "chunked");
|
||||
}
|
||||
|
||||
h2_task_set_request(task, to_h1->method, to_h1->path,
|
||||
to_h1->authority, to_h1->headers, eos);
|
||||
h2_task_set_request(task, to_h1->method,
|
||||
to_h1->scheme,
|
||||
to_h1->authority,
|
||||
to_h1->path,
|
||||
to_h1->headers, eos);
|
||||
to_h1->eoh = 1;
|
||||
|
||||
if (eos) {
|
||||
|
@@ -26,8 +26,9 @@ struct h2_to_h1 {
|
||||
h2_mplx *m;
|
||||
|
||||
const char *method;
|
||||
const char *path;
|
||||
const char *scheme;
|
||||
const char *authority;
|
||||
const char *path;
|
||||
|
||||
int chunked;
|
||||
int eoh;
|
||||
@@ -47,8 +48,11 @@ struct h2_to_h1 {
|
||||
*/
|
||||
h2_to_h1 *h2_to_h1_create(int stream_id, apr_pool_t *pool,
|
||||
apr_bucket_alloc_t *bucket_alloc,
|
||||
const char *method, const char *path,
|
||||
const char *authority, struct h2_mplx *m);
|
||||
const char *method,
|
||||
const char *scheme,
|
||||
const char *authority,
|
||||
const char *path,
|
||||
struct h2_mplx *m);
|
||||
|
||||
/* Destroy the converter and free resources. */
|
||||
void h2_to_h1_destroy(h2_to_h1 *to_h1);
|
||||
|
@@ -20,7 +20,7 @@
|
||||
* @macro
|
||||
* Version number of the h2 module as c string
|
||||
*/
|
||||
#define MOD_H2_VERSION "1.0.0"
|
||||
#define MOD_H2_VERSION "0.9.1"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
|
@@ -3149,7 +3149,7 @@ AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p,
|
||||
return apr_pstrndup(p, buf, k);
|
||||
}
|
||||
|
||||
AP_DECLARE(int) ap_array_index(apr_array_header_t *array, const char *s)
|
||||
AP_DECLARE(int) ap_array_index(const apr_array_header_t *array, const char *s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < array->nelts; i++) {
|
||||
|
Reference in New Issue
Block a user