/* Send 100 Continue when appropriate */
if (req->req.expect_100_continue && !req->payload_halted &&
req->response == NULL) {
- http_server_connection_trigger_responses(conn);
+ http_server_connection_output_trigger(conn);
}
/* Delegate payload handling to request handler */
return 1;
}
-void http_server_connection_trigger_responses(
- struct http_server_connection *conn)
+void http_server_connection_output_trigger(struct http_server_connection *conn)
{
+ if (conn->conn.output == NULL)
+ return;
o_stream_set_flush_pending(conn->conn.output, TRUE);
}
+void http_server_connection_output_halt(struct http_server_connection *conn)
+{
+ conn->output_halted = TRUE;
+
+ if (conn->conn.output == NULL)
+ return;
+
+ o_stream_unset_flush_callback(conn->conn.output);
+}
+
+void http_server_connection_output_resume(struct http_server_connection *conn)
+{
+ if (conn->output_halted) {
+ conn->output_halted = FALSE;
+ o_stream_set_flush_callback(conn->conn.output,
+ http_server_connection_output, conn);
+ }
+}
+
bool http_server_connection_pending_payload(
struct http_server_connection *conn)
{
bool close_indicated:1;
bool input_broken:1;
bool output_locked:1;
+ bool output_halted:1;
bool in_req_callback:1; /* performing request callback (busy) */
};
void http_server_connection_handle_output_error(
struct http_server_connection *conn);
-void http_server_connection_trigger_responses(
- struct http_server_connection *conn);
+void http_server_connection_output_trigger(struct http_server_connection *conn);
+void http_server_connection_output_halt(struct http_server_connection *conn);
+void http_server_connection_output_resume(struct http_server_connection *conn);
+
int http_server_connection_flush(struct http_server_connection *conn);
int http_server_connection_output(struct http_server_connection *conn);
i_assert(req->state <= HTTP_SERVER_REQUEST_STATE_QUEUED);
req->payload_halted = FALSE;
if (req->req.expect_100_continue && !req->sent_100_continue)
- http_server_connection_trigger_responses(req->conn);
+ http_server_connection_output_trigger(req->conn);
}
static void
e_debug(req->event, "Ready to respond");
req->state = HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND;
- http_server_connection_trigger_responses(req->conn);
+ http_server_connection_output_trigger(req->conn);
}
void http_server_request_submit_response(struct http_server_request *req)
http_server_request_ready_to_respond(req);
break;
case HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND:
- http_server_connection_trigger_responses(req->conn);
+ http_server_connection_output_trigger(req->conn);
break;
case HTTP_SERVER_REQUEST_STATE_ABORTED:
break;
return;
}
- http_server_connection_trigger_responses(conn);
+ http_server_connection_output_trigger(conn);
}
static struct http_server_response *
if (blocking && req->req.expect_100_continue &&
!req->sent_100_continue)
- http_server_connection_trigger_responses(conn);
+ http_server_connection_output_trigger(conn);
hsristream->read_status = 0;
io = io_add_istream(&stream->istream,
if (req->state < HTTP_SERVER_REQUEST_STATE_PAYLOAD_OUT) {
e_debug(resp->event,
"Preparing to send blocking payload");
- http_server_connection_trigger_responses(conn);
+ http_server_connection_output_trigger(conn);
} else if (resp->payload_output != NULL) {
e_debug(resp->event,
"Sending blocking payload");