The following escaping behavior should be implemented: https://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#quoting
Created attachment 33544 [details] Let backslashes escape characters This will enable escaping (quoting) by using an backslash. Apart from this, it will enable escaping the percent sign by using %%. It also fixes a bug, when % was not followed by a digit or a curly brace. The functionality for %% should probably not be added. Documentation for the quotation feature is missing, too.
Normally % should be escaped with \% according to the documentation, not anything else.
This looks fixed by r1729730
Fixed in 9.0.0.M4 and 8.0.33.
It seems not fixed at 8.5.20 - \%20 was converted to %2520
(In reply to Stefan from comment #5) > It seems not fixed at 8.5.20 - \%20 was converted to %2520 What happens when you don't place the backslash in front of %20?
With backslash --- RewriteRule ^/context/id=(\w{3})(\d{12}).*$ %{CONTEXT_PATH}/site/form/?mode=search&key=Help\%20Desk&key2="$1$2" [NC,NE,L] RESULT - wrong URL fqdn/context/site/form/?mode=search&key=Help%2520Desk&key2="1234" Without backslash --- RewriteRule ^/context/id=(\w{3})(\d{12}).*$ %{CONTEXT_PATH}/site/form/?mode=search&key=Help%20Desk&key2="$1$2" [NC,NE,L] RESULT - Exception 10-Nov-2017 16:03:52.643 SCHWERWIEGEND [http-nio-80-exec-28] org.apache.coyote.http11.Http11Processor.service Error processing request java.lang.NullPointerException at org.apache.catalina.valves.rewrite.Substitution$RewriteCondBackReferenceElement.evaluate(Substitution.java:65) at org.apache.catalina.valves.rewrite.Substitution.evaluate(Substitution.java:269) at org.apache.catalina.valves.rewrite.RewriteRule.evaluate(RewriteRule.java:135) at org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:313) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1457) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)
When a RewriteRule such as RewriteRule /abc /r%20 is used, the %2 will be interpreted as a back-reference to a match. Your condition has two matching groups, but %2 would reference back to a third group, that does not exist. That's where the NPE comes from. (I left out the matching groups for simplicity.) If you escape the % with a backslash, it will be put verbatim in the (url decoded) rewritten path and finally url encoded into %25. What you need is a way to encode %20 into a static string - that is a space in this case, right?
Can you try and add an R flag to the variant that has the escaped percent sign?
That's right, I missed %2 as a back-reference. Adding a R flag does the job. I don't know why and seems a bit tricky, but it solves the problem. thank you very much!
Re-resolving this as FIXED since the original issue is fixed. %20 is a special case. The rules are based on decoded URIs. The problem is that space is a delimiter for the rules so while there are ways (via regular expressions) to use space in a pattern, there isn't a way to include a space in the substitution. One option would be to decode the rules but that would likely break existing rules. Using R is probably the best work-around if you need to include a space in the re-written URI.