Browse Source

[mod_rewrite] rewrite_raw result gets decoded

personal/stbuehler/wip
Stefan Bühler 8 years ago
parent
commit
76c12e4077
  1. 6
      doc/mod_rewrite.xml
  2. 42
      src/modules/mod_rewrite.c
  3. 36
      tests/t-rewrite.py

6
doc/mod_rewrite.xml

@ -76,13 +76,15 @@
</action>
<action name="rewrite_raw">
<short>modify request path and querystring, matching raw path</short>
<short>modify request path and querystring, matching and writing raw path</short>
<parameter name="rule">
<short>a simple target string or one rule, mapping a regular expression to a target string, or a list of rules.</short>
</parameter>
<description>
<textile>
Similar to "@rewrite@":mod_rewrite.html#mod_rewrite__action_rewrite, but matches the raw path (i.e. the path before URL decoding and sanitizing).
Similar to "@rewrite@":mod_rewrite.html#mod_rewrite__action_rewrite, but matches the raw path (i.e. the path before URL decoding and sanitizing) and the result is decoded again.
"@rewrite@":mod_rewrite.html#mod_rewrite__action_rewrite write the result to @request.path@ and uses URL encoding to generate @request.raw_path@; "@rewrite_raw@":mod_rewrite.html#mod_rewrite__action_rewrite_raw writes @request.raw_path@ and decodes it into @request.path@. In both cases @request.path@ gets simplified afterwards.
</textile>
</description>
</action>

42
src/modules/mod_rewrite.c

@ -94,17 +94,10 @@ error:
return FALSE;
}
static gboolean rewrite_internal(liVRequest *vr, GString *dest_path, GString *dest_query, rewrite_rule *rule, gboolean raw) {
gchar *path;
static gboolean rewrite_internal(liVRequest *vr, GString *dest_path, GString *dest_query, rewrite_rule *rule, gchar *path) {
GMatchInfo *match_info = NULL;
GMatchInfo *prev_match_info = NULL;
if (raw) {
path = vr->request.uri.raw_path->str;
} else {
path = vr->request.uri.path->str;
}
if (NULL != rule->regex && !g_regex_match(rule->regex, path, 0, &match_info)) {
if (NULL != match_info) {
g_match_info_free(match_info);
@ -137,6 +130,7 @@ static liHandlerResult rewrite(liVRequest *vr, gpointer param, gpointer *context
rewrite_data *rd = param;
gboolean debug = _OPTION(vr, rd->p, 0).boolean;
GString *dest_query = g_string_sized_new(31);
gchar *path = rd->raw ? vr->request.uri.raw_path->str : vr->request.uri.path->str;
UNUSED(context);
for (i = 0; i < rd->rules->len; i++) {
@ -144,18 +138,36 @@ static liHandlerResult rewrite(liVRequest *vr, gpointer param, gpointer *context
rule = &g_array_index(rd->rules, rewrite_rule, i);
if (rewrite_internal(vr, dest_path, dest_query, rule, rd->raw)) {
if (rewrite_internal(vr, dest_path, dest_query, rule, path)) {
/* regex matched */
if (debug) {
VR_DEBUG(vr, "rewrite: path \"%s\" => \"%s\", query \"%s\" => \"%s\"",
vr->request.uri.path->str, dest_path->str,
vr->request.uri.query->str, dest_query->str
);
if (NULL != rule->querystring) {
VR_DEBUG(vr, "rewrite%s: path \"%s\" => \"%s\", query \"%s\" => \"%s\"",
rd->raw ? " (raw)" : "",
path, dest_path->str,
vr->request.uri.query->str, dest_query->str
);
} else {
VR_DEBUG(vr, "rewrite%s: path \"%s\" => \"%s\"",
rd->raw ? " (raw)" : "",
path, dest_path->str
);
}
}
/* change request path */
g_string_truncate(vr->request.uri.path, 0);
g_string_append_len(vr->request.uri.path, GSTR_LEN(dest_path));
if (rd->raw) {
g_string_truncate(vr->request.uri.raw_path, 0);
g_string_append_len(vr->request.uri.raw_path, GSTR_LEN(dest_path));
g_string_truncate(vr->request.uri.path, 0);
g_string_append_len(vr->request.uri.path, GSTR_LEN(dest_path));
li_url_decode(vr->request.uri.path);
} else {
g_string_truncate(vr->request.uri.path, 0);
g_string_append_len(vr->request.uri.path, GSTR_LEN(dest_path));
li_string_encode(vr->request.uri.path->str, vr->request.uri.raw_path, LI_ENCODING_URI);
}
li_path_simplify(vr->request.uri.path);
/* change request query */
if (NULL != rule->querystring) {

36
tests/t-rewrite.py

@ -22,6 +22,37 @@ class TestRewrite2(CurlRequest):
rewrite "/somethingelse" => "/nothing", "^/somefile$" => "/test.txt";
defaultaction;
"""
# match decoded and simplified paths by default
class TestRewrite3(CurlRequest):
URL = "/http://some%2Ffile"
EXPECT_RESPONSE_BODY = "/dest/file"
EXPECT_RESPONSE_CODE = 200
config = """
rewrite "/http:/some(/.*)" => "/dest$1";
respond 200 => "%{req.path}";
"""
# match raw paths and simplify path
class TestRewrite4(CurlRequest):
URL = "/http://some%2Ffile"
EXPECT_RESPONSE_BODY = "/dest/http:/some/file"
EXPECT_RESPONSE_CODE = 200
config = """
rewrite_raw "(/http://some%2F.*)" => "/dest$1";
respond 200 => "%{req.path}";
"""
# match and write raw paths
class TestRewrite5(CurlRequest):
URL = "/http://some%2Ffile"
EXPECT_RESPONSE_BODY = "/dest/http://some%2Ffile"
EXPECT_RESPONSE_CODE = 200
config = """
rewrite_raw "(/http://some%2F.*)" => "/dest$1";
respond 200 => "%{req.raw_path}";
"""
class Test(GroupTest):
plain_config = """
setup { module_load "mod_rewrite"; }
@ -29,5 +60,8 @@ setup { module_load "mod_rewrite"; }
group = [
TestRewrite1,
TestRewrite2
TestRewrite2,
TestRewrite3,
TestRewrite4,
TestRewrite5,
]

Loading…
Cancel
Save