void h2_ngn_shed_abort(h2_ngn_shed *shed)
{
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, shed->c,
+ "h2_ngn_shed(%ld): abort", shed->c->id);
shed->aborted = 1;
}
"h2_ngn_shed(%ld): pull task for engine %s, shutdown=%d",
shed->c->id, ngn->id, want_shutdown);
if (shed->aborted) {
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, shed->c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, shed->c,
"h2_ngn_shed(%ld): abort while pulling requests %s",
shed->c->id, ngn->id);
ngn->shutdown = 1;
if (entry->task->c && ngn->c) {
entry->task->c->current_thread = ngn->c->current_thread;
}
+ if (entry->task->engine == ngn) {
+ /* If an engine pushes its own base task, and then pulls
+ * it back to itself again, it needs to be thawed.
+ */
+ h2_task_thaw(entry->task);
+ }
return APR_SUCCESS;
}
h2_stream_state_t state;
unsigned int suspended : 1;
+ unsigned int data_sent : 1;
unsigned int data_received : 1;
+ uint32_t error_code;
apr_bucket_brigade *input;
apr_bucket_brigade *output;
* that it has started processing. */
session->last_stream_id = frame->goaway.last_stream_id;
dispatch_event(session, H2_PROXYS_EV_REMOTE_GOAWAY, 0, NULL);
- if (APLOGcinfo(session->c)) {
- char buffer[256];
-
- h2_util_frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03342)
- "h2_proxy_session(%s): recv FRAME[%s]",
- session->id, buffer);
- }
break;
default:
break;
uint32_t error_code, void *user_data)
{
h2_proxy_session *session = user_data;
+ h2_proxy_stream *stream;
if (!session->aborted) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03360)
"h2_proxy_session(%s): stream=%d, closed, err=%d",
session->id, stream_id, error_code);
+ stream = h2_ihash_get(session->streams, stream_id);
+ if (stream) {
+ stream->error_code = error_code;
+ }
dispatch_event(session, H2_PROXYS_EV_STREAM_DONE, stream_id, NULL);
}
return 0;
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, status, stream->r,
"h2_proxy_stream(%d): request body read %ld bytes, flags=%d",
stream->id, (long)readlen, (int)*data_flags);
+ stream->data_sent = 1;
return readlen;
}
else if (APR_STATUS_IS_EAGAIN(status)) {
stream = nghttp2_session_get_stream_user_data(session->ngh2, stream_id);
if (stream) {
+ int touched = (stream->data_sent ||
+ stream_id <= session->last_stream_id);
+ int complete = (stream->error_code == 0);
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03364)
- "h2_proxy_sesssion(%s): stream(%d) closed",
- session->id, stream_id);
+ "h2_proxy_sesssion(%s): stream(%d) closed "
+ "(complete=%d, touched=%d)",
+ session->id, stream_id, complete, touched);
- if (!stream->data_received) {
+ if (complete && !stream->data_received) {
apr_bucket *b;
/* if the response had no body, this is the time to flush
* an empty brigade which will also "write" the resonse
h2_ihash_remove(session->streams, stream_id);
h2_iq_remove(session->suspended, stream_id);
if (session->done) {
- session->done(session, stream->r, 1, 1);
+ session->done(session, stream->r, complete, touched);
}
}
APR_BLOCK_READ: APR_NONBLOCK_READ,
ctx->capacity, &ctx->next);
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, ctx->owner,
- "h2_proxy_engine(%s): pulled request %s",
+ "h2_proxy_engine(%s): pulled request (%s) %s",
ctx->engine_id,
+ before_leave? "before leave" : "regular",
(ctx->next? ctx->next->the_request : "NULL"));
return APR_STATUS_IS_EAGAIN(status)? APR_SUCCESS : status;
}
else {
/* end of processing, maybe error */
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner,
- APLOGNO(03375) "eng(%s): end of session run",
- ctx->engine_id);
+ APLOGNO(03375) "eng(%s): end of session %s",
+ ctx->engine_id, ctx->session->id);
/*
* Any open stream of that session needs to
* a) be reopened on the new session iff safe to do so