Skip to content

Instantly share code, notes, and snippets.

@adsr
Created May 15, 2024 15:35
Show Gist options
  • Save adsr/b4def4974fc84f28ba520b6c98bec0ef to your computer and use it in GitHub Desktop.
Save adsr/b4def4974fc84f28ba520b6c98bec0ef to your computer and use it in GitHub Desktop.
diff --git a/include/http_core.h b/include/http_core.h
index 15c9bac524..036d62486b 100644
--- a/include/http_core.h
+++ b/include/http_core.h
@@ -1059,6 +1059,8 @@ AP_DECLARE(int) ap_state_query(int query_code);
#define AP_SQ_RM_CONFIG_TEST 3
/** only dump some parts of the config */
#define AP_SQ_RM_CONFIG_DUMP 4
+ /** rewrite test */
+#define AP_SQ_RM_REWRITE_TEST 5
#ifdef __cplusplus
}
diff --git a/include/http_main.h b/include/http_main.h
index fa1ce85216..7b5cb1a50c 100644
--- a/include/http_main.h
+++ b/include/http_main.h
@@ -33,7 +33,7 @@
* in apr_getopt() format. Use this for default'ing args that the MPM
* can safely ignore and pass on from its rewrite_args() handler.
*/
-#define AP_SERVER_BASEARGS "C:c:D:d:E:e:f:vVlLtTSMh?X"
+#define AP_SERVER_BASEARGS "C:c:D:d:E:e:f:vVlLtTSMh?XR"
#ifdef __cplusplus
extern "C" {
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 80fbc9e84f..f68cf75f17 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -321,6 +321,8 @@ typedef struct {
int skip; /* number of next rules to skip */
int maxrounds; /* limit on number of loops with N flag */
char *escapes; /* specific backref escapes */
+ char *filename;
+ int line_num;
} rewriterule_entry;
typedef struct {
@@ -3781,6 +3783,8 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
newrule->cookie = NULL;
newrule->skip = 0;
newrule->maxrounds = REWRITE_MAX_ROUNDS;
+ newrule->filename = apr_pstrdup(cmd->pool, cmd->directive->filename);
+ newrule->line_num = cmd->directive->line_num;
if (a3 != NULL) {
if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
cmd_rewriterule_setflag)) != NULL) {
@@ -4187,6 +4191,8 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
}
}
+ printf("rewrite_match @ %s:%d\n", p->filename, p->line_num);
+
/* expand the result */
if (!(p->flags & RULEFLAG_NOSUB)) {
newuri = do_expand(p->output, ctx, p);
@@ -5294,6 +5300,7 @@ static const command_rec command_table[] = {
"an URL-applied regexp-pattern and a substitution URL"),
AP_INIT_TAKE23( "RewriteMap", cmd_rewritemap, NULL, RSRC_CONF,
"a mapname and a filename and options"),
+ AP_INIT_NO_ARGS("HookFixup", (void *)hook_fixup, NULL, RSRC_CONF, ""),
{ NULL }
};
diff --git a/server/main.c b/server/main.c
index 62e06df045..216d882ad9 100644
--- a/server/main.c
+++ b/server/main.c
@@ -40,6 +40,7 @@
#include "apr_uri.h"
#include "util_ebcdic.h"
#include "ap_mpm.h"
+#include "http_protocol.h"
#if APR_HAVE_UNISTD_H
#include <unistd.h>
@@ -378,7 +379,7 @@ static void usage(process_rec *process)
pad_len, " ");
#endif
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
- " %*s [-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]",
+ " %*s [-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X] [-R]",
pad_len, " ");
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
"Options:");
@@ -459,10 +460,73 @@ static void usage(process_rec *process)
" -T : start without DocumentRoot(s) check");
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
" -X : debug mode (only one worker, do not detach)");
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
+ " -R : rewrite test");
destroy_and_exit_process(process, 1);
}
+static int ap_run_rewrite_test_one(process_rec *proc, char *host, char *method, char *uri) {
+ apr_pool_t *pool;
+ conn_rec *conn;
+ request_rec *req;
+ server_rec *svr;
+
+ apr_pool_create(&pool, NULL);
+
+ module *mod_rewrite;
+ const command_rec *hook_fixup_cmd;
+ int (*hook_fixup)(request_rec *r);
+
+ mod_rewrite = ap_find_linked_module("mod_rewrite.c");
+ hook_fixup_cmd = ap_find_command("HookFixup", mod_rewrite->cmds);
+ hook_fixup = (void *)hook_fixup_cmd->func.no_args;
+
+ svr = ap_server_conf;
+
+ conn = apr_pcalloc(pool, sizeof(*conn));
+ conn->pool = pool;
+ conn->base_server = svr;
+ conn->local_addr = apr_pcalloc(pool, sizeof(*conn->local_addr));
+ conn->local_addr->ipaddr_ptr = apr_pcalloc(pool, sizeof(*conn->local_addr->ipaddr_ptr));
+ conn->local_addr->ipaddr_len = 4;
+ conn->local_addr->port = atoi(getenv("REWRITE_TEST_PORT"));
+ ap_update_vhost_given_ip(conn);
+
+ req = ap_create_request(conn);
+ req->the_request = apr_psprintf(pool, "%s %s HTTP/1.1", method, uri);
+ apr_table_setn(req->headers_in, "Host", host);
+ apr_table_setn(req->headers_in, "X-Forwarded-Proto", "https");
+
+ ap_parse_request_line(req);
+ ap_check_request_header(req);
+ ap_run_translate_name(req);
+ ap_run_map_to_storage(req);
+
+ hook_fixup(req);
+
+ apr_pool_destroy(pool);
+
+ return 0;
+}
+
+static int ap_run_rewrite_test(process_rec *proc) {
+ ssize_t rv;
+ size_t len;
+ char *line, *host, *method, *uri;
+ line = NULL;
+
+ while ((rv = getline(&line, &len, stdin)) != -1) {
+ host = strtok(line, "\t\n");
+ method = strtok(NULL, "\t\n");
+ uri = strtok(NULL, "\t\n");
+ ap_run_rewrite_test_one(proc, host, method, uri);
+ }
+
+ free(line);
+ return 0;
+}
+
int main(int argc, const char * const argv[])
{
char c;
@@ -626,6 +690,10 @@ int main(int argc, const char * const argv[])
}
break;
+ case 'R':
+ ap_run_mode = AP_SQ_RM_REWRITE_TEST;
+ break;
+
case 'h':
case '?':
usage(process);
@@ -706,6 +774,9 @@ int main(int argc, const char * const argv[])
ap_show_directives();
destroy_and_exit_process(process, 0);
}
+ else if (ap_run_mode == AP_SQ_RM_REWRITE_TEST) {
+ ap_run_rewrite_test(process);
+ }
else {
ap_run_test_config(pconf, ap_server_conf);
if (ap_run_mode == AP_SQ_RM_CONFIG_TEST)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment