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