changeset 20344:2b71a1c2febc

lib-http: Changed http_client_request_error to set request to NULL It's going to internally unreference it, so the caller should be aware of it also. I also changed request state check to be an assert, since I don't think there's any safe way this could work otherwise.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 18 May 2016 19:40:32 +0300
parents b71ec4f214a6
children faef7fa2d17a
files src/lib-http/http-client-connection.c src/lib-http/http-client-host.c src/lib-http/http-client-private.h src/lib-http/http-client-queue.c src/lib-http/http-client-request.c
diffstat 5 files changed, 20 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-http/http-client-connection.c	Sat May 21 00:16:38 2016 +0200
+++ b/src/lib-http/http-client-connection.c	Wed May 18 19:40:32 2016 +0300
@@ -114,7 +114,7 @@
 
 	array_foreach_modifiable(&conn->request_wait_list, req) {
 		i_assert((*req)->submitted);
-		http_client_request_error(*req, status, error);
+		http_client_request_error(req, status, error);
 		http_client_request_unref(req);
 	}
 	array_clear(&conn->request_wait_list);
@@ -129,7 +129,7 @@
 	if (array_is_created(&conn->request_wait_list)) {
 		array_foreach_modifiable(&conn->request_wait_list, req) {
 			i_assert((*req)->submitted);
-			http_client_request_error(*req,
+			http_client_request_error(req,
 				HTTP_CLIENT_REQUEST_ERROR_ABORTED,
 				"Aborting");
 			http_client_request_unref(req);
@@ -139,7 +139,7 @@
 	if (conn->pending_request != NULL) {
 		struct http_client_request *pending_req = conn->pending_request;
 		conn->pending_request = NULL;
-		http_client_request_error(pending_req,
+		http_client_request_error(&pending_req,
 			HTTP_CLIENT_REQUEST_ERROR_ABORTED,
 			"Aborting");
 		http_client_request_unref(&pending_req);
@@ -819,7 +819,7 @@
 			/* response cannot be 2xx if request payload was not completely sent
 			 */
 			if (early && response.status / 100 == 2) {
-				http_client_request_error(req,
+				http_client_request_error(&req,
 					HTTP_CLIENT_REQUEST_ERROR_BAD_RESPONSE,
 					"Server responded with success response "
 					"before all payload was sent");
--- a/src/lib-http/http-client-host.c	Sat May 21 00:16:38 2016 +0200
+++ b/src/lib-http/http-client-host.c	Wed May 18 19:40:32 2016 +0300
@@ -210,7 +210,7 @@
 	if (http_client_peer_addr_is_https(&addr) &&
 		host->client->ssl_ctx == NULL) {
 		if (http_client_init_ssl_ctx(host->client, &error) < 0) {
-			http_client_request_error(req,
+			http_client_request_error(&req,
 				HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, error);
 			return;
 		}
--- a/src/lib-http/http-client-private.h	Sat May 21 00:16:38 2016 +0200
+++ b/src/lib-http/http-client-private.h	Wed May 18 19:40:32 2016 +0300
@@ -296,7 +296,7 @@
 void http_client_request_retry(struct http_client_request *req,
 	unsigned int status, const char *error);
 void http_client_request_error_delayed(struct http_client_request **_req);
-void http_client_request_error(struct http_client_request *req,
+void http_client_request_error(struct http_client_request **req,
 	unsigned int status, const char *error);
 void http_client_request_redirect(struct http_client_request *req,
 	unsigned int status, const char *location);
--- a/src/lib-http/http-client-queue.c	Sat May 21 00:16:38 2016 +0200
+++ b/src/lib-http/http-client-queue.c	Wed May 18 19:40:32 2016 +0300
@@ -154,7 +154,7 @@
 	t_array_init(&treqs, array_count(req_arr));
 	array_copy(&treqs.arr, 0, &req_arr->arr, 0, array_count(req_arr));
 	array_foreach_modifiable(&treqs, req_idx) {
-		http_client_request_error(*req_idx, status, error);
+		http_client_request_error(req_idx, status, error);
 	}
 
 	/* all queues should be empty now... unless new requests were submitted
@@ -536,7 +536,7 @@
 
 		http_client_queue_debug(queue,
 			"Request %s timed out",	http_client_request_label(req));
-		http_client_request_error(req,
+		http_client_request_error(&req,
 			HTTP_CLIENT_REQUEST_ERROR_TIMED_OUT,
 			"Timed out");
 	}
--- a/src/lib-http/http-client-request.c	Sat May 21 00:16:38 2016 +0200
+++ b/src/lib-http/http-client-request.c	Wed May 18 19:40:32 2016 +0300
@@ -1088,11 +1088,12 @@
 	http_client_request_destroy(&req);
 }
 
-void http_client_request_error(struct http_client_request *req,
+void http_client_request_error(struct http_client_request **_req,
 	unsigned int status, const char *error)
 {
-	if (req->state >= HTTP_REQUEST_STATE_FINISHED)
-		return;
+	struct http_client_request *req = *_req;
+
+	i_assert(req->state < HTTP_REQUEST_STATE_FINISHED);
 	req->state = HTTP_REQUEST_STATE_ABORTED;
 
 	if (req->queue != NULL)
@@ -1111,6 +1112,7 @@
 		http_client_request_send_error(req, status, error);
 		http_client_request_destroy(&req);
 	}
+	*_req = NULL;
 }
 
 void http_client_request_abort(struct http_client_request **_req)
@@ -1166,19 +1168,19 @@
 	/* parse URL */
 	if (http_url_parse(location, NULL, 0,
 			   pool_datastack_create(), &url, &error) < 0) {
-		http_client_request_error(req, HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
+		http_client_request_error(&req, HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
 			t_strdup_printf("Invalid redirect location: %s", error));
 		return;
 	}
 
 	if (++req->redirects > req->client->set.max_redirects) {
 		if (req->client->set.max_redirects > 0) {
-			http_client_request_error(req,
+			http_client_request_error(&req,
 				HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
 				t_strdup_printf("Redirected more than %d times",
 					req->client->set.max_redirects));
 		} else {
-			http_client_request_error(req,
+			http_client_request_error(&req,
 				HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
 					"Redirect refused");
 		}
@@ -1189,7 +1191,7 @@
 	if (req->payload_input != NULL && req->payload_size > 0 && status != 303) {
 		if (req->payload_input->v_offset != req->payload_offset &&
 			!req->payload_input->seekable) {
-			http_client_request_error(req,
+			http_client_request_error(&req,
 				HTTP_CLIENT_REQUEST_ERROR_ABORTED,
 				"Redirect failed: Cannot resend payload; stream is not seekable");
 			return;
@@ -1252,7 +1254,7 @@
 	if (req->payload_input != NULL && req->payload_size > 0) {
 		if (req->payload_input->v_offset != req->payload_offset &&
 			!req->payload_input->seekable) {
-			http_client_request_error(req,
+			http_client_request_error(&req,
 				HTTP_CLIENT_REQUEST_ERROR_ABORTED,
 				"Resubmission failed: Cannot resend payload; stream is not seekable");
 			return;
@@ -1265,7 +1267,7 @@
 	if (req->payload_input != NULL && req->payload_size > 0) {
 		if (req->payload_input->v_offset != req->payload_offset &&
 			!req->payload_input->seekable) {
-			http_client_request_error(req,
+			http_client_request_error(&req,
 				HTTP_CLIENT_REQUEST_ERROR_ABORTED,
 				"Resubmission failed: Cannot resend payload; stream is not seekable");
 			return;
@@ -1288,7 +1290,7 @@
 	unsigned int status, const char *error)
 {
 	if (!http_client_request_try_retry(req))
-		http_client_request_error(req, status, error);
+		http_client_request_error(&req, status, error);
 }
 
 bool http_client_request_try_retry(struct http_client_request *req)