On Mon, Dec 05, 2016 at 04:20:02PM +0200, Gregory Edigarov wrote: > Hello, > > I know, it considered featuritis, but still, hey, it should go somewhere. > This diff is based on the diff sent here by Stanislav Adaszewski > (s.adaszev...@gmail.com), > some time ago. > I've added one option 'test', i.e.: pass rewrite [test] index.php?q=%1, so > it will not rewrite > if file or directory present, and a manual page section, describing the > rule. > For those like me, trying to stick with base as much as possible. > > suggestions? >
Hello, The diff is malformed and cannot be applied. The patch below is re-based against -current. I exclude the httpd.conf example bits. They can be added later as separate patch. Index: httpd.conf.5 =================================================================== RCS file: /home/vlado/cvsync/cvsroot/src/usr.sbin/httpd/httpd.conf.5,v retrieving revision 1.76 diff -u -p -r1.76 httpd.conf.5 --- httpd.conf.5 14 Nov 2016 10:28:31 -0000 1.76 +++ httpd.conf.5 6 Jan 2017 09:47:53 -0000 @@ -388,6 +388,8 @@ The pattern may contain captures that ca .Ar uri of an enclosed .Ic block return +or +.Ic pass rewrite option. .It Oo Ic no Oc Ic log Op Ar option Set the specified logging options. @@ -446,6 +448,17 @@ instead of the log files. Disable any previous .Ic block in a location. +.It Ic pass rewrite Oo Ic test Oc Ic Ar uri +Disable any previous block in location, the path gets rewritten as +specified in +.Ic block return +statement. If +.Ic test +option is present, the rewrite will +.Em not +happen if file or directory referenced by the +.Ar uri +present. .It Ic root Ar option Configure the document root and options for the request path. Valid options are: Index: httpd.h =================================================================== RCS file: /home/vlado/cvsync/cvsroot/src/usr.sbin/httpd/httpd.h,v retrieving revision 1.124 diff -u -p -r1.124 httpd.h --- httpd.h 17 Nov 2016 14:52:48 -0000 1.124 +++ httpd.h 6 Jan 2017 09:47:53 -0000 @@ -73,6 +73,7 @@ #define SERVER_MAX_PREFETCH 256 #define SERVER_MIN_PREFETCHED 32 #define SERVER_HSTS_DEFAULT_AGE 31536000 +#define SERVER_MAX_RECUR_REWR 0 #define MEDIATYPE_NAMEMAX 128 /* file name extension */ #define MEDIATYPE_TYPEMAX 64 /* length of type/subtype */ @@ -364,13 +365,15 @@ SPLAY_HEAD(client_tree, client); #define SRVFLAG_SERVER_MATCH 0x00200000 #define SRVFLAG_SERVER_HSTS 0x00400000 #define SRVFLAG_DEFAULT_TYPE 0x00800000 +#define SRVFLAG_REWRITE 0x01000000 +#define SRVFLAG_TEST 0x02000000 #define SRVFLAG_BITS \ "\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX" \ "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG\13SOCKET" \ "\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG" \ "\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK\25LOCATION_MATCH" \ - "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE" + "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31REWRITE\32TEST" #define TCPFLAG_NODELAY 0x01 #define TCPFLAG_NNODELAY 0x02 @@ -472,6 +475,7 @@ struct server_config { int return_code; char *return_uri; off_t return_uri_len; + char rewrite_uri[PATH_MAX]; int hsts_max_age; uint8_t hsts_flags; Index: parse.y =================================================================== RCS file: /home/vlado/cvsync/cvsroot/src/usr.sbin/httpd/parse.y,v retrieving revision 1.87 diff -u -p -r1.87 parse.y --- parse.y 5 Jan 2017 13:53:09 -0000 1.87 +++ parse.y 6 Jan 2017 09:47:53 -0000 @@ -134,7 +134,7 @@ typedef struct { %token LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK %token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TIMEOUT %token TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST -%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS +%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE TEST %token <v.string> STRING %token <v.number> NUMBER %type <v.port> port @@ -971,6 +971,29 @@ filter : block RETURN NUMBER optstring /* Forbidden */ srv_conf->return_code = 403; } + | PASS REWRITE STRING { + srv_conf->flags |= SRVFLAG_REWRITE; + if (strlcpy(srv_conf->rewrite_uri, $3, + sizeof(srv_conf->rewrite_uri)) >= + sizeof(srv_conf->rewrite_uri)) { + yyerror("url rewrite string too long"); + free($3); + YYERROR; + } + free($3); + } + | PASS REWRITE TEST STRING { + srv_conf->flags |= SRVFLAG_REWRITE; + srv_conf->flags |= SRVFLAG_TEST; + if (strlcpy(srv_conf->rewrite_uri, $4, + sizeof(srv_conf->rewrite_uri)) >= + sizeof(srv_conf->rewrite_uri)) { + yyerror("url rewrite string too long"); + free($4); + YYERROR; + } + free($4); + } | PASS { srv_conf->flags &= ~SRVFLAG_BLOCK; srv_conf->flags |= SRVFLAG_NO_BLOCK; @@ -1231,6 +1254,7 @@ lookup(char *s) { "request", REQUEST }, { "requests", REQUESTS }, { "return", RETURN }, + { "rewrite", REWRITE }, { "root", ROOT }, { "sack", SACK }, { "server", SERVER }, @@ -1240,6 +1264,7 @@ lookup(char *s) { "subdomains", SUBDOMAINS }, { "syslog", SYSLOG }, { "tcp", TCP }, + { "test", TEST }, { "timeout", TIMEOUT }, { "tls", TLS }, { "type", TYPE }, Index: server_http.c =================================================================== RCS file: /home/vlado/cvsync/cvsroot/src/usr.sbin/httpd/server_http.c,v retrieving revision 1.110 diff -u -p -r1.110 server_http.c --- server_http.c 26 Aug 2016 10:46:39 -0000 1.110 +++ server_http.c 6 Jan 2017 09:47:53 -0000 @@ -20,6 +20,7 @@ #include <sys/queue.h> #include <sys/socket.h> #include <sys/tree.h> +#include <sys/stat.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -1039,7 +1040,7 @@ server_expand_http(struct client *clt, c int server_response(struct httpd *httpd, struct client *clt) { - char path[PATH_MAX]; + char path[PATH_MAX],d_path[PATH_MAX]; char hostname[HOST_NAME_MAX+1]; struct http_descriptor *desc = clt->clt_descreq; struct http_descriptor *resp = clt->clt_descresp; @@ -1047,9 +1048,12 @@ server_response(struct httpd *httpd, str struct server_config *srv_conf = &srv->srv_conf; struct kv *kv, key, *host; struct str_find sm; + struct stat st; int portval = -1, ret; char *hostval; const char *errstr = NULL; + char buf[IBUF_READ_SIZE]; + int n; /* Canonicalize the request path */ if (desc->http_path == NULL || @@ -1154,6 +1158,75 @@ server_response(struct httpd *httpd, str /* Now search for the location */ srv_conf = server_getlocation(clt, desc->http_path); + /* URL Rewriting logic */ + DPRINTF("%s: URL Rewriting logic, flags: %08X, rewrite_uri: %s, " + "http_path: %s\n", __func__, srv_conf->flags, + srv_conf->rewrite_uri, desc->http_path); + for (n = 0; srv_conf->flags & SRVFLAG_REWRITE; n++) { + if (n > SERVER_MAX_RECUR_REWR) { + server_abort_http(clt, 500, "recursive " + "rewrite limit exceeded"); + return (-1); + } + if (srv_conf->flags & SRVFLAG_TEST) { + snprintf(d_path,PATH_MAX,"%s%s",srv_conf->root,path); + if (stat(d_path,&st)) { + DPRINTF("%s: Rewrite test from: %s to %s, n: %d\n", + __func__, desc->http_path, srv_conf->rewrite_uri, n); + if (server_expand_http(clt, srv_conf->rewrite_uri, buf, + sizeof(buf)) == NULL) { + server_abort_http(clt, 500, strerror(errno)); + return (-1); + } + if (desc->http_path != NULL) { + free(desc->http_path); + desc->http_path = NULL; + } + desc->http_path = strdup(buf); + if (desc->http_path == NULL) { + server_abort_http(clt, 500, strerror(errno)); + return (-1); + } + desc->http_query = strchr(desc->http_path, '?'); + if (desc->http_query != NULL) { + *desc->http_query++ = '\0'; + desc->http_query = strdup(desc->http_query); + if (desc->http_query == NULL) { + server_abort_http(clt, 500, strerror(errno)); + } + } + srv_conf = server_getlocation(clt, desc->http_path); + } + else break; + } else { + DPRINTF("%s: Rewrite from: %s to %s, n: %d\n", __func__, + desc->http_path, srv_conf->rewrite_uri, n); + if (server_expand_http(clt, srv_conf->rewrite_uri, buf, + sizeof(buf)) == NULL) { + server_abort_http(clt, 500, strerror(errno)); + return (-1); + } + if (desc->http_path != NULL) { + free(desc->http_path); + desc->http_path = NULL; + } + desc->http_path = strdup(buf); + if (desc->http_path == NULL) { + server_abort_http(clt, 500, strerror(errno)); + return (-1); + } + desc->http_query = strchr(desc->http_path, '?'); + if (desc->http_query != NULL) { + *desc->http_query++ = '\0'; + desc->http_query = strdup(desc->http_query); + if (desc->http_query == NULL) { + server_abort_http(clt, 500, strerror(errno)); + } + } + srv_conf = server_getlocation(clt, desc->http_path); + } + } + if (srv_conf->flags & SRVFLAG_BLOCK) { server_abort_http(clt, srv_conf->return_code, srv_conf->return_uri); @@ -1196,8 +1269,10 @@ server_getlocation(struct client *clt, c TAILQ_FOREACH(location, &srv->srv_hosts, entry) { #ifdef DEBUG if (location->flags & SRVFLAG_LOCATION) { - DPRINTF("%s: location \"%s\" path \"%s\"", - __func__, location->location, path); + DPRINTF("%s: location \"%s\" path \"%s\" flags: %08X " + "rewrite_uri: %s", + __func__, location->location, path, location->flags, + location->rewrite_uri); } #endif if ((location->flags & SRVFLAG_LOCATION) &&
signature.asc
Description: PGP signature