Skip to content

Commit

Permalink
copy of v1.5.5 from apache httpd svn
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan Eissing committed May 18, 2016
1 parent f9b2970 commit 5742353
Show file tree
Hide file tree
Showing 20 changed files with 236 additions and 92 deletions.
11 changes: 11 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
v1.5.5
--------------------------------------------------------------------------------
* Fix async write issue that sometimes led to selection of wrong timeout
vs. keepalive timeout selection for idle sessions.
* Checking LimitRequestLine, LimitRequestFields and
LimitRequestFieldSize configurated values for incoming streams. Returning
HTTP status 431 for too long/many headers fields and 414 for a too long
pseudo header.
* Tracking conn_rec->current_thread on slave connections, so
that mod_lua finds the correct one. Fixes PR 59542.

v1.5.3
--------------------------------------------------------------------------------
* slave connections have conn_rec->aborted flag set when a stream
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#

AC_PREREQ([2.69])
AC_INIT([mod_http2], [1.5.3], [[email protected]])
AC_INIT([mod_http2], [1.5.5], [[email protected]])

LT_PREREQ([2.2.6])
LT_INIT()
Expand Down
21 changes: 13 additions & 8 deletions mod_http2/h2_from_h1.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ static void fix_vary(request_rec *r)
}
}

static void set_basic_http_header(request_rec *r, apr_table_t *headers)
void h2_from_h1_set_basic_http_header(apr_table_t *headers, request_rec *r,
apr_pool_t *pool)
{
char *date = NULL;
const char *proxy_date = NULL;
Expand All @@ -302,33 +303,37 @@ static void set_basic_http_header(request_rec *r, apr_table_t *headers)
* keep the set-by-proxy server and date headers, otherwise
* generate a new server header / date header
*/
if (r->proxyreq != PROXYREQ_NONE) {
if (r && r->proxyreq != PROXYREQ_NONE) {
proxy_date = apr_table_get(r->headers_out, "Date");
if (!proxy_date) {
/*
* proxy_date needs to be const. So use date for the creation of
* our own Date header and pass it over to proxy_date later to
* avoid a compiler warning.
*/
date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
date = apr_palloc(pool, APR_RFC822_DATE_LEN);
ap_recent_rfc822_date(date, r->request_time);
}
server = apr_table_get(r->headers_out, "Server");
}
else {
date = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
ap_recent_rfc822_date(date, r->request_time);
date = apr_palloc(pool, APR_RFC822_DATE_LEN);
ap_recent_rfc822_date(date, r? r->request_time : apr_time_now());
}

apr_table_setn(headers, "Date", proxy_date ? proxy_date : date );
apr_table_unset(r->headers_out, "Date");
if (r) {
apr_table_unset(r->headers_out, "Date");
}

if (!server && *us) {
server = us;
}
if (server) {
apr_table_setn(headers, "Server", server);
apr_table_unset(r->headers_out, "Server");
if (r) {
apr_table_unset(r->headers_out, "Server");
}
}
}

Expand Down Expand Up @@ -445,7 +450,7 @@ static h2_response *create_response(h2_from_h1 *from_h1, request_rec *r)

headers = apr_table_make(r->pool, 10);

set_basic_http_header(r, headers);
h2_from_h1_set_basic_http_header(headers, r, r->pool);
if (r->status == HTTP_NOT_MODIFIED) {
apr_table_do((int (*)(void *, const char *, const char *)) copy_header,
(void *) headers, r->headers_out,
Expand Down
3 changes: 3 additions & 0 deletions mod_http2/h2_from_h1.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,7 @@ apr_status_t h2_response_output_filter(ap_filter_t *f, apr_bucket_brigade *bb);

apr_status_t h2_response_trailers_filter(ap_filter_t *f, apr_bucket_brigade *bb);

void h2_from_h1_set_basic_http_header(apr_table_t *headers, request_rec *r,
apr_pool_t *pool);

#endif /* defined(__mod_h2__h2_from_h1__) */
6 changes: 3 additions & 3 deletions mod_http2/h2_h2.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,9 +485,9 @@ int h2_is_acceptable_connection(conn_rec *c, int require_all)
if (strncmp("TLS", val, 3)
|| !strcmp("TLSv1", val)
|| !strcmp("TLSv1.1", val)) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03050)
"h2_h2(%ld): tls protocol not suitable: %s",
(long)c->id, val);
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03050)
"h2_h2(%ld): tls protocol not suitable: %s",
(long)c->id, val);
return 0;
}
}
Expand Down
90 changes: 45 additions & 45 deletions mod_http2/h2_mplx.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,11 @@ h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *parent,
m->stream_max_mem = h2_config_geti(conf, H2_CONF_STREAM_MAX_MEM);

