dovecot-2.2: lib-http: If we get disconnected, say exactly what ...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Mar 5 14:32:14 EET 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/f89ebdc1625d
changeset: 15999:f89ebdc1625d
user: Timo Sirainen <tss at iki.fi>
date: Tue Mar 05 14:32:03 2013 +0200
description:
lib-http: If we get disconnected, say exactly what the error was.
diffstat:
src/lib-http/http-client-connection.c | 41 +++++++++++++++++++++-------------
src/lib-http/http-client-private.h | 6 +++-
src/lib-http/http-client-request.c | 33 +++++++++++++++++++++------
3 files changed, 54 insertions(+), 26 deletions(-)
diffs (220 lines):
diff -r 194ec0e10f3a -r f89ebdc1625d src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c Tue Mar 05 14:31:43 2013 +0200
+++ b/src/lib-http/http-client-connection.c Tue Mar 05 14:32:03 2013 +0200
@@ -200,6 +200,7 @@
{
struct http_client_request *const *req_idx;
struct http_client_request *req;
+ const char *error;
if (conn->to_response != NULL)
timeout_remove(&conn->to_response);
@@ -212,18 +213,19 @@
req = req_idx[0];
conn->payload_continue = TRUE;
- if (http_client_request_send_more(req) < 0) {
+ if (http_client_request_send_more(req, &error) < 0) {
http_client_connection_abort_temp_error(&conn,
- HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Failed to send request");
+ HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
+ t_strdup_printf("Failed to send request: %s", error));
}
}
bool http_client_connection_next_request(struct http_client_connection *conn)
{
struct http_client_request *req = NULL;
+ const char *error;
if (!http_client_connection_is_ready(conn)) {
-
http_client_connection_debug(conn, "Not ready for next request");
return FALSE;
}
@@ -250,10 +252,10 @@
http_client_connection_debug(conn, "Claimed request %s",
http_client_request_label(req));
- if (http_client_request_send(req) < 0) {
+ if (http_client_request_send(req, &error) < 0) {
http_client_connection_abort_temp_error(&conn,
HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
- "Failed to send request");
+ t_strdup_printf("Failed to send request: %s", error));
return FALSE;
}
@@ -292,8 +294,10 @@
break;
case CONNECTION_DISCONNECT_CONN_CLOSED:
/* retry pending requests if possible */
+ errno = _conn->input->stream_errno;
http_client_connection_retry_requests(conn,
- HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost");
+ HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
+ t_strdup_printf("Connection lost: %m"));
default:
break;
}
@@ -459,10 +463,10 @@
conn->payload_continue = TRUE;
http_client_connection_debug(conn,
"Got expected 100-continue response");
- if (http_client_request_send_more(req) < 0) {
+ if (http_client_request_send_more(req, &error) < 0) {
http_client_connection_abort_temp_error(&conn,
HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
- "Failed to send request");
+ t_strdup_printf("Failed to send request: %s", error));
}
return;
} else if (response->status / 100 == 1) {
@@ -523,13 +527,14 @@
}
if (ret <= 0 &&
- (conn->conn.input->eof || conn->conn.input->stream_errno != 0)) {
+ (conn->conn.input->eof || conn->conn.input->stream_errno != 0)) {
int stream_errno = conn->conn.input->stream_errno;
- http_client_connection_debug(conn,
- "Lost connection to server (error=%s)",
- stream_errno != 0 ? strerror(stream_errno) : "EOF");
http_client_connection_abort_temp_error(&conn,
- HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost");
+ HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
+ t_strdup_printf("Connection lost: read(%s) failed: %s",
+ i_stream_get_name(conn->conn.input),
+ stream_errno != 0 ?
+ strerror(stream_errno) : "EOF"));
return;
}
@@ -550,12 +555,15 @@
{
struct http_client_request *const *req_idx, *req;
struct ostream *output = conn->conn.output;
+ const char *error;
int ret;
if ((ret = o_stream_flush(output)) <= 0) {
if (ret < 0) {
http_client_connection_abort_temp_error(&conn,
- HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost");
+ HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
+ t_strdup_printf("Connection lost: write(%s) failed: %m",
+ o_stream_get_name(output)));
}
return ret;
}
@@ -565,9 +573,10 @@
req = req_idx[0];
if (!req->payload_sync || conn->payload_continue) {
- if (http_client_request_send_more(req) < 0) {
+ if (http_client_request_send_more(req, &error) < 0) {
http_client_connection_abort_temp_error(&conn,
- HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost");
+ HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
+ t_strdup_printf("Connection lost: %s", error));
return -1;
}
if (!conn->output_locked) {
diff -r 194ec0e10f3a -r f89ebdc1625d src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h Tue Mar 05 14:31:43 2013 +0200
+++ b/src/lib-http/http-client-private.h Tue Mar 05 14:32:03 2013 +0200
@@ -200,8 +200,10 @@
void http_client_request_ref(struct http_client_request *req);
void http_client_request_unref(struct http_client_request **_req);
-int http_client_request_send(struct http_client_request *req);
-int http_client_request_send_more(struct http_client_request *req);
+int http_client_request_send(struct http_client_request *req,
+ const char **error_r);
+int http_client_request_send_more(struct http_client_request *req,
+ const char **error_r);
void http_client_request_callback(struct http_client_request *req,
struct http_response *response);
void http_client_request_resubmit(struct http_client_request *req);
diff -r 194ec0e10f3a -r f89ebdc1625d src/lib-http/http-client-request.c
--- a/src/lib-http/http-client-request.c Tue Mar 05 14:31:43 2013 +0200
+++ b/src/lib-http/http-client-request.c Tue Mar 05 14:32:03 2013 +0200
@@ -215,6 +215,7 @@
http_client_request_finish_payload_out(req);
} else {
req->payload_input = i_stream_create_from_data(data, size);
+ i_stream_set_name(req->payload_input, "<HTTP request payload>");
}
req->payload_size = 0;
req->payload_chunked = TRUE;
@@ -275,20 +276,32 @@
return http_client_request_continue_payload(_req, NULL, 0);
}
-int http_client_request_send_more(struct http_client_request *req)
+int http_client_request_send_more(struct http_client_request *req,
+ const char **error_r)
{
struct http_client_connection *conn = req->conn;
struct ostream *output = req->payload_output;
- int ret = 0;
+ off_t ret;
i_assert(req->payload_input != NULL);
/* chunked ostream needs to write to the parent stream's buffer */
o_stream_set_max_buffer_size(output, IO_BLOCK_SIZE);
- if (o_stream_send_istream(output, req->payload_input) < 0)
- ret = -1;
+ ret = o_stream_send_istream(output, req->payload_input);
o_stream_set_max_buffer_size(output, (size_t)-1);
+ if (req->payload_input->stream_errno != 0) {
+ errno = req->payload_input->stream_errno;
+ *error_r = t_strdup_printf("read(%s) failed: %m",
+ i_stream_get_name(req->payload_input));
+ } else if (output->stream_errno != 0) {
+ errno = output->stream_errno;
+ *error_r = t_strdup_printf("write(%s) failed: %m",
+ o_stream_get_name(output));
+ } else {
+ i_assert(ret >= 0);
+ }
+
if (!i_stream_have_bytes_left(req->payload_input)) {
if (!req->payload_chunked &&
req->payload_input->v_offset - req->payload_offset != req->payload_size) {
@@ -309,10 +322,11 @@
o_stream_set_flush_pending(output, TRUE);
http_client_request_debug(req, "Partially sent payload");
}
- return ret;
+ return ret < 0 ? -1 : 0;
}
-int http_client_request_send(struct http_client_request *req)
+int http_client_request_send(struct http_client_request *req,
+ const char **error_r)
{
struct http_client_connection *conn = req->conn;
struct ostream *output = conn->conn.output;
@@ -356,14 +370,17 @@
req->state = HTTP_REQUEST_STATE_PAYLOAD_OUT;
o_stream_cork(output);
- if (o_stream_sendv(output, iov, N_ELEMENTS(iov)) < 0)
+ if (o_stream_sendv(output, iov, N_ELEMENTS(iov)) < 0) {
+ *error_r = t_strdup_printf("write(%s) failed: %m",
+ o_stream_get_name(output));
ret = -1;
+ }
http_client_request_debug(req, "Sent header");
if (ret >= 0 && req->payload_output != NULL) {
if (!req->payload_sync) {
- if (http_client_request_send_more(req) < 0)
+ if (http_client_request_send_more(req, error_r) < 0)
ret = -1;
} else {
http_client_request_debug(req, "Waiting for 100-continue");
More information about the dovecot-cvs
mailing list