If the provided HTTP URL is invalid, the callback with the error is called some time later from the ioloop.
This change also amends the test-http-client-errors test suite with a new test for this new feature.
return req;
}
+#undef http_client_request_url_str
+struct http_client_request *
+http_client_request_url_str(struct http_client *client,
+ const char *method, const char *url_str,
+ http_client_request_callback_t *callback, void *context)
+{
+ struct http_client_request *req, *tmpreq;
+ struct http_url *target_url;
+ const char *error;
+
+ req = tmpreq = http_client_request_new
+ (client, method, callback, context);
+
+ if (http_url_parse(url_str, NULL, HTTP_URL_ALLOW_USERINFO_PART,
+ req->pool, &target_url, &error) < 0) {
+ req->label = p_strdup_printf(req->pool,
+ "[Req%u: %s %s]", req->id, req->method, url_str);
+ http_client_request_error(&tmpreq,
+ HTTP_CLIENT_REQUEST_ERROR_INVALID_URL,
+ t_strdup_printf("Invalid HTTP URL: %s", error));
+ return req;
+ }
+
+ req->origin_url = *target_url;
+ req->target = p_strdup(req->pool, http_url_create_target(target_url));
+ if (target_url->user != NULL && *target_url->user != '\0' &&
+ target_url->password != NULL) {
+ req->username = p_strdup(req->pool, target_url->user);
+ req->password = p_strdup(req->pool, target_url->password);
+ }
+ return req;
+}
+
#undef http_client_request_connect
struct http_client_request *
http_client_request_connect(struct http_client *client,
(req->host_socket != NULL) || (req->host_url != NULL);
const char *authority, *target;
+ if (req->state == HTTP_REQUEST_STATE_ABORTED)
+ return;
i_assert(req->state == HTTP_REQUEST_STATE_NEW);
authority = http_url_create_authority(&req->origin_url);
enum http_client_request_error {
/* The request was aborted */
HTTP_CLIENT_REQUEST_ERROR_ABORTED = HTTP_RESPONSE_STATUS_INTERNAL,
+ /* Failed to parse HTTP target url */
+ HTTP_CLIENT_REQUEST_ERROR_INVALID_URL,
/* Failed to perform DNS lookup for the host */
HTTP_CLIENT_REQUEST_ERROR_HOST_LOOKUP_FAILED,
/* Failed to setup any connection for the host and client settings allowed
CALLBACK_TYPECHECK(callback, void (*)( \
const struct http_response *response, typeof(context))), \
(http_client_request_callback_t *)callback, context)
+struct http_client_request *
+http_client_request_url_str(struct http_client *client,
+ const char *method, const char *url_str,
+ http_client_request_callback_t *callback, void *context);
+#define http_client_request_url_str(client, method, url_str, callback, context) \
+ http_client_request_url_str(client, method, url_str + \
+ CALLBACK_TYPECHECK(callback, void (*)( \
+ const struct http_response *response, typeof(context))), \
+ (http_client_request_callback_t *)callback, context)
/* create new HTTP CONNECT request. If this HTTP is configured to use a proxy,
a CONNECT request will be submitted at that proxy, otherwise the connection
test_end();
}
+/*
+ * Invalid URL
+ */
+
+/* client */
+
+struct _invalid_url {
+ unsigned int count;
+};
+
+static void
+test_client_invalid_url_response(
+ const struct http_response *resp,
+ struct _invalid_url *ctx)
+{
+ if (debug)
+ i_debug("RESPONSE: %u %s", resp->status, resp->reason);
+
+ test_assert(resp->status == HTTP_CLIENT_REQUEST_ERROR_INVALID_URL);
+ test_assert(resp->reason != NULL && *resp->reason != '\0');
+
+ if (--ctx->count == 0) {
+ i_free(ctx);
+ io_loop_stop(ioloop);
+ }
+}
+
+static bool
+test_client_invalid_url(const struct http_client_settings *client_set)
+{
+ struct http_client_request *hreq;
+ struct _invalid_url *ctx;
+
+ ctx = i_new(struct _invalid_url, 1);
+ ctx->count = 2;
+
+ http_client = http_client_init(client_set);
+
+ hreq = http_client_request_url_str(http_client,
+ "GET", "imap://example.com/INBOX",
+ test_client_invalid_url_response, ctx);
+ http_client_request_submit(hreq);
+
+ hreq = http_client_request_url_str(http_client,
+ "GET", "http:/www.example.com",
+ test_client_invalid_url_response, ctx);
+ http_client_request_submit(hreq);
+
+ return TRUE;
+}
+
+/* test */
+
+static void test_invalid_url(void)
+{
+ struct http_client_settings http_client_set;
+
+ test_client_defaults(&http_client_set);
+
+ test_begin("invalid url");
+ test_run_client_server(&http_client_set,
+ test_client_invalid_url,
+ NULL, 0, NULL);
+ test_end();
+}
+
/*
* Host lookup failed
*/
static void (*const test_functions[])(void) = {
test_unconfigured_ssl,
+ test_invalid_url,
test_host_lookup_failed,
test_connection_refused,
test_connection_lost_prematurely,