The whole thing initially handled processing of several streams in parallel. 
That is why it has more states than currently necessary.

h2_proxy_session_process() returns from H2_PROXYS_ST_WAIT state to the caller 
in mod_proxy_http2.c#255. That one checks the aborted state of the "master" 
connection. So, when our frontend connection goes away, mod_proxy_http2 
processing also aborts. (Which raises the question if c->aborted can ever be 
set on a HTTP/1.1 connection during this, uhmm.)

But, as I reread it now, the h2_proxy_session_process() will not timeout when 
the frontend connection stays and the backend just does not send anything back 
at all. So, any "ProxyTimeout" seems to be ignored atm.

- Stefan

> Am 27.05.2020 um 12:40 schrieb Ruediger Pluem <[email protected]>:
> 
> I try to understand the logic of mod_proxy_http2 with respect to timeouts. I 
> am currently stuck at this piece of code in
> h2_proxy_session_process in h2_proxy_session.c
> 
>        case H2_PROXYS_ST_BUSY:
>        case H2_PROXYS_ST_LOCAL_SHUTDOWN:
>        case H2_PROXYS_ST_REMOTE_SHUTDOWN:
>            have_written = send_loop(session);
> 
>            if (nghttp2_session_want_read(session->ngh2)) {
>                status = h2_proxy_session_read(session, 0, 0);
>                if (status == APR_SUCCESS) {
>                    have_read = 1;
>                }
>            }
> 
>            if (!have_written && !have_read
>                && !nghttp2_session_want_write(session->ngh2)) {
>                dispatch_event(session, H2_PROXYS_EV_NO_IO, 0, NULL);
>                goto run_loop;
>            }
>            break;
> 
>        case H2_PROXYS_ST_WAIT:
>            if (check_suspended(session) == APR_EAGAIN) {
>                /* no stream has become resumed. Do a blocking read with
>                 * ever increasing timeouts... */
>                if (session->wait_timeout < 25) {
>                    session->wait_timeout = 25;
>                }
>                else {
>                    session->wait_timeout = H2MIN(apr_time_from_msec(100),
>                                                  2*session->wait_timeout);
>                }
> 
>                status = h2_proxy_session_read(session, 1, 
> session->wait_timeout);
>                ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, session->c,
>                              APLOGNO(03365)
>                              "h2_proxy_session(%s): WAIT read, timeout=%fms",
>                              session->id, session->wait_timeout/1000.0);
>                if (status == APR_SUCCESS) {
>                    have_read = 1;
>                    dispatch_event(session, H2_PROXYS_EV_DATA_READ, 0, NULL);
>                }
>                else if (APR_STATUS_IS_TIMEUP(status)
>                    || APR_STATUS_IS_EAGAIN(status)) {
>                    /* go back to checking all inputs again */
>                    transit(session, "wait cycle", H2_PROXYS_ST_BUSY);
>                }
> 
> 
> Doesn't that loop forever with in the end 100ms blocking reads from the 
> backend if the backend never replies?
> The state of the session seems to switch between H2_PROXYS_ST_BUSY (set in 
> line 1454) and H2_PROXYS_ST_WAIT set
> by ev_no_io. Do I miss the exit?
> 
> 
> Regards
> 
> RĂ¼diger

Reply via email to