Commit 8014b9b8 authored by Jim Jagielski's avatar Jim Jagielski
Browse files

i ProxySCGIInternalRedirect with alternate response header


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1678234 13f79535-47bb-0310-9956-ffa450edef68
parent b48dd0b0
Loading
Loading
Loading
Loading
+5 −0
Changes for CHANGES: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@ Changes with Apache 2.4.13
     rfc822Name and dNSName into SSL_{CLIENT,SERVER}_SAN_{Email,DNS}_n
     environment variables. Also addresses PR 57207. [Kaspar Brand]

  *) mod_proxy_scgi: ProxySCGIInternalRedirect now allows an alternate
     response header to be used by the application, for when the application
     or framework is unable to return Location in the internal-redirect
     form.  [Jeff Trawick]

  *) mpm_event: Allow for timer events duplicates. [Jim Jagielski, Yann Ylavic]

  *) mod_proxy, mod_ssl, mod_cache_socache, mod_socache_*: Support machine
+0 −9
Changes for STATUS: 0 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -105,15 +105,6 @@ RELEASE SHOWSTOPPERS:
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
  [ start all new proposals below, under PATCHES PROPOSED. ]

  *) mod_proxy_scgi: ProxySCGIInternalRedirect with alternate response header
     trunk patch: 1674510
     2.4.x patch: trunk works (modulo CHANGES)
       This also needs <compatibility> in the doc moved down like in 
           http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_proxy_scgi.xml?r1=1674510&r2=1674530&diff_format=h
       and the version edited :)
     Pre-edited: http://people.apache.org/~trawick/r1674510-to-2.4.x.txt
     +1: trawick, jim, ylavic

   * mod_dav: Avoid some work that is unnecessary and often very time consuming.
     This helps mitigate Subversion issue #4531:
     http://subversion.tigris.org/issues/show_bug.cgi?id=4531
+13 −5
Changes for docs/manual/mod/mod_proxy_scgi.xml: 13 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -145,27 +145,35 @@ ProxySCGISendfile X-Send-Static
<name>ProxySCGIInternalRedirect</name>
<description>Enable or disable internal redirect responses from the
backend</description>
<syntax>ProxySCGIInternalRedirect On|Off</syntax>
<syntax>ProxySCGIInternalRedirect On|Off|<var>Headername</var></syntax>
<default>ProxySCGIInternalRedirect On</default>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context></contextlist>
<compatibility>The <var>Headername</var> feature is available in version
2.4.13 and later</compatibility>

<usage>
    <p>The <directive>ProxySCGIInternalRedirect</directive> enables the backend
    to internally redirect the gateway to a different URL. This feature
    originates in <module>mod_cgi</module>, which internally redirects the
    response if the response status is <code>OK</code> (<code>200</code>) and
    the response contains a <code>Location</code> header and its value starts
    with a slash (<code>/</code>). This value is interpreted as a new local
    URL that Apache httpd internally redirects to.</p>
    the response contains a <code>Location</code> (or configured alternate
    header) and its value starts with a slash (<code>/</code>). This value is 
    interpreted as a new local URL that Apache httpd internally redirects to.</p>

    <p><module>mod_proxy_scgi</module> does the same as
    <module>mod_cgi</module> in this regard, except that you can turn off the
    feature.</p>
    feature or specify the use of a header other than <code>Location</code>.</p>

    <example><title>Example</title>
    <highlight language="config">
    ProxySCGIInternalRedirect Off

# Django and some other frameworks will fully qualify "local URLs"
# set by the application, so an alternate header must be used.
&lt;Location /django-app/&gt;
    ProxySCGIInternalRedirect X-Location
&lt;/Location&gt;
    </highlight>
    </example>
