You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Hendrik Harms <he...@gmail.com> on 2022/03/01 08:34:05 UTC

Re: [users@httpd] ProxyPass option mapping=servlet hurts mod_rewrite

Hi Yann

Anyway, could you please try the attached patch and see if it works for you?
>

I have applied your patch to my httpd-2.4.52 and created two test cases.
One with a simple RewriteRule and a second one using a RewriteMap.
Both are working fine. :-)

Test logs attached: mod_rewrite_vs_proxy_pre_trans-v2_test_log.txt

Thank you for the very quick response!
Regards,
Hendrik

-- 
----------------------------------------------------------
Hendrik Harms
mail: hendrik.harms@gmail.com

Re: [users@httpd] ProxyPass option mapping=servlet hurts mod_rewrite

Posted by Yann Ylavic <yl...@gmail.com>.
Hi Hendrik;

>
> >  RewriteRule "^/alpha/gobeta/(.*)$"  http://server2.localnet:8080/beta/$1 [P]
> If the RewriteRule is specified with the option [P] it works correctly. The request
> https://example.ort/alpha/gobeta/anypath is sent to the beta backend.
>
> > Also, it seems to me that "/alpha/gobeta/.." is not matched by the
> > "ProxyPass /beta ...", so it really boils down to the RewriteRule only.
> > What do you expect here?
> But when I take the option [PT] the behavior changes. Without "mapping=servlet" the
> request is sent to the beta backend. With "mapping=servlet" the request is replied
> by a 404 NOT FOUND.  -  Is this change of behavior acceptable?

I don't think that it's a change in behaviour, what changes is
ProxyPass with and without mapping= with regard to the following
matches (RewriteRule or <Location[Match]>), but existing ProxyPass
without mapping= and RewriteRules work like before.

The ProxyPass mapping=servlet has to apply some special normalization
to the request uri-path (notably stripping path parameters defined by
the servlet specification) so that further mapping in httpd works
according to the backend application(s) server (e.g. Tomcat), so that
authn/authz in <Location[Match]> and RewriteRules have the same path
representation as the backend and can enforce relevant access or
forwarding rules. Still the potential path ";parameters" from the
original uri-path need to be forwarded to the backend since they will
finally be consumed by the applications (which is the point of the
servlet specification).

So there is no way for a RewriteRule happening *after* this
normalization to be able to modify the uri-path (e.g. with a [PT]
rule) without losing everything stripped by the normalization, while
sending the resulting uri-path to the backend (as I proposed with a
[P] rule) would be quite useless actually.
I'm afraid that the interaction between a ProxyPass mapping=servlet
and the following RewriteRules is then limited to non-rewrite rules or
rewrite rules that "break" the proxying (like [F] or [R] or internal
redirects to a local resource), which is is what r1898509 addresses,
but reconstructing a servlet uri-path based on the original one and
random regex substitutions to the path segments is outside the scope
of httpd or mod_proxy modules (this is also why there is no
ProxyPassMatch mapping=servlet so far), at least I wouldn't engage in
such dev but since httpd is a participative project anyone is free to
propose a patch ;)

> Maybe it is acceptable cause the option [PT] is the wrong choice if I want the request
> to be replied by the proxied beta backend.
> But some inexperienced admins will run into trouble. (like me ;-)

Admins have the choice to use a ProxyPass with mapping=servlet which
does simple/prefix rewrite like in:
  ProxyPass /alpha/gobeta http://server2.localnet:8080/beta mapping=servlet
which should be enough for most use cases (including your simple
example) without any RewriteRule (besides eventually to prevent this
ProxyPass from applying by using some further [R], [F] or (internal)
redirect rules, or yet some <Location[Match]> policies);

Or admins can use a ProxyPass[Match] without mapping=servlet and then
RewriteRules/<Location[Match]>, but then they need to take path
parameters into account in the regexes (which is not very practical if
not impossible in some cases).

Best of both worlds where httpd does application specific
normalization and restores it across all possible rewrites is not
something someone has proposed to implement so far..


Regards;
Yann.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] ProxyPass option mapping=servlet hurts mod_rewrite

Posted by Hendrik Harms <he...@gmail.com>.
Hi Yann,

>  RewriteRule "^/alpha/gobeta/(.*)$"  http://server2.localnet:8080/beta/$1
[P]
If the RewriteRule is specified with the option [P] it works correctly. The
request
https://example.ort/alpha/gobeta/anypath is sent to the beta backend.

