Bug 49746 - mod_rewrite urlencode option
Summary: mod_rewrite urlencode option
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_rewrite (show other bugs)
Version: 2.5-HEAD
Hardware: All All
: P4 enhancement with 2 votes (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
Keywords: PatchAvailable
Depends on:
Reported: 2010-08-12 15:07 UTC by jhmartin@toger.us
Modified: 2018-08-24 07:57 UTC (History)
1 user (show)

Add urlencode function. (938 bytes, patch)
2016-01-06 23:48 UTC, Philippe Lantin
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description jhmartin@toger.us 2010-08-12 15:07:43 UTC
I suggest adding a flag to mod_rewrite to optionally url-encode captured values.  

Something like:
RewriteRule /(.*) /some/other/url=&target=http://www.example.com/handler?foo=bar&target=$1&zed=zee [UE]

where UE causes the (.*) value to be urlencoded before being placed into $1.

This handles cases where you want to rewrite the request url into an argument of another url, and the requested url might have a multivalue query string in it.

Comment 1 Dan Poirier 2010-08-12 15:28:17 UTC
This feature is already available.


Look for the internal map for "escape".
Comment 2 jhmartin@toger.us 2010-08-12 16:24:06 UTC
This does not appear to work for escaping query-string arguments, as the & sign is not being escaped:

(5) map lookup OK: map=escape key=foo=bar&zed=zee&fib/fib -> val=foo=bar&zed=zee&fib/fib

This is with
Apache/2.2.15 (Unix) mod_ssl/2.2.15 OpenSSL/1.0.0 

I'm using
RewriteMap escape int:escape
${escape:%{QUERY_STRING}} in the rewrite rule.

wget -O- "http://www.example.com/?foo=bar&zed=zee&fib/fib"

Perhaps there is use in adding another map function with a more comprehensive translation list?
Comment 3 jhmartin@toger.us 2010-08-13 12:03:13 UTC
Since it looks like the escape map really just calls ap_escape_uri, which is a macro for ap_escape_os_path; how about a htmlescape map that calls ap_escape_html?
Comment 4 Bob Ionescu 2010-08-14 04:55:07 UTC
> where UE causes the (.*) value to be urlencoded before being placed into $1.

That's already done by the B flag.
Comment 5 jhmartin@toger.us 2010-08-25 12:44:56 UTC
Ah didn't see that (was looking at 2.0).  Thank you.
Comment 6 jhmartin@toger.us 2010-08-25 13:34:31 UTC
I'm sorry, have to reopen again.  Neither int:escape or [B] handle the case where the original request had a query string, and I now want to package up the entire original request and pass it in the query string.


/foo/bar?zed=zee&ivy=true  Should be come /some/other/url?target=/foo/bar%3Fzed=zee%26ivy=true, or something along those lines.

With the current mechanisms, the & in the query string is not escaped by either int:escape or [B] (as there is no way to backreference query_string), meaning the servlet thinks everything after the first name/value pair is a separate argument and not part of target.

RewriteMap escape int:escape
RewriteRule /(.*) /some/url?resource=fibble&target=http://%{HTTP_HOST}/$1?${escape:%{QUERY_STRING}} [B,PT,L]

(2) init rewrite engine with requested uri /foo/bar
(3) applying pattern '/(.*)' to uri '/foo/bar'
(5) escaping backreference 'foo/bar' to 'foo%2fbar'
(5) map lookup OK: map=escape key=zed=zee&ivy=true -> val=zed=zee&ivy=true
(2) rewrite '/foo/bar' -> '/some/url?resource=fibble&target='
(3) split uri=/some/url?resource=fibble&target= -> uri=/some/url, args=resource=fibble&target=
(2) forcing '/some/url' to get passed through to next API URI-to-filename handler
Comment 7 Philippe Lantin 2016-01-06 23:48:38 UTC
Created attachment 33414 [details]
Add urlencode function.

Patch against 2.2.31 that adds urlencode function from apr. Sample usage:

RewriteMap urlencode int:urlencode
RewriteRule /(.*) /some/url?resource=fibble&target=http://%{HTTP_HOST}/$1?${urlencode:%{QUERY_STRING}} [B,PT,L]
Comment 8 Hendrik Harms 2018-08-24 07:57:26 UTC
# using 2.4.33
# example for a redirect with encoded query
RewriteCond %{THE_REQUEST} " (/[^ ]+) "
RewriteRule .* /some/url?resource=fibble&target=%1 [R,B,NE,L,DPI,QSD]