You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2015/12/14 14:02:50 UTC
svn commit: r1719901 - in /httpd/httpd/trunk/modules/http2: h2_conn.c
h2_conn.h h2_ctx.c h2_ctx.h h2_h2.c h2_session.c h2_switch.c h2_worker.c
Author: icing
Date: Mon Dec 14 13:02:50 2015
New Revision: 1719901
URL: http://svn.apache.org/viewvc?rev=1719901&view=rev
Log:
internal rewiring to prepare for return from connection processing frequently before session end
Modified:
httpd/httpd/trunk/modules/http2/h2_conn.c
httpd/httpd/trunk/modules/http2/h2_conn.h
httpd/httpd/trunk/modules/http2/h2_ctx.c
httpd/httpd/trunk/modules/http2/h2_ctx.h
httpd/httpd/trunk/modules/http2/h2_h2.c
httpd/httpd/trunk/modules/http2/h2_session.c
httpd/httpd/trunk/modules/http2/h2_switch.c
httpd/httpd/trunk/modules/http2/h2_worker.c
Modified: httpd/httpd/trunk/modules/http2/h2_conn.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn.c?rev=1719901&r1=1719900&r2=1719901&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_conn.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_conn.c Mon Dec 14 13:02:50 2015
@@ -126,12 +126,10 @@ static module *h2_conn_mpm_module(void)
return mpm_module;
}
-apr_status_t h2_conn_process(conn_rec *c, request_rec *r, server_rec *s)
+apr_status_t h2_conn_setup(h2_ctx *ctx, conn_rec *c, request_rec *r)
{
- apr_status_t status;
h2_session *session;
const h2_config *config;
- int rv;
if (!workers) {
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02911)
@@ -139,28 +137,34 @@ apr_status_t h2_conn_process(conn_rec *c
return APR_EGENERAL;
}
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "h2_conn_process start");
-
- if (!s && r) {
- s = r->server;
- }
-
- config = s? h2_config_sget(s) : h2_config_get(c);
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "h2_conn_setup");
+ config = h2_config_sget(h2_ctx_server_get(ctx));
if (r) {
session = h2_session_rcreate(r, config, workers);
}
else {
session = h2_session_create(c, config, workers);
}
+
+ h2_ctx_session_set(ctx, session);
+ return APR_SUCCESS;
+}
+
+apr_status_t h2_conn_process(h2_ctx *ctx)
+{
+ apr_status_t status;
+ h2_session *session;
+ conn_rec *c;
+ int rv;
+
+ session = h2_ctx_session_get(ctx);
+ c = session->c;
if (!h2_is_acceptable_connection(c, 1)) {
nghttp2_submit_goaway(session->ngh2, NGHTTP2_FLAG_NONE, 0,
NGHTTP2_INADEQUATE_SECURITY, NULL, 0);
}
- /* What do install instead? */
- ap_remove_input_filter_byhandle(c->input_filters, "reqtimeout");
-
ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c);
status = h2_session_start(session, &rv);
@@ -176,20 +180,34 @@ apr_status_t h2_conn_process(conn_rec *c
status = h2_session_process(session);
- ap_log_cerror( APLOG_MARK, APLOG_DEBUG, status, session->c,
- "h2_session(%ld): done", session->id);
- /* Make sure this connection gets closed properly. */
- ap_update_child_status_from_conn(c->sbh, SERVER_CLOSING, c);
- c->keepalive = AP_CONN_CLOSE;
- if (c->cs) {
- c->cs->state = CONN_STATE_WRITE_COMPLETION;
+ if (status == APR_EOF) {
+ ap_log_cerror( APLOG_MARK, APLOG_DEBUG, status, session->c,
+ "h2_session(%ld): done", session->id);
+ /* Make sure this connection gets closed properly. */
+ ap_update_child_status_from_conn(c->sbh, SERVER_CLOSING, c);
+ c->keepalive = AP_CONN_CLOSE;
+ if (c->cs) {
+ c->cs->state = CONN_STATE_WRITE_COMPLETION;
+ }
+
+ h2_session_close(session);
+ /* hereafter session will be gone */
}
-
- h2_session_close(session);
- /* hereafter session will be gone */
+
return status;
}
+apr_status_t h2_conn_run(struct h2_ctx *ctx)
+{
+ apr_status_t status;
+
+ do {
+ status = h2_conn_process(ctx);
+ } while (status == APR_SUCCESS);
+
+ return (status == APR_EOF)? APR_SUCCESS : status;
+}
+
static void fix_event_conn(conn_rec *c, conn_rec *master);
@@ -220,8 +238,8 @@ conn_rec *h2_conn_create(conn_rec *maste
return c;
}
-apr_status_t h2_conn_setup(h2_task *task, apr_bucket_alloc_t *bucket_alloc,
- apr_thread_t *thread, apr_socket_t *socket)
+apr_status_t h2_slave_setup(h2_task *task, apr_bucket_alloc_t *bucket_alloc,
+ apr_thread_t *thread, apr_socket_t *socket)
{
conn_rec *master = task->mplx->c;
Modified: httpd/httpd/trunk/modules/http2/h2_conn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn.h?rev=1719901&r1=1719900&r2=1719901&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_conn.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_conn.h Mon Dec 14 13:02:50 2015
@@ -16,18 +16,36 @@
#ifndef __mod_h2__h2_conn__
#define __mod_h2__h2_conn__
+struct h2_ctx;
struct h2_task;
/**
- * Process the connection that is now starting the HTTP/2
- * conversation. Return when the HTTP/2 session is done
- * and the connection will close.
+ * Setup the connection and our context for HTTP/2 processing
*
+ * @param ctx the http2 context to setup
* @param c the connection HTTP/2 is starting on
* @param r the upgrade request that still awaits an answer, optional
- * @param s the server selected by request or, if NULL, connection
*/
-apr_status_t h2_conn_process(conn_rec *c, request_rec *r, server_rec *s);
+apr_status_t h2_conn_setup(struct h2_ctx *ctx, conn_rec *c, request_rec *r);
+
+/**
+ * Process the HTTP/2 connection. Return whenever blocking reads or
+ * long writes have to be performed.
+ *
+ * @param ctx the http2 context to process
+ * @return APR_SUCCESS as long as processing needs to continue, APR_EOF
+ * when HTTP/2 session is done.
+ */
+apr_status_t h2_conn_process(struct h2_ctx *ctx);
+
+/**
+ * Run the HTTP/2 connection. Return when the HTTP/2 session is done
+ * and the connection will close or a fatal error occured.
+ *
+ * @param ctx the http2 context to run
+ * @return APR_SUCCESS when session is done.
+ */
+apr_status_t h2_conn_run(struct h2_ctx *ctx);
/* Initialize this child process for h2 connection work,
* to be called once during child init before multi processing
@@ -49,7 +67,7 @@ h2_mpm_type_t h2_conn_mpm_type(void);
conn_rec *h2_conn_create(conn_rec *master, apr_pool_t *stream_pool);
-apr_status_t h2_conn_setup(struct h2_task *task, apr_bucket_alloc_t *bucket_alloc,
- apr_thread_t *thread, apr_socket_t *socket);
+apr_status_t h2_slave_setup(struct h2_task *task, apr_bucket_alloc_t *bucket_alloc,
+ apr_thread_t *thread, apr_socket_t *socket);
#endif /* defined(__mod_h2__h2_conn__) */
Modified: httpd/httpd/trunk/modules/http2/h2_ctx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_ctx.c?rev=1719901&r1=1719900&r2=1719901&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_ctx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_ctx.c Mon Dec 14 13:02:50 2015
@@ -30,6 +30,7 @@ static h2_ctx *h2_ctx_create(const conn_
h2_ctx *ctx = apr_pcalloc(c->pool, sizeof(h2_ctx));
AP_DEBUG_ASSERT(ctx);
ap_set_module_config(c->conn_config, &http2_module, ctx);
+ h2_ctx_server_set(ctx, c->base_server);
return ctx;
}
@@ -78,6 +79,11 @@ void h2_ctx_session_set(h2_ctx *ctx, str
ctx->session = session;
}
+server_rec *h2_ctx_server_get(h2_ctx *ctx)
+{
+ return ctx? ctx->server : NULL;
+}
+
h2_ctx *h2_ctx_server_set(h2_ctx *ctx, server_rec *s)
{
ctx->server = s;
Modified: httpd/httpd/trunk/modules/http2/h2_ctx.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_ctx.h?rev=1719901&r1=1719900&r2=1719901&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_ctx.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_ctx.h Mon Dec 14 13:02:50 2015
@@ -57,6 +57,7 @@ h2_ctx *h2_ctx_protocol_set(h2_ctx *ctx,
/* Set the server_rec relevant for this context.
*/
h2_ctx *h2_ctx_server_set(h2_ctx *ctx, server_rec *s);
+server_rec *h2_ctx_server_get(h2_ctx *ctx);
struct h2_session *h2_ctx_session_get(h2_ctx *ctx);
void h2_ctx_session_set(h2_ctx *ctx, struct h2_session *session);
Modified: httpd/httpd/trunk/modules/http2/h2_h2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.c?rev=1719901&r1=1719900&r2=1719901&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_h2.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_h2.c Mon Dec 14 13:02:50 2015
@@ -554,15 +554,19 @@ int h2_allows_h2_upgrade(conn_rec *c)
/*******************************************************************************
* Register various hooks
*/
-static const char* const mod_ssl[] = {"mod_ssl.c", NULL};
+static const char* const mod_ssl[] = { "mod_ssl.c", NULL};
+static const char* const mod_reqtimeout[] = { "mod_reqtimeout.c", NULL};
void h2_h2_register_hooks(void)
{
- /* When the connection processing actually starts, we might to
- * take over, if h2* was selected as protocol.
+ /* Our main processing needs to run quite late. Definitely after mod_ssl,
+ * as we need its connection filters, but also before reqtimeout as its
+ * method of timeouts is specific to HTTP/1.1 (as of now).
+ * The core HTTP/1 processing run as REALLY_LAST, so we will have
+ * a chance to take over before it.
*/
ap_hook_process_connection(h2_h2_process_conn,
- mod_ssl, NULL, APR_HOOK_MIDDLE);
+ mod_ssl, mod_reqtimeout, APR_HOOK_LAST);
/* With "H2SerializeHeaders On", we install the filter in this hook
* that parses the response. This needs to happen before any other post
@@ -574,6 +578,7 @@ void h2_h2_register_hooks(void)
int h2_h2_process_conn(conn_rec* c)
{
+ apr_status_t status;
h2_ctx *ctx;
if (c->master) {
@@ -586,19 +591,16 @@ int h2_h2_process_conn(conn_rec* c)
/* our stream pseudo connection */
return DECLINED;
}
-
- if (h2_ctx_protocol_get(c)) {
- /* Something has been negotiated */
- }
- else if (!strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))
- && h2_allows_h2_direct(c)
- && h2_is_acceptable_connection(c, 1)) {
- /* connection still is on http/1.1 and H2Direct is enabled.
+
+ if (!ctx && c->keepalives == 0
+ && !strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))
+ && h2_allows_h2_direct(c)
+ && h2_is_acceptable_connection(c, 1)) {
+ /* Fresh connection still is on http/1.1 and H2Direct is enabled.
* Otherwise connection is in a fully acceptable state.
* -> peek at the first 24 incoming bytes
*/
apr_bucket_brigade *temp;
- apr_status_t status;
char *s = NULL;
apr_size_t slen;
@@ -630,19 +632,17 @@ int h2_h2_process_conn(conn_rec* c)
apr_brigade_destroy(temp);
}
- else {
- /* the connection is not HTTP/1.1 or not for us, don't touch it */
- return DECLINED;
- }
- /* If "h2" was selected as protocol (by whatever mechanism), take over
- * the connection.
- */
if (ctx) {
- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
- "h2_h2, connection, h2 active");
-
- return h2_conn_process(c, NULL, ctx->server);
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "process_conn");
+ if (!h2_ctx_session_get(ctx)) {
+ status = h2_conn_setup(ctx, c, NULL);
+ if (status != APR_SUCCESS) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, "conn_setup");
+ return status;
+ }
+ }
+ return h2_conn_process(ctx);
}
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, declined");
Modified: httpd/httpd/trunk/modules/http2/h2_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_session.c?rev=1719901&r1=1719900&r2=1719901&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_session.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_session.c Mon Dec 14 13:02:50 2015
@@ -1596,6 +1596,7 @@ apr_status_t h2_session_process(h2_sessi
"h2_session: send: %s", nghttp2_strerror(rv));
if (nghttp2_is_fatal(rv)) {
h2_session_abort(session, status, rv);
+ status = APR_EGENERAL;
goto end_process;
}
}
@@ -1622,6 +1623,7 @@ apr_status_t h2_session_process(h2_sessi
"h2_session: send: %s", nghttp2_strerror(rv));
if (nghttp2_is_fatal(rv)) {
h2_session_abort(session, status, rv);
+ status = APR_EGENERAL;
goto end_process;
}
}
@@ -1760,6 +1762,8 @@ apr_status_t h2_session_process(h2_sessi
h2_conn_io_flush(&session->io);
}
}
+ /* normal end of session */
+ status = APR_EOF;
end_process:
return status;
Modified: httpd/httpd/trunk/modules/http2/h2_switch.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_switch.c?rev=1719901&r1=1719900&r2=1719901&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_switch.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_switch.c Mon Dec 14 13:02:50 2015
@@ -155,12 +155,15 @@ static int h2_protocol_switch(conn_rec *
ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
/* Ok, start an h2_conn on this one. */
- status = h2_conn_process(r->connection, r, r->server);
- if (status != DONE) {
- /* Nothing really to do about this. */
+ h2_ctx_server_set(ctx, r->server);
+ status = h2_conn_setup(ctx, r->connection, r);
+ if (status != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
- "session proessed, unexpected status");
+ "session setup");
+ return status;
}
+
+ return h2_conn_run(ctx);
}
return DONE;
}
Modified: httpd/httpd/trunk/modules/http2/h2_worker.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_worker.c?rev=1719901&r1=1719900&r2=1719901&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_worker.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_worker.c Mon Dec 14 13:02:50 2015
@@ -182,8 +182,8 @@ apr_status_t h2_worker_setup_task(h2_wor
apr_status_t status;
- status = h2_conn_setup(task, apr_bucket_alloc_create(task->pool),
- worker->thread, worker->socket);
+ status = h2_slave_setup(task, apr_bucket_alloc_create(task->pool),
+ worker->thread, worker->socket);
return status;
}