> Also, it seems to me that "/alpha/gobeta/.." is not matched by the
> "ProxyPass /beta ...", so it really boils down to the RewriteRule only.
> What do you expect here?
But when I take the option [PT] the behavior changes. Without
"mapping=servlet" the
request is sent to the beta backend. With "mapping=servlet" the request is
replied
by a 404 NOT FOUND.  -  Is this change of behavior acceptable?
Maybe it is acceptable cause the option [PT] is the wrong choice if I want
the request
to be replied by the proxied beta backend.
But some inexperienced admins will run into trouble. (like me ;-)

Regards,
Hendrik

Re: [users@httpd] ProxyPass option mapping=servlet hurts mod_rewrite

Posted by Yann Ylavic <yl...@gmail.com>.
On Thu, Mar 3, 2022 at 12:24 PM Yann Ylavic <yl...@gmail.com> wrote:
>
> Hi Hendrik;
>
> >
> > after reading your commit comment in https://svn.apache.org/r1898509  I realised that one important test case is missing:
> > What happens if mod_rewrite manipulates the URL of a target that is proxied with the option mapping=servlet?
> >
> > From my point of view this test case fails.  :-(
> >    ProxyPass /beta   http://server2.localnet:8080/beta  mapping=servlet
> >    RewirteRule "^/alpha/gobeta"  /beta [PT,L]
> > Calling  https://example.org/alpha/gobeta/test sends back a  404 instead the beta content.
> > In this case mod_proxy could not map the requests to the beta backend.
>
> Given that "ProxyPass ... mapping=servlet" applies before the
> RewriteRule, I don't see how you can have a RewriteRule [PT] that
> either "cancels" the ProxyPass (like in your RewriteMap examples)
> and/or that rewrites the uri but keeps proxying (like in the above
> example).
>
> Isn't:
>  RewriteRule "^/alpha/gobeta/(.*)$"  http://server2.localnet:8080/beta/$1 [P]
> (or alike) what you are looking for in the above example?

Also, it seems to me that "/alpha/gobeta/.." is not matched by the
"ProxyPass /beta ...", so it really boils down to the RewriteRule
only.
What do you expect here?

>
> Regards;
> Yann.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] ProxyPass option mapping=servlet hurts mod_rewrite

Posted by Yann Ylavic <yl...@gmail.com>.
Hi Hendrik;

>
> after reading your commit comment in https://svn.apache.org/r1898509  I realised that one important test case is missing:
> What happens if mod_rewrite manipulates the URL of a target that is proxied with the option mapping=servlet?
>
> From my point of view this test case fails.  :-(
>    ProxyPass /beta   http://server2.localnet:8080/beta  mapping=servlet
>    RewirteRule "^/alpha/gobeta"  /beta [PT,L]
> Calling  https://example.org/alpha/gobeta/test sends back a  404 instead the beta content.
> In this case mod_proxy could not map the requests to the beta backend.

Given that "ProxyPass ... mapping=servlet" applies before the
RewriteRule, I don't see how you can have a RewriteRule [PT] that
either "cancels" the ProxyPass (like in your RewriteMap examples)
and/or that rewrites the uri but keeps proxying (like in the above
example).

Isn't:
 RewriteRule "^/alpha/gobeta/(.*)$"  http://server2.localnet:8080/beta/$1 [P]
(or alike) what you are looking for in the above example?

Regards;
Yann.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] ProxyPass option mapping=servlet hurts mod_rewrite

Posted by Hendrik Harms <he...@gmail.com>.
Hi Yann,

after reading your commit comment in https://svn.apache.org/r1898509  I
realised that one important test case is missing:
What happens if mod_rewrite manipulates the URL of a target that is proxied
with the option mapping=servlet?

From my point of view this test case fails.  :-(
   ProxyPass /beta   http://server2.localnet:8080/beta  mapping=servlet
   RewirteRule "^/alpha/gobeta"  /beta [PT,L]
Calling  https://example.org/alpha/gobeta/test sends back a  404 instead
the beta content.
In this case mod_proxy could not map the requests to the beta backend.

more details in attachment: mod_rewrite_vs_proxy_pre_trans-v2_test_log2.txt

regards,
Hendrik

Re: [users@httpd] ProxyPass option mapping=servlet hurts mod_rewrite

Posted by Yann Ylavic <yl...@gmail.com>.
Hi,

>
> I have applied your patch to my httpd-2.4.52 and created two test cases.
> One with a simple RewriteRule and a second one using a RewriteMap.
> Both are working fine. :-)

Thanks for testing! Now checked in https://svn.apache.org/r1898509

Regards;
Yann.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org