</usage>
+47 −10
Changes for modules/proxy/mod_proxy_scgi.c: 47 added lines, 10 removed lines.
Original line number Diff line number Diff line
@@ -64,10 +64,12 @@ typedef struct {

const char *scgi_sendfile_off = "off";
const char *scgi_sendfile_on = "X-Sendfile";
const char *scgi_internal_redirect_off = "off";
const char *scgi_internal_redirect_on = "Location";

typedef struct {
    const char *sendfile;
    int internal_redirect;
    const char *internal_redirect;
} scgi_config;


@@ -417,11 +419,29 @@ static int pass_response(request_rec *r, proxy_conn_rec *conn)
        }
    }

    if (conf->internal_redirect && r->status == HTTP_OK) {
        location = apr_table_get(r->headers_out, "Location");
    if (r->status == HTTP_OK 
        && (!conf->internal_redirect /* default === On */
            || conf->internal_redirect != scgi_internal_redirect_off)) {
        short err = 1;
        const char *location_header = conf->internal_redirect ? 
            conf->internal_redirect : scgi_internal_redirect_on;

        location = apr_table_get(r->err_headers_out, location_header);
        if (!location) {
            err = 0;
            location = apr_table_get(r->headers_out, location_header);
        }
        if (location && *location == '/') {
            scgi_request_config *req_conf = apr_palloc(r->pool,
                                                       sizeof(*req_conf));
            if (strcasecmp(location_header, "Location")) {
                if (err) {
                    apr_table_unset(r->err_headers_out, location_header);
                }
                else {
                    apr_table_unset(r->headers_out, location_header);
                }
            }
            req_conf->location = location;
            req_conf->type = scgi_internal_redirect;
            ap_set_module_config(r->request_config, &proxy_scgi_module,
@@ -564,8 +584,8 @@ static void *create_scgi_config(apr_pool_t *p, char *dummy)
{
    scgi_config *conf=apr_palloc(p, sizeof(*conf));

    conf->sendfile = NULL;
    conf->internal_redirect = -1;
    conf->sendfile = NULL; /* === default (off) */
    conf->internal_redirect = NULL; /* === default (on) */

    return conf;
}
@@ -576,7 +596,7 @@ static void *merge_scgi_config(apr_pool_t *p, void *base_, void *add_)
    scgi_config *base=base_, *add=add_, *conf=apr_palloc(p, sizeof(*conf));

    conf->sendfile = add->sendfile ? add->sendfile: base->sendfile;
    conf->internal_redirect =   (add->internal_redirect != -1)
    conf->internal_redirect = add->internal_redirect
                              ? add->internal_redirect
                              : base->internal_redirect;
    return conf;
@@ -601,16 +621,33 @@ static const char *scgi_set_send_file(cmd_parms *cmd, void *mconfig,
}


static const char *scgi_set_internal_redirect(cmd_parms *cmd, void *mconfig,
                                              const char *arg)
{
    scgi_config *conf = mconfig;

    if (!strcasecmp(arg, "Off")) {
        conf->internal_redirect = scgi_internal_redirect_off;
    }
    else if (!strcasecmp(arg, "On")) {
        conf->internal_redirect = scgi_internal_redirect_on;
    }
    else {
        conf->internal_redirect = arg;
    }
    return NULL;
}


static const command_rec scgi_cmds[] =
{
    AP_INIT_TAKE1("ProxySCGISendfile", scgi_set_send_file, NULL,
                  RSRC_CONF|ACCESS_CONF,
                  "The name of the X-Sendfile peudo response header or "
                  "The name of the X-Sendfile pseudo response header or "
                  "On or Off"),
    AP_INIT_FLAG("ProxySCGIInternalRedirect", ap_set_flag_slot,
                 (void*)APR_OFFSETOF(scgi_config, internal_redirect),
    AP_INIT_TAKE1("ProxySCGIInternalRedirect", scgi_set_internal_redirect, NULL,
                  RSRC_CONF|ACCESS_CONF,
                 "Off if internal redirect responses should not be accepted"),
                  "The name of the pseudo response header or On or Off"),
    {NULL}
};