ProxyPassReverse を RewriteRule のオプションにするパッチ
なんか https + リバースプロキシで subversion 使っていたら COPY メソッドでこけて 502 Bad Gateway になってなんじゃこれはとあれこれしているうちにできたパッチ (against httpd-2.2.4)。
ProxyPassReverse でできるよ、というのは半分正解。RewriteRule は perdir コンテキストだが ProxyPassReverse は vhost dir (訂正: 2007/10/01) コンテキストだ。RewriteRule に [P] オプションを指定して便利なのってやはり .htaccess に書けるというところだと思う。
使いかたは PR オプションを RewriteRule に指定してください。[P,PR] みたく。
diff -ur httpd-2.2.4.orig/modules/mappers/mod_rewrite.c httpd-2.2.4/modules/mappers/mod_rewrite.c --- httpd-2.2.4.orig/modules/mappers/mod_rewrite.c 2006-09-15 22:19:25.000000000 +0900 +++ httpd-2.2.4/modules/mappers/mod_rewrite.c 2007-07-16 09:23:40.000000000 +0900 @@ -145,6 +145,7 @@ #define RULEFLAG_NOESCAPE 1<<11 #define RULEFLAG_NOSUB 1<<12 #define RULEFLAG_STATUS 1<<13 +#define RULEFLAG_PROXYREVERSE 1<<14 /* return code of the rewrite rule * the result may be escaped - or not @@ -746,7 +747,7 @@ /* * strip 'http[s]://ourhost/' from URI */ -static void reduce_uri(request_rec *r) +static int reduce_uri(request_rec *r) { char *cp; apr_size_t l; @@ -799,10 +800,11 @@ if (ap_matches_request_vhost(r, host, port)) { rewritelog((r, 3, NULL, "reduce %s -> %s", r->filename, url)); r->filename = apr_pstrdup(r->pool, url); + return 1; } } - return; + return 0; } /* @@ -3278,6 +3280,10 @@ || !strcasecmp(key, "assthrough")) { /* passthrough */ cfg->flags |= RULEFLAG_PASSTHROUGH; } + else if (((*key == 'R' || *key == 'r') && !key[1]) + || !strcasecmp(key, "roxyReverse")) { + cfg->flags |= RULEFLAG_PROXYREVERSE; + } else { ++error; } @@ -3811,6 +3817,43 @@ rewritelog((r, 2, ctx->perdir, "forcing proxy-throughput with %s", r->filename)); + if (p->flags & RULEFLAG_PROXYREVERSE) { + static const char *transform_hdrs[] = { + "Location", + "Content-Location", + "URI", + "Destination", + "Set-Cookie", + NULL + }; + int i ; + rewrite_ctx _ctx = *ctx; + request_rec _r = *_ctx.r; + _r.path_info = NULL; + _ctx.r = &_r; + + for (i = 0; transform_hdrs[i]; ++i) { + const char *val = apr_table_get(ctx->r->headers_in, + transform_hdrs[i]); + if (!val) + continue; + _r.filename = (char *)val; + if (reduce_uri(&_r) && ctx->perdir) { + apr_size_t rlen = strlen(ctx->uri), alen = strlen(r->uri); + if (alen > rlen) + _r.filename += alen - rlen; + } + p->flags &= ~RULEFLAG_PROXYREVERSE; + if (apply_rewrite_rule(p, &_ctx)) + rewritelog((r, 2, ctx->perdir, + "rewrite location header %s: %s -> %s", + transform_hdrs[i], val, _r.filename)); + p->flags |= RULEFLAG_PROXYREVERSE; + apr_table_setn(ctx->r->headers_in, transform_hdrs[i], + _r.filename); + } + } + r->filename = apr_pstrcat(r->pool, "proxy:", r->filename, NULL); return 1; }
http://voltex.jp/patches/mod_rewrite_proxy_reverse-20070716.patch.diff.gz