On Fri, Dec 22, 2017 at 6:14 PM, Stefan Eissing
<stefan.eiss...@greenbytes.de> wrote:
> The changes in h2_h2.c and h2_switch.c work find in my test. However, the
> change in h2_conn.c which sets CONN_STATE_LINGER does not. It prevents the
> last GOAWAY frame from the server to be sent out, in some tests.
> The current flow, when the client sends a GOAWAY is that the session
> transits to H2_SESSION_ST_DONE, the mpm calls the pre_linger hook and
> that writes the server's GOAWAY (as it does in situations where the connection
> is shut down after an idle timeout by the mpm itself).

Argh, forgot about the pre_close_connection hook..

> mod_http2 also returns from connection procession when the connection
> can only progress when more frames from the client arrive. For example,
> when the session is H2_SESSION_ST_DONE, which means that all streams have
> been processed. This is analog to a request being done on a h1 connection.
> But the h2session and all its state is still alive. So c->aborted should
> not be set. And it is definitely not in LINGER.

Yes, the issue is probably not about CONN_STATE_LINGER, but c->aborted.
I wanted to close the connection as quickly as possible, that was not
a good idea.
I could replace ap_flush_conn() by ap_lingering_close() in my patch,
but the simpler is to let the MPM do it, v2 attached simply sets
the Upgrade case, still the MPM will do the right thing with
c->keepalive = AP_CONN_CLOSE).
My main concern was returning anything else than

> I am all for aligning h2 connection states more with the connection state
> model that mpm_event has (and vice versa). Maybe we have to lock ourselves
> into a room with a whiteboard and beers and figure this out one day...

Would be a pleasure :)

> Do we have good documentation about the CONN_STATE engine somewhere?

I updated some comments in event.c lately...
Index: modules/http2/h2_conn.c
--- modules/http2/h2_conn.c	(revision 1819027)
+++ modules/http2/h2_conn.c	(working copy)
@@ -253,25 +253,12 @@ apr_status_t h2_conn_run(struct h2_ctx *ctx, conn_
     } while (!async_mpm
              && c->keepalive == AP_CONN_KEEPALIVE 
              && mpm_state != AP_MPMQ_STOPPING);
     if (c->cs) {
-        switch (session->state) {
-            case H2_SESSION_ST_INIT:
-            case H2_SESSION_ST_CLEANUP:
-            case H2_SESSION_ST_DONE:
-            case H2_SESSION_ST_IDLE:
-                c->cs->state = CONN_STATE_WRITE_COMPLETION;
-                break;
-            case H2_SESSION_ST_BUSY:
-            case H2_SESSION_ST_WAIT:
-            default:
-                c->cs->state = CONN_STATE_HANDLER;
-                break;
-        }
+        c->cs->state = CONN_STATE_LINGER;
-    return DONE;
+    return APR_SUCCESS;
 apr_status_t h2_conn_pre_close(struct h2_ctx *ctx, conn_rec *c)
Index: modules/http2/h2_h2.c
--- modules/http2/h2_h2.c	(revision 1819027)
+++ modules/http2/h2_h2.c	(working copy)
@@ -669,10 +669,11 @@ int h2_h2_process_conn(conn_rec* c)
             ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, c, "conn_setup");
             if (status != APR_SUCCESS) {
-                return status;
+                return !OK;
-        return h2_conn_run(ctx, c);
+        h2_conn_run(ctx, c);
+        return OK;
     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, declined");
Index: modules/http2/h2_switch.c
--- modules/http2/h2_switch.c	(revision 1819027)
+++ modules/http2/h2_switch.c	(working copy)
@@ -185,13 +185,12 @@ static int h2_protocol_switch(conn_rec *c, request
                 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(03088)
                               "session setup");
-                return status;
+                return !OK;
             h2_conn_run(ctx, c);
-            return DONE;
-        return DONE;
+        return OK;
     return DECLINED;

Reply via email to