package: haproxy - [PATCH 10/10] MEDIUM: http: add "redirect scheme" to ease HTTP to
HTTPS redirection git-svn-id: svn://svn.openwrt.org/openwrt/packages@38945 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
e5d1dac1c9
commit
722ee7bfa2
@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=haproxy
|
||||
PKG_VERSION:=1.4.24
|
||||
PKG_RELEASE:=09
|
||||
PKG_RELEASE:=10
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.4/src
|
||||
|
@ -0,0 +1,202 @@
|
||||
From eb9632f7c6ae675bdee4c82eb0d298ba7f37fc52 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Wed, 12 Sep 2012 08:43:15 +0200
|
||||
Subject: [PATCH 10/10] MEDIUM: http: add "redirect scheme" to ease HTTP to
|
||||
HTTPS redirection
|
||||
|
||||
For instance :
|
||||
|
||||
redirect scheme https if !{ is_ssl }
|
||||
|
||||
Backport-suggested-by: Russell Geldmacher <russell.geldmacher@gmail.com>
|
||||
(cherry picked from commit 2e1dca8f5238155cbc52d37316fe858c4f61cf34)
|
||||
---
|
||||
doc/configuration.txt | 35 ++++++++++++++++++-------
|
||||
include/types/proto_http.h | 1 +
|
||||
src/cfgparse.c | 14 +++++++++-
|
||||
src/proto_http.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 104 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/doc/configuration.txt b/doc/configuration.txt
|
||||
index 56438dd..f2043a1 100644
|
||||
--- a/doc/configuration.txt
|
||||
+++ b/doc/configuration.txt
|
||||
@@ -4039,8 +4039,9 @@ rate-limit sessions <rate>
|
||||
See also : the "backlog" keyword and the "fe_sess_rate" ACL criterion.
|
||||
|
||||
|
||||
-redirect location <to> [code <code>] <option> [{if | unless} <condition>]
|
||||
-redirect prefix <to> [code <code>] <option> [{if | unless} <condition>]
|
||||
+redirect location <loc> [code <code>] <option> [{if | unless} <condition>]
|
||||
+redirect prefix <pfx> [code <code>] <option> [{if | unless} <condition>]
|
||||
+redirect scheme <sch> [code <code>] <option> [{if | unless} <condition>]
|
||||
Return an HTTP redirection if/unless a condition is matched
|
||||
May be used in sections : defaults | frontend | listen | backend
|
||||
no | yes | yes | yes
|
||||
@@ -4049,14 +4050,25 @@ redirect prefix <to> [code <code>] <option> [{if | unless} <condition>]
|
||||
response. If no condition is specified, the redirect applies unconditionally.
|
||||
|
||||
Arguments :
|
||||
- <to> With "redirect location", the exact value in <to> is placed into
|
||||
- the HTTP "Location" header. In case of "redirect prefix", the
|
||||
- "Location" header is built from the concatenation of <to> and the
|
||||
- complete URI, including the query string, unless the "drop-query"
|
||||
- option is specified (see below). As a special case, if <to>
|
||||
- equals exactly "/" in prefix mode, then nothing is inserted
|
||||
- before the original URI. It allows one to redirect to the same
|
||||
- URL.
|
||||
+ <loc> With "redirect location", the exact value in <loc> is placed into
|
||||
+ the HTTP "Location" header.
|
||||
+
|
||||
+ <pfx> With "redirect prefix", the "Location" header is built from the
|
||||
+ concatenation of <pfx> and the complete URI path, including the
|
||||
+ query string, unless the "drop-query" option is specified (see
|
||||
+ below). As a special case, if <pfx> equals exactly "/", then
|
||||
+ nothing is inserted before the original URI. It allows one to
|
||||
+ redirect to the same URL (for instance, to insert a cookie).
|
||||
+
|
||||
+ <sch> With "redirect scheme", then the "Location" header is built by
|
||||
+ concatenating <sch> with "://" then the first occurrence of the
|
||||
+ "Host" header, and then the URI path, including the query string
|
||||
+ unless the "drop-query" option is specified (see below). If no
|
||||
+ path is found or if the path is "*", then "/" is used instead. If
|
||||
+ no "Host" header is found, then an empty host component will be
|
||||
+ returned, which most recent browsers interprete as redirecting to
|
||||
+ the same host. This directive is mostly used to redirect HTTP to
|
||||
+ HTTPS.
|
||||
|
||||
<code> The code is optional. It indicates which type of HTTP redirection
|
||||
is desired. Only codes 301, 302, 303, 307 and 308 are supported,
|
||||
@@ -4117,6 +4129,9 @@ redirect prefix <to> [code <code>] <option> [{if | unless} <condition>]
|
||||
acl missing_slash path_reg ^/article/[^/]*$
|
||||
redirect code 301 prefix / drop-query append-slash if missing_slash
|
||||
|
||||
+ Example: redirect all HTTP traffic to HTTPS when SSL is handled by haproxy.
|
||||
+ redirect scheme https if !{ is_ssl }
|
||||
+
|
||||
See section 7 about ACL usage.
|
||||
|
||||
|
||||
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
|
||||
index 09d4dd8..0e2b14f 100644
|
||||
--- a/include/types/proto_http.h
|
||||
+++ b/include/types/proto_http.h
|
||||
@@ -224,6 +224,7 @@ enum {
|
||||
REDIRECT_TYPE_NONE = 0, /* no redirection */
|
||||
REDIRECT_TYPE_LOCATION, /* location redirect */
|
||||
REDIRECT_TYPE_PREFIX, /* prefix redirect */
|
||||
+ REDIRECT_TYPE_SCHEME, /* scheme redirect (eg: switch from http to https) */
|
||||
};
|
||||
|
||||
/* Perist types (force-persist, ignore-persist) */
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index cecec03..09ffcd3 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -2182,6 +2182,18 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
cur_arg++;
|
||||
destination = args[cur_arg];
|
||||
}
|
||||
+ else if (!strcmp(args[cur_arg], "scheme")) {
|
||||
+ if (!*args[cur_arg + 1]) {
|
||||
+ Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
|
||||
+ file, linenum, args[0], args[cur_arg]);
|
||||
+ err_code |= ERR_ALERT | ERR_FATAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ type = REDIRECT_TYPE_SCHEME;
|
||||
+ cur_arg++;
|
||||
+ destination = args[cur_arg];
|
||||
+ }
|
||||
else if (!strcmp(args[cur_arg], "set-cookie")) {
|
||||
if (!*args[cur_arg + 1]) {
|
||||
Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
|
||||
@@ -2240,7 +2252,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
- Alert("parsing [%s:%d] : '%s' expects 'code', 'prefix', 'location', 'set-cookie', 'clear-cookie', 'drop-query' or 'append-slash' (was '%s').\n",
|
||||
+ Alert("parsing [%s:%d] : '%s' expects 'code', 'prefix', 'location', 'scheme', 'set-cookie', 'clear-cookie', 'drop-query' or 'append-slash' (was '%s').\n",
|
||||
file, linenum, args[0], args[cur_arg]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
diff --git a/src/proto_http.c b/src/proto_http.c
|
||||
index 7fd1fe6..ed35795 100644
|
||||
--- a/src/proto_http.c
|
||||
+++ b/src/proto_http.c
|
||||
@@ -3390,6 +3390,71 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
|
||||
goto return_bad_req;
|
||||
|
||||
switch(rule->type) {
|
||||
+ case REDIRECT_TYPE_SCHEME: {
|
||||
+ const char *path;
|
||||
+ const char *host;
|
||||
+ struct hdr_ctx ctx;
|
||||
+ int pathlen;
|
||||
+ int hostlen;
|
||||
+
|
||||
+ host = "";
|
||||
+ hostlen = 0;
|
||||
+ ctx.idx = 0;
|
||||
+ if (http_find_header2("Host", 4, msg->sol, &txn->hdr_idx, &ctx)) {
|
||||
+ host = ctx.line + ctx.val;
|
||||
+ hostlen = ctx.vlen;
|
||||
+ }
|
||||
+
|
||||
+ path = http_get_path(txn);
|
||||
+ /* build message using path */
|
||||
+ if (path) {
|
||||
+ pathlen = txn->req.sl.rq.u_l + (txn->req.sol + txn->req.sl.rq.u) - path;
|
||||
+ if (rule->flags & REDIRECT_FLAG_DROP_QS) {
|
||||
+ int qs = 0;
|
||||
+ while (qs < pathlen) {
|
||||
+ if (path[qs] == '?') {
|
||||
+ pathlen = qs;
|
||||
+ break;
|
||||
+ }
|
||||
+ qs++;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ path = "/";
|
||||
+ pathlen = 1;
|
||||
+ }
|
||||
+
|
||||
+ /* check if we can add scheme + "://" + host + path */
|
||||
+ if (rdr.len + rule->rdr_len + 3 + hostlen + pathlen > rdr.size - 4)
|
||||
+ goto return_bad_req;
|
||||
+
|
||||
+ /* add scheme */
|
||||
+ memcpy(rdr.str + rdr.len, rule->rdr_str, rule->rdr_len);
|
||||
+ rdr.len += rule->rdr_len;
|
||||
+
|
||||
+ /* add "://" */
|
||||
+ memcpy(rdr.str + rdr.len, "://", 3);
|
||||
+ rdr.len += 3;
|
||||
+
|
||||
+ /* add host */
|
||||
+ memcpy(rdr.str + rdr.len, host, hostlen);
|
||||
+ rdr.len += hostlen;
|
||||
+
|
||||
+ /* add path */
|
||||
+ memcpy(rdr.str + rdr.len, path, pathlen);
|
||||
+ rdr.len += pathlen;
|
||||
+
|
||||
+ /* append a slash at the end of the location is needed and missing */
|
||||
+ if (rdr.len && rdr.str[rdr.len - 1] != '/' &&
|
||||
+ (rule->flags & REDIRECT_FLAG_APPEND_SLASH)) {
|
||||
+ if (rdr.len > rdr.size - 5)
|
||||
+ goto return_bad_req;
|
||||
+ rdr.str[rdr.len] = '/';
|
||||
+ rdr.len++;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
case REDIRECT_TYPE_PREFIX: {
|
||||
const char *path;
|
||||
int pathlen;
|
||||
--
|
||||
1.8.1.5
|
||||
|
Loading…
x
Reference in New Issue
Block a user