【问题标题】:Altering the URI value that all subsequent RewriteRule's use to match against更改所有后续 RewriteRule 用来匹配的 URI 值
【发布时间】:2017-03-24 13:32:18
【问题描述】:

我有一个生产和开发服务器,它们是彼此的克隆。 我还有一个处理所有传入的 apache24 反向代理服务器 根据 URI 从不同的后端服务器请求和代理内容。

我希望代理从我们的开发服务器中提取内容,如果 URI 以'/test'开头,例如:https://ourdomain.com/test/some/app/index.php?foo=bar

但是,我不想为所有内容创建重复的规则,一个用于 生产和测试,所以我试图弄清楚如何完成这个 每个重写规则都有一个规则,这些规则从 后端服务器

除了如何有效地删除“/test”之外,我已经弄清楚了一切 RewriteCond、RewriteRule 和 都用于匹配。

我正在寻找的最终结果是:

代理服务器 https://ourdomain.com/some/app/index.php?foo=bar 的传入请求这样做:

RewriteRule ^/some$ /some/ [R=301,L]
<Location "/some/">
ProxyPass            https://BackendProductionHost/some/app/index.php?foo=bar
ProxyPassReverse    https://BackendProductionHost/some/app/index.php?foo=bar
</Location>

代理服务器 https://ourdomain.com/test/some/app/index.php?foo=bar 的传入请求执行此操作:

RewriteRule ^/test/some$ /test/some/ [R=301,L]
<Location "/test/some/">
ProxyPass            https://BackendDevelopmentHost/some/app/index.php?foo=bar
ProxyPassReverse    https://BackendDevelopmentHost/some/app/index.php?foo=bar
## Note that '/test' is NOT part of the URI sent to the backend development server
</Location>

但只使用一组规则来处理这两种情况。

为什么?我们有很多不同的后端服务器,每一个都有一个 开发克隆。我正在努力减少规则的重复。

以下是我所拥有的:

## fyi - These are located in a <VirtaulHost> .. and not a .htaccess, if it matters


RewriteEngine On
ProxyPassInterpolateEnv On

## Set an environment variable named 'serverhost' to the production server
## host value (BackendProductionHost)
##    Note:
##      -- I have to use 'SetEnvIfExpr' because "The SetEnv directive runs
##         late during request processing meaning that directives such as
##         SetEnvIf and RewriteCond will not see the variables set with it."
##      -- The expression "1==1" always evaluates to true which allows me
##         to set a default value.    

SetEnvIfExpr "1==1" serverhost=BackendProductionHost


## Change the 'serverhost' env value to the development server host value
## If the URI begins with a path of '/test', eg:

RewriteCond %{REQUEST_URI} ^/test
RewriteRule .* - [E=serverhost:BackendDevelopmentHost]


## Remove /test from the URI      
RewriteCond %{REQUEST_URI} ^/test
#RewriteRule ^/test(.*)$ $1
RewriteRule ^/test(.*)$ $1 [E=REQUEST_URI:$1]
##   -- Neither of the above change the URI value that RewriteCond, RewriteRule,
##      and <Location ..> use for their matching,  IS THIS POSSIBLE?


## If the URI used for the matching can be changed to remove '/test' when it
## is present then the following would work:


RewriteRule ^/some$ /some/ [R=301,L]
<Location /some/>
    ProxyPass            https://${serverhost}/some/app/ interpolate
    ProxyPassReverse    https://${serverhost}/some/app/ interpolate
</Location>
##  The rules above only work for the production URL and never the test URL
##  (no request sent to BackendDevelopmentServer)

## I have also tried the following:
ProxyPassMatch  "^(/test)?/some/"  https://${serverhost}/some/app/ interpolate

## The rule above works for the production URL and at least generates a
## request to the back end development server but the request from the proxy
## to the dev server looks like:
## "GET /some/app//test/some/index.php?foo=bar HTTP/1.1"

我正在尝试做的事情是否可行,或者我应该坚持使用一组重复的测试规则??

