You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Ralf S. Engelschall" <rs...@engelschall.com> on 1997/03/17 17:31:59 UTC
[SYNC] mod_rewrite (AGAIN UPDATED)
Here is the again an updated patch to bring the current CVS version in sync
with my author version 3.0.1. The rfc1413-patch was removed in 3.0.1. Changes
to CVS version are:
- a kludge to make mod_rewrite compilable under AIX which
needs fcntl instead of flock
[fixed the AIX compilation bug]
- improvements to the redirection stuff to enable the users to generally
redirect to http, https, gopher and ftp. This is the result of a problem
dicussion on c.i.w.s.u. This also provides the power to realise access
multiplexers like http://www.perl.com/CPAN directly with mod_rewrite.
[I've tested it with per-server and per-directory redirects
and worked correct but this one should be reviewed]
- added TIME variable for RewriteCond which expands to YYYYMMDDHHMMSS
strings and added the special patterns >STRING, <STRING and =STRING to
RewriteCond. These do a lexicographic compare. This can be used in
conjunction with %{TIME} or other variables to create time-dependend
rewriting rules. A example is still included in the updated
documentation (a day/night page example).
[No side effect to existing code, just a little new feature which stands
for its own and could be used for a lot of solutions. A great exception,
because I've still stopped active delepment of mod_rewrite and thus
usually no more featurs are added, even if there are a lot possible
ones on my TODO list ;-)]
Greetings,
Ralf S. Engelschall
rse@engelschall.com
www.engelschall.com
*** mod_rewrite.h.old Sat Feb 22 03:00:16 1997
--- mod_rewrite.h Mon Mar 17 17:20:41 1997
***************
*** 64,70 ****
** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|
** |_____|
**
! ** URL Rewriting Module, Version 3.0.0 (01-02-1997)
**
** This module uses a rule-based rewriting engine (based on a
** regular-expression parser) to rewrite requested URLs on the fly.
--- 64,70 ----
** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|
** |_____|
**
! ** URL Rewriting Module, Version 3.0.1 (17-Mar-1997)
**
** This module uses a rule-based rewriting engine (based on a
** regular-expression parser) to rewrite requested URLs on the fly.
***************
*** 110,117 ****
/* The locking support:
! Try to determine whether we should use
! fcntl() or flock(). */
#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
#define USE_FCNTL 1
#include <fcntl.h>
--- 110,117 ----
/* The locking support:
! Try to determine whether we should use fcntl() or flock().
! Would be better conf.h could provide this... :-( */
#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
#define USE_FCNTL 1
#include <fcntl.h>
***************
*** 131,136 ****
--- 131,141 ----
#include <fcntl.h>
#endif
#endif
+ #ifdef AIX
+ #undef USE_FLOCK
+ #define USE_FCNTL 1
+ #include <fcntl.h>
+ #endif
***************
*** 382,387 ****
--- 387,395 ----
/* File locking */
static void fd_lock(int fd);
static void fd_unlock(int fd);
+
+ /* Lexicographic Comparison */
+ int compare_lexicography(char *cpNum1, char *cpNum2);
#endif /* _MOD_REWRITE_H */
*** mod_rewrite.c.old Fri Mar 7 15:00:11 1997
--- mod_rewrite.c Mon Mar 17 17:20:34 1997
***************
*** 61,67 ****
** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|
** |_____|
**
! ** URL Rewriting Module, Version 3.0.0 (06-Mar-1997)
**
** This module uses a rule-based rewriting engine (based on a
** regular-expression parser) to rewrite requested URLs on the fly.
--- 61,67 ----
** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|
** |_____|
**
! ** URL Rewriting Module, Version 3.0.1 (17-Mar-1997)
**
** This module uses a rule-based rewriting engine (based on a
** regular-expression parser) to rewrite requested URLs on the fly.
***************
*** 935,958 ****
rewritelog(r, 1, "go-ahead with proxy request %s [OK]", r->filename);
return OK;
}
! #ifdef APACHE_SSL
! else if ( (!r->connection->client->ssl &&
! strlen(r->filename) > 7 &&
strncmp(r->filename, "http://", 7) == 0)
! || (r->connection->client->ssl &&
! strlen(r->filename) > 8 &&
! strncmp(r->filename, "https://", 8) == 0) ) {
! #else
! else if (strlen(r->filename) > 7 &&
! strncmp(r->filename, "http://", 7) == 0) {
! #endif
! /* it was finally rewritten to a remote path */
! #ifdef APACHE_SSL
! for (cp = r->filename+strlen(http_method(r))+3; *cp != '/' && *cp != '\0'; cp++)
! #else
! for (cp = r->filename+7; *cp != '/' && *cp != '\0'; cp++)
! #endif
;
if (*cp != '\0') {
rewritelog(r, 1, "escaping %s for redirect", r->filename);
--- 935,957 ----
rewritelog(r, 1, "go-ahead with proxy request %s [OK]", r->filename);
return OK;
}
! else if ( (strlen(r->filename) > 7 &&
strncmp(r->filename, "http://", 7) == 0)
! || (strlen(r->filename) > 8 &&
! strncmp(r->filename, "https://", 8) == 0)
! || (strlen(r->filename) > 9 &&
! strncmp(r->filename, "gopher://", 9) == 0)
! || (strlen(r->filename) > 6 &&
! strncmp(r->filename, "ftp://", 6) == 0) ) {
! /* it was finally rewritten to a remote URL */
! /* skip 'scheme:' */
! for (cp = r->filename; *cp != ':' && *cp != '\0'; cp++)
! ;
! /* skip '//' */
! cp += 2;
! /* skip host part */
! for ( ; *cp != '/' && *cp != '\0'; cp++)
;
if (*cp != '\0') {
rewritelog(r, 1, "escaping %s for redirect", r->filename);
***************
*** 1160,1187 ****
rewritelog(r, 1, "[per-dir %s] go-ahead with proxy request %s [OK]", dconf->directory, r->filename);
return OK;
}
! #ifdef APACHE_SSL
! else if ( (!r->connection->client->ssl &&
! strlen(r->filename) > 7 &&
strncmp(r->filename, "http://", 7) == 0)
! || (r->connection->client->ssl &&
! strlen(r->filename) > 8 &&
! strncmp(r->filename, "https://", 8) == 0) ) {
! #else
! else if (strlen(r->filename) > 7 &&
! strncmp(r->filename, "http://", 7) == 0) {
! #endif
! /* it was finally rewritten to a remote path */
/* because we are in a per-dir context
first try to replace the directory with its base-URL
if there is a base-URL available */
if (dconf->baseurl != NULL) {
! #ifdef APACHE_SSL
! if ((cp = strchr(r->filename+strlen(http_method(r))+3, '/')) != NULL) {
! #else
! if ((cp = strchr(r->filename+7, '/')) != NULL) {
! #endif
rewritelog(r, 2, "[per-dir %s] trying to replace prefix %s with %s", dconf->directory, dconf->directory, dconf->baseurl);
cp2 = subst_prefix_path(r, cp, dconf->directory, dconf->baseurl);
if (strcmp(cp2, cp) != 0) {
--- 1159,1184 ----
rewritelog(r, 1, "[per-dir %s] go-ahead with proxy request %s [OK]", dconf->directory, r->filename);
return OK;
}
! else if ( (strlen(r->filename) > 7 &&
strncmp(r->filename, "http://", 7) == 0)
! || (strlen(r->filename) > 8 &&
! strncmp(r->filename, "https://", 8) == 0)
! || (strlen(r->filename) > 9 &&
! strncmp(r->filename, "gopher://", 9) == 0)
! || (strlen(r->filename) > 6 &&
! strncmp(r->filename, "ftp://", 6) == 0) ) {
! /* it was finally rewritten to a remote URL */
/* because we are in a per-dir context
first try to replace the directory with its base-URL
if there is a base-URL available */
if (dconf->baseurl != NULL) {
! /* skip 'scheme:' */
! for (cp = r->filename; *cp != ':' && *cp != '\0'; cp++)
! ;
! /* skip '//' */
! cp += 2;
! if ((cp = strchr(cp, '/')) != NULL) {
rewritelog(r, 2, "[per-dir %s] trying to replace prefix %s with %s", dconf->directory, dconf->directory, dconf->baseurl);
cp2 = subst_prefix_path(r, cp, dconf->directory, dconf->baseurl);
if (strcmp(cp2, cp) != 0) {
***************
*** 1192,1202 ****
}
/* now prepare the redirect... */
! #ifdef APACHE_SSL
! for (cp = r->filename+strlen(http_method(r))+3; *cp != '/' && *cp != '\0'; cp++)
! #else
! for (cp = r->filename+7; *cp != '/' && *cp != '\0'; cp++)
! #endif
;
if (*cp != '\0') {
rewritelog(r, 1, "[per-dir %s] escaping %s for redirect", dconf->directory, r->filename);
--- 1189,1202 ----
}
/* now prepare the redirect... */
!
! /* skip 'scheme:' */
! for (cp = r->filename; *cp != ':' && *cp != '\0'; cp++)
! ;
! /* skip '//' */
! cp += 2;
! /* skip host part */
! for ( ; *cp != '/' && *cp != '\0'; cp++)
;
if (*cp != '\0') {
rewritelog(r, 1, "[per-dir %s] escaping %s for redirect", dconf->directory, r->filename);
***************
*** 1523,1536 ****
}
/* if this is a implicit redirect in a per-dir rule */
! #ifdef APACHE_SSL
! if (perdir != NULL && ( (!r->connection->client->ssl &&
! strncmp(output, "http://", 7) == 0)
! || (r->connection->client->ssl &&
! strncmp(output, "https://", 8) == 0) )) {
! #else
! if (perdir != NULL && strncmp(output, "http://", 7) == 0) {
! #endif
if (p->flags & RULEFLAG_NOTMATCH) {
strncpy(newuri, output, sizeof(newuri)-1);
EOS_PARANOIA(newuri);
--- 1523,1534 ----
}
/* if this is a implicit redirect in a per-dir rule */
! i = strlen(output);
! if (perdir != NULL
! && ( (i > 7 && strncmp(output, "http://", 7) == 0)
! || (i > 8 && strncmp(output, "https://", 8) == 0)
! || (i > 9 && strncmp(output, "gopher://", 9) == 0)
! || (i > 6 && strncmp(output, "ftp://", 6) == 0) ) ) {
if (p->flags & RULEFLAG_NOTMATCH) {
strncpy(newuri, output, sizeof(newuri)-1);
EOS_PARANOIA(newuri);
***************
*** 1591,1597 ****
r->filename = pstrdup(r->pool, newuri);
! /* reduce http://<ourhost>[:<port>] */
reduce_uri(r);
/* split out on-the-fly generated QUERY_STRING '....?xxxxx&xxxx...' */
--- 1589,1595 ----
r->filename = pstrdup(r->pool, newuri);
! /* reduce http[s]://<ourhost>[:<port>] */
reduce_uri(r);
/* split out on-the-fly generated QUERY_STRING '....?xxxxx&xxxx...' */
***************
*** 1607,1622 ****
}
/* if we are forced to do a explicit redirect by [R] flag
! finally prefix the new URI with http://<ourname> explicitly */
if (flags & RULEFLAG_FORCEREDIRECT) {
! #ifdef APACHE_SSL
! if ( (!r->connection->client->ssl &&
! strncmp(r->filename, "http://", 7) != 0) ||
! (r->connection->client->ssl &&
! strncmp(r->filename, "https://", 8) != 0)) {
! #else
! if (strncmp(r->filename, "http://", 7) != 0) {
! #endif
#ifdef APACHE_SSL
if ((!r->connection->client->ssl && r->server->port == 80) ||
( r->connection->client->ssl && r->server->port == 443) )
--- 1605,1622 ----
}
/* if we are forced to do a explicit redirect by [R] flag
! and the current URL still is not a fully qualified one we
! finally prefix it with http[s]://<ourname> explicitly */
if (flags & RULEFLAG_FORCEREDIRECT) {
! if ( !(strlen(r->filename) > 7 &&
! strncmp(r->filename, "http://", 7) == 0)
! && !(strlen(r->filename) > 8 &&
! strncmp(r->filename, "https://", 8) == 0)
! && !(strlen(r->filename) > 9 &&
! strncmp(r->filename, "gopher://", 9) == 0)
! && !(strlen(r->filename) > 6 &&
! strncmp(r->filename, "ftp://", 6) == 0) ) {
!
#ifdef APACHE_SSL
if ((!r->connection->client->ssl && r->server->port == 80) ||
( r->connection->client->ssl && r->server->port == 443) )
***************
*** 1736,1741 ****
--- 1736,1750 ----
destroy_sub_req(rsub);
}
}
+ else if (strlen(p->pattern) > 1 && *(p->pattern) == '>') {
+ rc = (compare_lexicography(input, p->pattern+1) == 1 ? 1 : 0);
+ }
+ else if (strlen(p->pattern) > 1 && *(p->pattern) == '<') {
+ rc = (compare_lexicography(input, p->pattern+1) == -1 ? 1 : 0);
+ }
+ else if (strlen(p->pattern) > 1 && *(p->pattern) == '=') {
+ rc = (strcmp(input, p->pattern+1) == 0 ? 1 : 0);
+ }
else {
/* it is really a regexp pattern, so apply it */
rc = (regexec(p->regexp, input, 0, NULL, 0) == 0);
***************
*** 1790,1796 ****
/*
**
! ** strip 'http://ourhost/' from URI
**
*/
--- 1799,1805 ----
/*
**
! ** strip 'http[s]://ourhost/' from URI
**
*/
***************
*** 2613,2618 ****
--- 2622,2636 ----
else if (strcasecmp(var, "TIME_WDAY") == 0) {
MKTIMESTR("%d", tm_wday)
}
+ else if (strcasecmp(var, "TIME") == 0) {
+ tc = time(NULL);
+ tm = localtime(&tc);
+ ap_snprintf(resultbuf, sizeof(resultbuf), "%02d%02d%02d%02d%02d%02d%02d",
+ (tm->tm_year / 100) + 19, (tm->tm_year % 100),
+ tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ result = resultbuf;
+ rewritelog(r, 1, "RESULT='%s'", result);
+ }
/* all other env-variables from the parent Apache process */
else if (strlen(var) > 4 && strncasecmp(var, "ENV:", 4) == 0) {
***************
*** 3225,3230 ****
--- 3243,3274 ----
fprintf(stderr, "Error freeing lock. Exiting!");
exit(1);
}
+ }
+
+ /*
+ **
+ ** Lexicographic Compare
+ **
+ */
+
+ int compare_lexicography(char *cpNum1, char *cpNum2)
+ {
+ int i;
+ int n1, n2;
+
+ n1 = strlen(cpNum1);
+ n2 = strlen(cpNum2);
+ if (n1 > n2)
+ return 1;
+ if (n1 < n2)
+ return -1;
+ for (i = 0; i < n1; i++) {
+ if (cpNum1[i] > cpNum2[i])
+ return 1;
+ if (cpNum1[i] < cpNum2[i])
+ return -1;
+ }
+ return 0;
}