diff --git a/include/httpd.h b/include/httpd.h index d68db185c4..54b356cfa0 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -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 } diff --git a/modules/http2/h2_conn.c b/modules/http2/h2_conn.c index a37276238e..1d4d704ecc 100644 --- a/modules/http2/h2_conn.c +++ b/modules/http2/h2_conn.c @@ -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; } diff --git a/modules/http2/h2_conn.h b/modules/http2/h2_conn.h index 795e1d6a97..49a70db850 100644 --- a/modules/http2/h2_conn.h +++ b/modules/http2/h2_conn.h @@ -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); diff --git a/modules/http2/h2_io.c b/modules/http2/h2_io.c index c4039194eb..9ce2e954d0 100644 --- a/modules/http2/h2_io.c +++ b/modules/http2/h2_io.c @@ -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)); diff --git a/modules/http2/h2_io.h b/modules/http2/h2_io.h index 46606ea5e0..946ee44334 100644 --- a/modules/http2/h2_io.h +++ b/modules/http2/h2_io.h @@ -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; diff --git a/modules/http2/h2_io_set.c b/modules/http2/h2_io_set.c index 049e6d7894..6a688b9a58 100644 --- a/modules/http2/h2_io_set.c +++ b/modules/http2/h2_io_set.c @@ -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; diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c index 673b46248f..a9727b0508 100644 --- a/modules/http2/h2_mplx.c +++ b/modules/http2/h2_mplx.c @@ -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); } diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c index 1405c5bc43..5653a40233 100644 --- a/modules/http2/h2_request.c +++ b/modules/http2/h2_request.c @@ -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; } diff --git a/modules/http2/h2_request.h b/modules/http2/h2_request.h index dac8c6fdaa..aa5e0bc3c0 100644 --- a/modules/http2/h2_request.h +++ b/modules/http2/h2_request.h @@ -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, diff --git a/modules/http2/h2_task.c b/modules/http2/h2_task.c index 71b212eaac..e28dd25a33 100644 --- a/modules/http2/h2_task.c +++ b/modules/http2/h2_task.c @@ -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. */ diff --git a/modules/http2/h2_task.h b/modules/http2/h2_task.h index 4130a02377..b66ce38c25 100644 --- a/modules/http2/h2_task.h +++ b/modules/http2/h2_task.h @@ -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); diff --git a/modules/http2/h2_task_input.c b/modules/http2/h2_task_input.c index 0070c1eea1..cc7d8503fd 100644 --- a/modules/http2/h2_task_input.c +++ b/modules/http2/h2_task_input.c @@ -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", diff --git a/modules/http2/h2_to_h1.c b/modules/http2/h2_to_h1.c index 3ddf455c42..bb913d5bb2 100644 --- a/modules/http2/h2_to_h1.c +++ b/modules/http2/h2_to_h1.c @@ -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) { diff --git a/modules/http2/h2_to_h1.h b/modules/http2/h2_to_h1.h index 275448f61f..74586e2b7e 100644 --- a/modules/http2/h2_to_h1.h +++ b/modules/http2/h2_to_h1.h @@ -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); diff --git a/modules/http2/h2_version.h b/modules/http2/h2_version.h index c36efa16a6..ec761f895e 100644 --- a/modules/http2/h2_version.h +++ b/modules/http2/h2_version.h @@ -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 diff --git a/server/util.c b/server/util.c index 6f764e6a67..c77635fe0e 100644 --- a/server/util.c +++ b/server/util.c @@ -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++) {