m->streams = h2_ihash_create(m->pool, offsetof(h2_stream,id));
m->sready = h2_ihash_create(m->pool, offsetof(h2_stream,id));
m->shold = h2_ihash_create(m->pool, offsetof(h2_stream,id));
m->spurge = h2_ihash_create(m->pool, offsetof(h2_stream,id));
m->q = h2_iq_create(m->pool, m->max_streams);
m->tasks = h2_ihash_create(m->pool, offsetof(h2_task,stream_id));
m->ready_tasks = h2_ihash_create(m->pool, offsetof(h2_task,stream_id));

m->stream_timeout = stream_timeout;
m->workers = workers;
Expand Down Expand Up @@ -373,7 +373,6 @@ static void task_destroy(h2_mplx *m, h2_task *task, int called_from_master)
&& !task->rst_error);

h2_ihash_remove(m->tasks, task->stream_id);
h2_ihash_remove(m->ready_tasks, task->stream_id);
if (m->redo_tasks) {
h2_ihash_remove(m->redo_tasks, task->stream_id);
}
Expand Down Expand Up @@ -428,7 +427,7 @@ static void stream_done(h2_mplx *m, h2_stream *stream, int rst_error)
* stream destruction until the task is done.
*/
h2_iq_remove(m->q, stream->id);
h2_ihash_remove(m->ready_tasks, stream->id);
h2_ihash_remove(m->sready, stream->id);
h2_ihash_remove(m->streams, stream->id);
if (stream->input) {
m->tx_handles_reserved += h2_beam_get_files_beamed(stream->input);
Expand Down Expand Up @@ -465,8 +464,10 @@ static int task_print(void *ctx, void *val)
{
h2_mplx *m = ctx;
h2_task *task = val;
h2_stream *stream = h2_ihash_get(m->streams, task->stream_id);
if (task->request) {

if (task && task->request) {
h2_stream *stream = h2_ihash_get(m->streams, task->stream_id);

ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, /* NO APLOGNO */
"->03198: h2_stream(%s): %s %s %s -> %s %d"
"[orph=%d/started=%d/done=%d]",
Expand All @@ -488,6 +489,15 @@ static int task_print(void *ctx, void *val)
return 1;
}

static int task_abort_connection(void *ctx, void *val)
{
h2_task *task = val;
if (task->c) {
task->c->aborted = 1;
}
return 1;
}

apr_status_t h2_mplx_release_and_join(h2_mplx *m, apr_thread_cond_t *wait)
{
apr_status_t status;
Expand Down Expand Up @@ -537,6 +547,8 @@ apr_status_t h2_mplx_release_and_join(h2_mplx *m, apr_thread_cond_t *wait)
* and workers *should* return in a timely fashion.
*/
for (i = 0; m->workers_busy > 0; ++i) {
h2_ihash_iter(m->tasks, task_abort_connection, m);

m->join_wait = wait;
status = apr_thread_cond_timedwait(wait, m->lock, apr_time_from_sec(wait_secs));

Expand Down Expand Up @@ -644,11 +656,10 @@ apr_status_t h2_mplx_in_update_windows(h2_mplx *m)
return status;
}

static int task_iter_first(void *ctx, void *val)
static int stream_iter_first(void *ctx, void *val)
{
task_iter_ctx *tctx = ctx;
h2_task *task = val;
tctx->task = task;
h2_stream **pstream = ctx;
*pstream = val;
return 0;
}

Expand All @@ -660,17 +671,11 @@ h2_stream *h2_mplx_next_submit(h2_mplx *m)

AP_DEBUG_ASSERT(m);
if ((status = enter_mutex(m, &acquired)) == APR_SUCCESS) {
task_iter_ctx ctx;
ctx.m = m;
ctx.task = NULL;
h2_ihash_iter(m->ready_tasks, task_iter_first, &ctx);

if (ctx.task && !m->aborted) {
h2_task *task = ctx.task;

h2_ihash_remove(m->ready_tasks, task->stream_id);
stream = h2_ihash_get(m->streams, task->stream_id);
if (stream && task) {
h2_ihash_iter(m->sready, stream_iter_first, &stream);
if (stream) {
h2_task *task = h2_ihash_get(m->tasks, stream->id);
h2_ihash_remove(m->sready, stream->id);
if (task) {
task->submitted = 1;
if (task->rst_error) {
h2_stream_rst(stream, task->rst_error);
Expand All @@ -681,24 +686,11 @@ h2_stream *h2_mplx_next_submit(h2_mplx *m)
task->output.beam);
}
}
else if (task) {
/* We have the io ready, but the stream has gone away, maybe
* reset by the client. Should no longer happen since such
* streams should clear io's from the ready queue.
*/
ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, APLOGNO(03347)
"h2_mplx(%s): stream for response closed, "
"resetting io to close request processing",
task->id);
h2_task_rst(task, H2_ERR_STREAM_CLOSED);
if (!task->worker_started || task->worker_done) {
task_destroy(m, task, 1);
}
else {
/* hang around until the h2_task is done, but
* shutdown output */
h2_task_shutdown(task, 0);
}
else {
/* We have the stream ready without a task. This happens
* when we fail streams early. A response should already
* be present. */
AP_DEBUG_ASSERT(stream->response || stream->rst_error);
}
}
leave_mutex(m, acquired);
Expand Down Expand Up @@ -731,7 +723,7 @@ static apr_status_t out_open(h2_mplx *m, int stream_id, h2_response *response)
h2_beam_mutex_set(task->output.beam, beam_enter, task->cond, m);
}

h2_ihash_add(m->ready_tasks, task);
h2_ihash_add(m->sready, stream);
if (response && response->http_status < 300) {
/* we might see some file buckets in the output, see
* if we have enough handles reserved. */
Expand Down Expand Up @@ -762,18 +754,22 @@ apr_status_t h2_mplx_out_open(h2_mplx *m, int stream_id, h2_response *response)
static apr_status_t out_close(h2_mplx *m, h2_task *task)
{
apr_status_t status = APR_SUCCESS;
h2_stream *stream = h2_ihash_get(m->streams, task->stream_id);
h2_stream *stream;

if (!task || !stream) {
if (!task) {
return APR_ECONNABORTED;
}


stream = h2_ihash_get(m->streams, task->stream_id);
if (!stream) {
return APR_ECONNABORTED;
}

if (!task->response && !task->rst_error) {
/* In case a close comes before a response was created,
* insert an error one so that our streams can properly
* reset.
* insert an error one so that our streams can properly reset.
*/
h2_response *r = h2_response_die(task->stream_id, APR_EGENERAL,
h2_response *r = h2_response_die(task->stream_id, 500,
task->request, m->pool);
status = out_open(m, task->stream_id, r);
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, m->c,
Expand Down Expand Up @@ -858,6 +854,10 @@ apr_status_t h2_mplx_process(h2_mplx *m, struct h2_stream *stream,
if (m->aborted) {
status = APR_ECONNABORTED;
}
else if (stream->response) {
/* already have a respone, schedule for submit */
h2_ihash_add(m->sready, stream);
}
else {
h2_beam_create(&stream->input, stream->pool, stream->id,
"input", 0);
Expand Down
2 changes: 1 addition & 1 deletion mod_http2/h2_mplx.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ struct h2_mplx {
unsigned int need_registration : 1;

struct h2_ihash_t *streams; /* all streams currently processing */
struct h2_ihash_t *sready; /* all streams ready for response */
struct h2_ihash_t *shold; /* all streams done with task ongoing */
struct h2_ihash_t *spurge; /* all streams done, ready for destroy */
struct h2_iqueue *q; /* all stream ids that need to be started */

struct h2_ihash_t *tasks; /* all tasks started and not destroyed */
struct h2_ihash_t *ready_tasks; /* all tasks ready for submit */
struct h2_ihash_t *redo_tasks; /* all tasks that need to be redone */

apr_uint32_t max_streams; /* max # of concurrent streams */
Expand Down
6 changes: 6 additions & 0 deletions mod_http2/h2_ngn_shed.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ apr_status_t h2_ngn_shed_pull_task(h2_ngn_shed *shed,
ngn->no_live++;
*ptask = entry->task;
entry->task->assigned = ngn;
/* task will now run in ngn's own thread. Modules like lua
* seem to require the correct thread set in the conn_rec.
* See PR 59542. */
if (entry->task->c && ngn->c) {
entry->task->c->current_thread = ngn->c->current_thread;
}
return APR_SUCCESS;
}

Expand Down
22 changes: 13 additions & 9 deletions mod_http2/h2_proxy_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 +336,10 @@ static int on_data_chunk_recv(nghttp2_session *ngh2, uint8_t flags,

stream = nghttp2_session_get_stream_user_data(ngh2, stream_id);
if (!stream) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, stream->r, APLOGNO(03358)
"h2_proxy_session(%s): recv data chunk for "
"unknown stream %d, ignored",
session->id, stream_id);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03358)
"h2_proxy_session(%s): recv data chunk for "
"unknown stream %d, ignored",
session->id, stream_id);
return 0;
}

Expand Down Expand Up @@ -422,9 +422,9 @@ static ssize_t stream_data_read(nghttp2_session *ngh2, int32_t stream_id,
*data_flags = 0;
stream = nghttp2_session_get_stream_user_data(ngh2, stream_id);
if (!stream) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, stream->r, APLOGNO(03361)
"h2_proxy_stream(%s): data_read, stream %d not found",
stream->session->id, stream_id);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03361)
"h2_proxy_stream(%s): data_read, stream %d not found",
stream->session->id, stream_id);
return NGHTTP2_ERR_CALLBACK_FAILURE;
}

Expand Down Expand Up @@ -581,6 +581,7 @@ static apr_status_t open_stream(h2_proxy_session *session, const char *url,
h2_proxy_stream *stream;
apr_uri_t puri;
const char *authority, *scheme, *path;
apr_status_t status;

stream = apr_pcalloc(r->pool, sizeof(*stream));

Expand All @@ -595,7 +596,10 @@ static apr_status_t open_stream(h2_proxy_session *session, const char *url,

stream->req = h2_req_create(1, stream->pool, 0);

apr_uri_parse(stream->pool, url, &puri);
status = apr_uri_parse(stream->pool, url, &puri);
if (status != APR_SUCCESS)
return status;

scheme = (strcmp(puri.scheme, "h2")? "http" : "https");
authority = puri.hostname;
if (!ap_strchr_c(authority, ':') && puri.port
Expand Down Expand Up @@ -763,7 +767,7 @@ apr_status_t h2_proxy_session_submit(h2_proxy_session *session,
apr_status_t status;

status = open_stream(session, url, r, &stream);
if (status == OK) {
if (status == APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03381)
"process stream(%d): %s %s%s, original: %s",
stream->id, stream->req->method,
Expand Down
3 changes: 2 additions & 1 deletion mod_http2/h2_response.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,14 @@ h2_response *h2_response_die(int stream_id, apr_status_t type,
{
apr_table_t *headers = apr_table_make(pool, 5);
char *date = NULL;
int status = (type >= 200 && type < 600)? type : 500;

date = apr_palloc(pool, APR_RFC822_DATE_LEN);
ap_recent_rfc822_date(date, req->request_time);
apr_table_setn(headers, "Date", date);
apr_table_setn(headers, "Server", ap_get_server_banner());

return h2_response_create_int(stream_id, 0, 500, headers, NULL, pool);
return h2_response_create_int(stream_id, 0, status, headers, NULL, pool);
}

h2_response *h2_response_clone(apr_pool_t *pool, h2_response *from)
Expand Down
Loading

0 comments on commit 5742353

Please sign in to comment.