From e8df1e128dac0b76a7d2481e242d3388bd5fcd01 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 16 Dec 2013 14:30:55 +0100 Subject: [PATCH] MEDIUM: http: make option http_proxy automatically rewrite the URL There are very few users of http_proxy, and all of them complain about the same thing : the request is passed unmodified to the server (in its proxy form), and it is not possible to fix it using reqrep rules because http_proxy happens after. So let's have http_proxy fix the URL it has analysed to get rid of the scheme and the host part. This will do what users of this feature expect. --- src/proto_http.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/proto_http.c b/src/proto_http.c index 721bc36bef..bd663ef338 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3747,6 +3747,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit) */ if ((s->be->options & PR_O_HTTP_PROXY) && !(s->flags & SN_ADDR_SET)) { struct connection *conn; + char *path; /* Note that for now we don't reuse existing proxy connections */ if (unlikely((conn = si_alloc_conn(req->cons, 0)) == NULL)) { @@ -3762,7 +3763,39 @@ int http_process_request(struct session *s, struct channel *req, int an_bit) return 0; } - url2sa(req->buf->p + msg->sl.rq.u, msg->sl.rq.u_l, &conn->addr.to); + + path = http_get_path(txn); + url2sa(req->buf->p + msg->sl.rq.u, + path ? path - (req->buf->p + msg->sl.rq.u) : msg->sl.rq.u_l, + &conn->addr.to); + /* if the path was found, we have to remove everything between + * req->buf->p + msg->sl.rq.u and path (excluded). If it was not + * found, we need to replace from req->buf->p + msg->sl.rq.u for + * u_l characters by a single "/". + */ + if (path) { + char *cur_ptr = req->buf->p; + char *cur_end = cur_ptr + txn->req.sl.rq.l; + int delta; + + delta = buffer_replace2(req->buf, req->buf->p + msg->sl.rq.u, path, NULL, 0); + http_msg_move_end(&txn->req, delta); + cur_end += delta; + if (http_parse_reqline(&txn->req, HTTP_MSG_RQMETH, cur_ptr, cur_end + 1, NULL, NULL) == NULL) + goto return_bad_req; + } + else { + char *cur_ptr = req->buf->p; + char *cur_end = cur_ptr + txn->req.sl.rq.l; + int delta; + + delta = buffer_replace2(req->buf, req->buf->p + msg->sl.rq.u, + req->buf->p + msg->sl.rq.u + msg->sl.rq.u_l, "/", 1); + http_msg_move_end(&txn->req, delta); + cur_end += delta; + if (http_parse_reqline(&txn->req, HTTP_MSG_RQMETH, cur_ptr, cur_end + 1, NULL, NULL) == NULL) + goto return_bad_req; + } } /*