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;
  }