【问题讨论】:

    标签: apache mod-rewrite proxy


    【解决方案1】:

    我想出了如何实现我的要求。简而言之,下面的配置允许我们像往常一样浏览生产网站,并通过在 URL 的域部分后添加“/test”来浏览到它的开发对应网站。

    例如:

    https://our_public_domain.example/somewebstuff/thing.htm

    https://our_public_domain.example/test/somewebstuff/thing.htm

    RewriteEngine On
    ProxyPassInterpolateEnv On
    
    # --------------------------------------------------------------------------
    # - We are creating some environement variables and assigning default values
    # - pertaining to a production environment.  If the URI begins with '/test/'
    # - then we are overwriting the environment variables with variables
    # - pertaining to a test environment.
    # --------------------------------------------------------------------------
    
    
    # - set default environment variables to production values
    # - Note that the 'test' variable is set to nothing
    SetEnvIfExpr "1==1" lnxhost=192.168.1.1
    SetEnvIfExpr "1==1" winhost=prodserver.example
    SetEnvIfExpr "1==1" apihost=another.example/some/production/enpoint/base
    SetEnvIfExpr "1==1" test=
    
    
    # - override environment variable values to development values if URI matches: ^/test/
    # - phrased differently, if the request was *not* ^/test/, skip these next four rules aka: [S=4]
    RewriteCond %{REQUEST_URI} !^/test/
    RewriteRule  .?  -  [S=4]
    RewriteRule .* - [E=lnxhost:192.168.1.100]
    RewriteRule .* - [E=winhost:devserver.example]
    RewriteRule .* - [E=apihost:another.example/some/development/enpoint/base]
    RewriteRule .* - [E=test:/test]
    
    
    # /somewebstuff is proxied to the lnxhost backend server 
    RewriteRule ^(/test)?/somewebstuff$ $1/somewebstuff/ [R=301,L]
    ProxyPassMatch  "^(?:/test)?/somewebstuff/(.*)$"  "https://${lnxhost}/somewebstuff/$1" interpolate
    <LocationMatch "(/test)?/somewebstuff/">
        ProxyPassReverse    https://${lnxhost}${test}/somewebstuff/ interpolate
    </LocationMatch>
    RewriteRule ^(/test)?/somewebstuff/ "-" [L]
    
    
    # /someapistuff is proxied to the apihost backend server
    RewriteRule ^(/test)?/someapistuff$ $1/someapistuff/ [R=301,L]
    ProxyPassMatch  "^(?:/test)?/someapistuff/(.*)$"  "https://${apihost}/$1" interpolate
    # Note: ProxyPassReverse is not needed for the someapistuff API usage
    RewriteRule ^(/test)?/someapistuff/ "-" [L]
    
    
    # anything not handled by a rule above is proxied by default to the winhost backend server
    ProxyPassMatch  "^(?:/test)?/(.*)$"  "https://${winhost}/$1" interpolate
    <LocationMatch "(/test)?/">
        ProxyPassReverse    https://${winhost}${test}/ interpolate
    </LocationMatch>
    

    我还对我正在使用的语法进行了大量注释说明:

    # - Any URI's that are exactly 'example' or 'test/example' (without a trailing slash)
    # - are redirected to 'example/' or 'test/example/' (with a trailing slash)
    # - The 'L' flag stops any further rule prosessing
    #RewriteRule ^(/test)?/example$ $1/example/ [R=301,L]
    
    # - Content is retrieved from the backend content location for URI's that
    # - begin with 'example/' or 'test/example/':
    #ProxyPassMatch  "^(?:/test)?/example/(.*)$"  "https://${lnxhost}/backend/content/$1" interpolate
    
    # - The locationMatch and ProxyPassReverse allow for proper proxy handling of redirects
    # - sent from the backend server in both a test and production context:
    #<LocationMatch "(/test)?/example/">
    #    ProxyPassReverse    https://${lnxhost}${test}/backend/content/ interpolate
    #</LocationMatch>
    
    # - Stop any further processing of rules
    #RewriteRule ^(/test)?/example/ "-" [L]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多