From 069def4dc35022852d569b7ab75a3b19d2cb0f1c Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 4 Aug 2013 20:33:05 +0300 Subject: [PATCH] lib-http: Fixed redirect request target encoding and NULL target. Patch by Stephan Bosch. --- src/lib-http/http-client-request.c | 11 ++++---- src/lib-http/http-url.c | 42 ++++++++++++++++++++---------- src/lib-http/http-url.h | 2 ++ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/lib-http/http-client-request.c b/src/lib-http/http-client-request.c index 13c51267fd..1d80c83a9e 100644 --- a/src/lib-http/http-client-request.c +++ b/src/lib-http/http-client-request.c @@ -68,7 +68,7 @@ http_client_request(struct http_client *client, req->method = p_strdup(pool, method); req->hostname = p_strdup(pool, host); req->port = HTTP_DEFAULT_PORT; - req->target = p_strdup(pool, target); + req->target = (target == NULL ? "/" : p_strdup(pool, target)); req->callback = callback; req->context = context; req->headers = str_new(default_pool, 256); @@ -555,7 +555,7 @@ void http_client_request_redirect(struct http_client_request *req, unsigned int status, const char *location) { struct http_url *url; - const char *error; + const char *error, *target; unsigned int newport; /* parse URL */ @@ -607,16 +607,17 @@ void http_client_request_redirect(struct http_client_request *req, } newport = (url->have_port ? url->port : (url->have_ssl ? 443 : 80)); + target = http_url_create_target(url); - http_client_request_debug(req, "Redirecting to http://%s:%u%s", - url->host_name, newport, url->path); + http_client_request_debug(req, "Redirecting to http%s://%s:%u%s", + (url->have_ssl ? "s" : ""), url->host_name, newport, target); // FIXME: handle literal IP specially (avoid duplicate parsing) req->host = NULL; req->conn = NULL; req->hostname = p_strdup(req->pool, url->host_name); req->port = newport; - req->target = p_strdup(req->pool, url->path); + req->target = p_strdup(req->pool, target); req->ssl = url->have_ssl; /* https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-21 diff --git a/src/lib-http/http-url.c b/src/lib-http/http-url.c index 55deea5898..1574feedd4 100644 --- a/src/lib-http/http-url.c +++ b/src/lib-http/http-url.c @@ -237,6 +237,24 @@ int http_url_parse(const char *url, struct http_url *base, * HTTP URL construction */ +static void http_url_add_target(string_t *urlstr, const struct http_url *url) +{ + if (url->path == NULL || *url->path == '\0') { + /* Older syntax of RFC 2616 requires this slash at all times for an + absolute URL + */ + str_append_c(urlstr, '/'); + } else { + uri_append_path_data(urlstr, "", url->path); + } + + /* query (pre-encoded) */ + if (url->enc_query != NULL) { + str_append_c(urlstr, '?'); + str_append(urlstr, url->enc_query); + } +} + const char *http_url_create(const struct http_url *url) { string_t *urlstr = t_str_new(512); @@ -259,20 +277,7 @@ const char *http_url_create(const struct http_url *url) if (url->have_port) uri_append_port(urlstr, url->port); - if (url->path == NULL || *url->path == '\0') { - /* Older syntax of RFC 2616 requires this slash at all times for an - absolute URL - */ - str_append_c(urlstr, '/'); - } else { - uri_append_path_data(urlstr, "", url->path); - } - - /* query (pre-encoded) */ - if (url->enc_query != NULL) { - str_append_c(urlstr, '?'); - str_append(urlstr, url->enc_query); - } + http_url_add_target(urlstr, url); /* fragment */ if (url->enc_fragment != NULL) { @@ -283,6 +288,15 @@ const char *http_url_create(const struct http_url *url) return str_c(urlstr); } +const char *http_url_create_target(const struct http_url *url) +{ + string_t *urlstr = t_str_new(256); + + http_url_add_target(urlstr, url); + + return str_c(urlstr); +} + void http_url_escape_param(string_t *out, const char *data) { uri_append_query_data(out, "&;/?=+", data); diff --git a/src/lib-http/http-url.h b/src/lib-http/http-url.h index 686500086e..76067d1fce 100644 --- a/src/lib-http/http-url.h +++ b/src/lib-http/http-url.h @@ -45,6 +45,8 @@ int http_url_parse(const char *url, struct http_url *base, const char *http_url_create(const struct http_url *url); +const char *http_url_create_target(const struct http_url *url); + void http_url_escape_param(string_t *out, const char *data); #endif -- 2.47.3