Hi Willy,

Yikes, sorry about the mangled patch -- not sure what happened
there... Thanks for bringing this into the 1.4 line, though!

rusty

On Mon, Nov 18, 2013 at 1:25 AM, Willy Tarreau <[email protected]> wrote:
> Hi Russell,
>
> On Fri, Nov 15, 2013 at 07:37:31PM -0500, Russell Geldmacher wrote:
>> Hi everyone,
>>
>> Recently we've had a requirement come through that could be
>> implemented quite nicely using 1.5-dev's 'redirect scheme'
>> functionality. However, (understandably) policies prevent us from
>> running a dev version in production.
>>
>> I found the original patch that Willy posted for this functionality
>> (http://marc.info/?l=haproxy&m=134743247117173) and adjusted it so
>> that it applies and runs under 1.4.24.
>>
>> Not sure if you guys accept backport patches but I just wanted to get
>> this out there in case other folks were searching for the same thing.
>
> That seems reasonably low impact, yes. However your patch was mangled,
> all spaces and tabs used for indenting were removed by your mail agent
> as you can see below. So I have just cherry-picked it again and it's
> now OK.
>
> Regards,
> Willy
>
>> ---------------------
>>
>> diff -urb haproxy-1.4.24/doc/configuration.txt
>> haproxy-1.4.24-scheme/doc/configuration.txt
>> --- a/doc/configuration.txt 2013-06-17 09:28:14.000000000 -0400
>> +++ b/doc/configuration.txt 2013-11-15 19:15:58.000000000 -0500
>> @@ -4039,8 +4039,9 @@
>>    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 @@
>>    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,
>> diff -urb haproxy-1.4.24/include/types/proto_http.h
>> haproxy-1.4.24-scheme/include/types/proto_http.h
>> --- a/include/types/proto_http.h 2013-06-17 09:28:14.000000000 -0400
>> +++ b/include/types/proto_http.h 2013-11-15 19:11:48.000000000 -0500
>> @@ -224,6 +224,7 @@
>>   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 -urb haproxy-1.4.24/src/cfgparse.c haproxy-1.4.24-scheme/src/cfgparse.c
>> --- a/src/cfgparse.c 2013-06-17 09:28:14.000000000 -0400
>> +++ b/src/cfgparse.c 2013-11-15 19:19:10.000000000 -0500
>> @@ -2182,6 +2182,18 @@
>>   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 @@
>>   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 -urb haproxy-1.4.24/src/proto_http.c 
>> haproxy-1.4.24-scheme/src/proto_http.c
>> --- a/src/proto_http.c 2013-06-17 09:28:14.000000000 -0400
>> +++ b/src/proto_http.c 2013-11-15 19:11:48.000000000 -0500
>> @@ -3390,6 +3390,71 @@
>>   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;

Reply via email to