Roxen.git / server / modules / filters / hostredirect.pike

version» Context lines:

Roxen.git/server/modules/filters/hostredirect.pike:1:   // This is a roxen module. Copyright © 1996 - 2009, Roxen IS.      // This module redirects requests to different places, depending on the   // hostname that was used to access the server. It can be used as a   // cheap way (IP number wise) to do virtual hosting. Note that this   // won't work with all clients.      // responsible for the changes to the original version 1.3: Martin Baehr mbaehr@iaeste.or.at    - constant cvs_version = "$Id: hostredirect.pike,v 1.41 2011/05/25 14:49:05 grubba Exp $"; + constant cvs_version = "$Id$";   constant thread_safe=1;      inherit "module";   #include <module.h>      #ifdef HOSTREDIRECT_DEBUG   #define dwerror(ARGS...) werror(ARGS)   #else   #define dwerror(ARGS...) 0   #endif      void create()   {    defvar("hostredirect", "", "Redirect rules", TYPE_TEXT_FIELD,    "Syntax:<pre>" -  "[permanent] domain [other domain][path]</pre>" +  " <i>domain path</i></pre>"    "<strong>Examples:</strong><pre>" -  " permanent domain.com www.domain.com" +     " ab.domain.com /ab/\n"    " bc.domain.com /bc/\n"    " main.domain.com /\n" -  " ab.domian.com www.domain.com/ab/" +     " default /serverlist.html</pre>"    "<p>If someone access the server at http://ab.domain.com/text.html, "    "it will be internally redirected to http://ab.domain.com/ab/text.html. "    "If someone accesses http://bc.domain.com/bc/text.html, the URL "    "won't be modified. The <tt>default</tt> line is a special case "    "which points on a file which is used when no hosts match. It is "    "very recommended that this file contains a list of all the "    "servers, with correct URL's. If someone visits with a client "    "that doesn't send the <tt>host</tt> header, the module won't "    "do anything at all.</p>\n" -  "<p>If the first string on the line is 'permanent', the http return code is " -  "301 (moved permanently) instead of 302 (found).</p> " +     "v2 also allows the following syntax for HTTP redirects:<pre>" -  "[permanent] domain [url][path][%p]\n</pre>" +  " <tt>[permanent]</tt> <i>domain</i> <i>target</i>\n</pre>"    "<strong>Examples:</strong><pre>" -  " ab.domain.org http://my.university.edu/~me/ab/%p\n" -  " bc.domain.com %u/bc/%p%q\n" -  " default %u/serverlist.html</pre>" +  " permanent domain.com www.domain.com\n" +  " ab.domain.org http://my.university.edu/~me/ab/%p\n" +  " bc.domain.com %u/bc/%p%q\n" +  " default %u/serverlist.html</pre>"    "<p><strong>There are several patterns that can be used " -  "in the 'to' field:</strong></p>\n" +  "in the 'target' field:</strong></p>\n"    "<dl>\n"    "<dh><tt>%p</tt> (Path)</dh>\n" -  "<dd>A <tt>%p</tt> in the 'to' field will be replaced with the full " +  "<dd>A <tt>%p</tt> in the 'target' field will be replaced with the full "    "path of the request.</dd>\n"    "<dh><tt>%q</tt> (Query)</dh>\n" -  "<dd>A <tt>%q</tt> in the 'to' field will be replaced with the " +  "<dd>A <tt>%q</tt> in the 'target' field will be replaced with the "    "query string (if any). Note that the query string will be prepended " -  "with <tt>?</tt> if there's no <tt>?</tt> earlier in the 'to' " +  "with <tt>?</tt> if there's no <tt>?</tt> earlier in the 'target' "    "field, and with <tt>&amp;</tt> otherwise. Note also that for "    "internal redirects the query variables are passed along to "    "the redirect target without any need to use <tt>%q</tt>.</dd>\n"    "<dh><tt>%u</tt> (URL)</dh>\n" -  "<dd>A <tt>%u</tt> in the 'to' field will be replaced with this " +  "<dd>A <tt>%u</tt> in the 'target' field will be replaced with this "    "server's URL (useful if you want to send an external redirect "    "instead of doing an internal one).</dd>\n"    "</dl>\n" -  +  "<p>If the first string on the line is 'permanent', the http return " +  "code is 301 (moved permanently) instead of 302 (found).</p> "    "<p>Internal redirects will always have the path and query variables "    "added, whether you use <tt>%p</tt> and/or <tt>%q</tt> or not. "    "However for HTTP redirects <tt>%p</tt> and/or <tt>%q</tt> are "    "mandatory if you want to propagate the path and/or query variables "    "respectively. <strong><tt>default</tt> will never add a path, "    "even if <tt>%p</tt> is present.</strong> "    "In fact if <tt>%p</tt> is included it will "    "just stay and probably not produce the expected result.</p>"    );       defvar("ignorepaths",    Variable.StringList( ({ "/_internal/", "/__internal/", "/internal-roxen-", -  "/roxen-files/", "/edit", "/__frame/" +  "/roxen-files/", "/edit", "/__ie/", "/yui/",    }), 0, "Ignore paths",    "A list of path prefixes that should not be redirected. "    "Useful for making global images work in sub sites." ));    defvar("ignorevariables",    Variable.StringList( ({ "__force_path", "__sb_force_login" }),    0, "Ignore form variables",    "A list of form variables. If one of the form variables "    "is set, the request will not be redirected."    "Useful for making login redirects to / work in sub "    "sites." ));
Roxen.git/server/modules/filters/hostredirect.pike:139:    host = (host / ":")[0]; // Remove port number    host = (host / "\0")[0]; // Spoof protection.    dwerror("HR: get_host: %O\n", host);    return host;   }      string get_protocol(string ignored, RequestID id)   {    string prot = lower_case((id->prot/"/")[0]);    // Check if the request is done via https. -  if(id->my_fd && id->my_fd && id->my_fd->SSLConnection) +  if(id->my_fd && id->my_fd->get_peer_certificate_info && +  id->my_fd->query_connection())    prot = "https";    dwerror("HR: get_protocol: %O\n", prot);    return prot;   }      string get_port(string ignored, RequestID id)   {    string port = id->my_fd && id->my_fd->query_address &&    (id->my_fd->query_address(1) / " ")[1];   
Roxen.git/server/modules/filters/hostredirect.pike:277:    // Don't redirect if the prot/host/port is the same and the    // beginning of the path is already correct.    if(has_prefix(cur_uri->path, to_uri->path) &&    cur_uri->scheme == to_uri->scheme &&    cur_uri->host == to_uri->host &&    cur_uri->port == to_uri->port)    {    return 0;    }    }; -  to=replace(to, ({ "\000", " " }), ({"%00", "%20" })); +  to = Roxen.http_encode_invalids(to);    dwerror("HR: %O -> %O (http redirect)\n", id->not_query, to);    return Roxen.http_low_answer( return_code,    "See <a href='"+to+"'>"+to+"</a>")    + ([ "extra_heads":([ "Location":to, ]) ]);    } else {    // Internal redirect       if(has_prefix(id->not_query, to_prefix)) {    // Already have the correct beginning...    return 0;    }       // if the default file contains images, they will not be found,    // because they will be redirected just like the original request    // without id->not_query. maybe it's possible to check the referer    // and if it matches patterns["default"] add the id->not_query after all.    if(to[0] != '/')    to = "/"+ to; -  if(host != "default" && strlen(to) > 1 && to[-1] == '/') +  if((host != "default") && !path && strlen(to) > 1 && to[-1] == '/')    to = to[0..strlen(to)-2];    if((host != "default") && !path )    to +=id->not_query;       dwerror("HR: %O -> %O (internal redirect)\n", id->not_query, to);       id->misc->host_redirected = 1; -  +  if (!id->misc->redirected_raw_url) { +  id->misc->redirected_raw_url = id->raw_url; +  id->misc->redirected_not_query = id->not_query; +  }    id->not_query = id->scan_for_query( to );    id->raw_url = Roxen.http_encode_invalids(to);    //if we internally redirect to the proxy,    //the proxy checks the raw_url for the place toget,    //so we have to update the raw_url here too, or    //we need to patch the proxy-module    return 0;    }   }