Skip to content

Commit

Permalink
lib: iostream-pump - Specify what failed in completion callback param…
Browse files Browse the repository at this point in the history
…eter

This makes it easier for the caller to find out whether the failure was due
to istream or ostream.
  • Loading branch information
sirainen authored and Timo Sirainen committed Nov 1, 2017
1 parent 6ce52ed commit 39435f0
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 15 deletions.
12 changes: 8 additions & 4 deletions src/lib-http/http-server-request.c
Expand Up @@ -670,7 +670,7 @@ payload_handler_pump_switch_ioloop(
}

static void
payload_handler_pump_callback(bool success,
payload_handler_pump_callback(enum iostream_pump_status status,
struct http_server_payload_handler_pump *phandler)
{
struct http_server_payload_handler *handler = &phandler->handler;
Expand All @@ -679,7 +679,8 @@ payload_handler_pump_callback(bool success,
struct istream *input = iostream_pump_get_input(phandler->pump);
struct ostream *output = iostream_pump_get_output(phandler->pump);

if (success) {
switch (status) {
case IOSTREAM_PUMP_STATUS_INPUT_EOF:
if (!i_stream_read_eof(conn->incoming_payload)) {
http_server_request_fail_close(req,
413, "Payload Too Large");
Expand All @@ -694,14 +695,16 @@ payload_handler_pump_callback(bool success,
i_assert(req->callback_refcount > 0 ||
(req->response != NULL && req->response->submitted));
}
} else if (input->stream_errno != 0) {
break;
case IOSTREAM_PUMP_STATUS_INPUT_ERROR:
http_server_request_client_error(req,
"iostream_pump: read(%s) failed: %s",
i_stream_get_name(input),
i_stream_get_error(input));
http_server_request_fail_close(req,
400, "Bad Request");
} else {
break;
case IOSTREAM_PUMP_STATUS_OUTPUT_ERROR:
if (output->stream_errno != 0) {
http_server_request_error(req,
"iostream_pump: write(%s) failed: %s",
Expand All @@ -710,6 +713,7 @@ payload_handler_pump_callback(bool success,
}
http_server_request_fail_close(req,
500, "Internal Server Error");
break;
}

if (conn->payload_handler != NULL)
Expand Down
8 changes: 6 additions & 2 deletions src/lib/iostream-proxy.c
Expand Up @@ -20,14 +20,18 @@ struct iostream_proxy {
};

static
void iostream_proxy_rtl_completion(bool success, struct iostream_proxy *proxy)
void iostream_proxy_rtl_completion(enum iostream_pump_status status,
struct iostream_proxy *proxy)
{
bool success = (status == IOSTREAM_PUMP_STATUS_INPUT_EOF);
proxy->callback(IOSTREAM_PROXY_SIDE_RIGHT, success, proxy->context);
}

static
void iostream_proxy_ltr_completion(bool success, struct iostream_proxy *proxy)
void iostream_proxy_ltr_completion(enum iostream_pump_status status,
struct iostream_proxy *proxy)
{
bool success = (status == IOSTREAM_PUMP_STATUS_INPUT_EOF);
proxy->callback(IOSTREAM_PROXY_SIDE_LEFT, success, proxy->context);
}

Expand Down
13 changes: 8 additions & 5 deletions src/lib/iostream-pump.c
Expand Up @@ -41,9 +41,12 @@ void iostream_pump_copy(struct iostream_pump *pump)

switch(res) {
case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
io_remove(&pump->io);
pump->callback(IOSTREAM_PUMP_STATUS_INPUT_ERROR, pump->context);
return;
case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
io_remove(&pump->io);
pump->callback(FALSE, pump->context);
pump->callback(IOSTREAM_PUMP_STATUS_OUTPUT_ERROR, pump->context);
return;
case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT:
pump->waiting_output = TRUE;
Expand All @@ -55,14 +58,14 @@ void iostream_pump_copy(struct iostream_pump *pump)
/* flush it */
switch (o_stream_flush(pump->output)) {
case -1:
pump->callback(FALSE, pump->context);
pump->callback(IOSTREAM_PUMP_STATUS_OUTPUT_ERROR, pump->context);
break;
case 0:
pump->waiting_output = TRUE;
pump->completed = TRUE;
break;
default:
pump->callback(TRUE, pump->context);
pump->callback(IOSTREAM_PUMP_STATUS_INPUT_EOF, pump->context);
break;
}
return;
Expand All @@ -79,12 +82,12 @@ int iostream_pump_flush(struct iostream_pump *pump)
int ret;
if ((ret = o_stream_flush(pump->output)) <= 0) {
if (ret < 0)
pump->callback(FALSE, pump->context);
pump->callback(IOSTREAM_PUMP_STATUS_OUTPUT_ERROR, pump->context);
return ret;
}
pump->waiting_output = FALSE;
if (pump->completed) {
pump->callback(TRUE, pump->context);
pump->callback(IOSTREAM_PUMP_STATUS_INPUT_EOF, pump->context);
return 1;
}

Expand Down
17 changes: 15 additions & 2 deletions src/lib/iostream-pump.h
Expand Up @@ -23,7 +23,20 @@ struct istream;
struct ostream;
struct iostream_pump;

typedef void iostream_pump_callback_t(bool success, void *context);
enum iostream_pump_status {
/* pump succeeded - EOF received from istream and all output was
written successfully to ostream. */
IOSTREAM_PUMP_STATUS_INPUT_EOF,
/* pump failed - istream returned an error */
IOSTREAM_PUMP_STATUS_INPUT_ERROR,
/* pump failed - ostream returned an error */
IOSTREAM_PUMP_STATUS_OUTPUT_ERROR,
};

/* The callback is called once when the pump succeeds or fails due to
iostreams. (It's not called if pump is destroyed.) */
typedef void iostream_pump_callback_t(enum iostream_pump_status status,
void *context);

struct iostream_pump *
iostream_pump_create(struct istream *input, struct ostream *output);
Expand All @@ -41,7 +54,7 @@ void iostream_pump_set_completion_callback(struct iostream_pump *pump,
iostream_pump_callback_t *callback, void *context);
#define iostream_pump_set_completion_callback(pump, callback, context) \
iostream_pump_set_completion_callback(pump, (iostream_pump_callback_t *)callback, context + \
CALLBACK_TYPECHECK(callback, void (*)(bool, typeof(context))))
CALLBACK_TYPECHECK(callback, void (*)(enum iostream_pump_status, typeof(context))))

/* Returns TRUE if the pump is currently only writing to the ostream. The input
listener has been removed either because the ostream buffer is full or
Expand Down
4 changes: 2 additions & 2 deletions src/lib/test-iostream-pump.c
Expand Up @@ -18,10 +18,10 @@ static
unsigned char data[] = "hello, world";

static
void completed(bool success, int *u0)
void completed(enum iostream_pump_status status, int *u0)
{
/* to somehow discern between error and success .. */
(*u0) -= (success ? 1 : 2);
(*u0) -= (status == IOSTREAM_PUMP_STATUS_INPUT_EOF ? 1 : 2);
io_loop_stop(current_ioloop);
}

Expand Down

0 comments on commit 39435f0

Please sign in to comment.