1
0
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:
Stefan Eissing
2015-08-18 14:33:55 +00:00
parent 2db3ea7e7f
commit e005a156f4
16 changed files with 80 additions and 119 deletions

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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. */

View File

@@ -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);

View File

@@ -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",

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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

View File

@@ -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++) {