return h2_from_h1_read_response(task->output->from_h1, f, bb);
}
-static apr_status_t h2_response_freeze_filter(ap_filter_t* f,
- apr_bucket_brigade* bb)
-{
- h2_task *task = f->ctx;
- AP_DEBUG_ASSERT(task);
-
- if (task->frozen) {
- ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, f->r,
- "h2_response_freeze_filter, saving");
- return ap_save_brigade(f, &task->output->frozen_bb, &bb, task->c->pool);
- }
-
- if (APR_BRIGADE_EMPTY(bb)) {
- return APR_SUCCESS;
- }
-
- ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, f->r,
- "h2_response_freeze_filter, passing");
- return ap_pass_brigade(f->next, bb);
-}
-
/*******************************************************************************
* Register various hooks
*/
NULL, AP_FTYPE_PROTOCOL);
ap_register_output_filter("H2_TRAILERS", h2_response_trailers_filter,
NULL, AP_FTYPE_PROTOCOL);
- ap_register_output_filter("H2_RESPONSE_FREEZE", h2_response_freeze_filter,
- NULL, AP_FTYPE_RESOURCE);
}
/* post config init */
apr_status_t h2_task_freeze(h2_task *task, request_rec *r)
{
if (!task->frozen) {
- conn_rec *c = task->c;
-
task->frozen = 1;
- task->output->frozen_bb = apr_brigade_create(c->pool, c->bucket_alloc);
- ap_add_output_filter("H2_RESPONSE_FREEZE", task, r, r->connection);
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, task->c,
"h2_task(%s), frozen", task->id);
}
return APR_SUCCESS;
if (output->task->frozen) {
h2_util_bb_log(output->c, output->task->stream_id, APLOG_TRACE2,
- "frozen task output write", bb);
- return ap_save_brigade(f, &output->frozen_bb, &bb, output->c->pool);
+ "frozen task output write, ignored", bb);
+ return APR_SUCCESS;
}
status = open_if_needed(output, f, bb, "write");
void h2_task_output_close(h2_task_output *output)
{
- if (output->task->frozen) {
- return;
- }
open_if_needed(output, NULL, NULL, "close");
if (output->state != H2_TASK_OUT_DONE) {
- if (output->frozen_bb && !APR_BRIGADE_EMPTY(output->frozen_bb)) {
- h2_mplx_out_write(output->task->mplx, output->task->stream_id,
- NULL, 1, output->frozen_bb, NULL, NULL);
- }
- output->state = H2_TASK_OUT_DONE;
h2_mplx_out_close(output->task->mplx, output->task->stream_id,
get_trailers(output));
+ output->state = H2_TASK_OUT_DONE;
}
}
apr_off_t written;
apr_bucket_brigade *bb;
- apr_bucket_brigade *frozen_bb;
};
h2_task_output *h2_task_output_create(struct h2_task *task, conn_rec *c);
return status;
}
-static apr_status_t setup_engine(h2_proxy_ctx *ctx)
+static apr_status_t push_request_somewhere(h2_proxy_ctx *ctx)
{
conn_rec *c = ctx->owner;
const char *engine_type, *hostname;
== APR_SUCCESS && ctx->engine == NULL) {
/* Another engine instance has taken over processing of this
* request. */
- ctx->r_status = APR_SUCCESS;
+ ctx->r_status = SUSPENDED;
ctx->next = NULL;
- return APR_EOF;
+ return APR_SUCCESS;
}
}
goto cleanup;
}
- if (!ctx->engine && setup_engine(ctx) != APR_SUCCESS) {
- goto cleanup;
+ /* If we are not already hosting an engine, try to push the request
+ * to an already existing engine or host a new engine here. */
+ if (!ctx->engine) {
+ push_request_somewhere(ctx);
+ if (ctx->r_status == SUSPENDED) {
+ /* request was pushed to another engine */
+ goto cleanup;
+ }
}
/* Step Two: Make the Connection (or check that an already existing