httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@engelschall.com (Ralf S. Engelschall)
Subject [SYNC] mod_rewrite (UPDATED!)
Date Sun, 16 Mar 1997 19:53:58 GMT

Again here is an updated patch to bring the current CVS version in sync with
my author version. Changes 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]

   - replaced the get_remote_logname() call which don't
     worked for vhost context where IdentityCheck is turned on and the main
     server has it off.
     [Simple workaround by directly doing the lookup]

   - 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 ;-)]

While mod_rewrite was named 3.0.0 for a long develop time now, the above is
actually the final one because today I've rolled the tarball mod_rewrite-3.0.0
and released it on its updated webpages along with its new documentation.
When no more bugfixes are neccessary this is the one for 1.2 RELEASE.  If not,
the next bugfix versions are named 3.0.1, etc.

If you're interrested in possible solutions with mod_rewrite, have a look at
the _new_ huge "practial solutions" page on
http://www.engelschall.com/sw/mod_rewrite/docs/mod_rewrite/solutions.html

Greetings,
                                       Ralf S. Engelschall
                                       rse@engelschall.com
                                       www.engelschall.com

*** mod_rewrite.h.old   Sat Feb 22 03:00:16 1997
--- mod_rewrite.h   Sun Mar 16 17:11:26 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.0 (16-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   Sun Mar 16 17:11:16 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.0 (16-Mar-1997)
  **
  **  This module uses a rule-based rewriting engine (based on a
  **  regular-expression parser) to rewrite requested URLs on the fly. 
***************
*** 108,113 ****
--- 108,114 ----
  #include "http_request.h"
  #include "http_core.h"
  #include "http_log.h"
+ #include "rfc1413.h"
  
      /* now our own stuff ... */
  #include "mod_rewrite.h"
***************
*** 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);
--- 936,958 ----
              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) {
--- 1160,1185 ----
              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);
--- 1190,1203 ----
              }
  
              /* 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);
--- 1524,1535 ----
          }
  
          /* 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...' */
--- 1590,1596 ----
  
          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)  )
--- 1606,1623 ----
          }
  
          /* 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 ****
--- 1737,1751 ----
              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
  **
  */
  
--- 1800,1806 ----
  
  /*
  **
! **  strip 'http[s]://ourhost/' from URI
  **
  */
  
***************
*** 2528,2534 ****
          result = r->connection->user;
      }
      else if (strcasecmp(var, "REMOTE_IDENT") == 0) {
!         result = (char *)get_remote_logname(r);
      }
  
      /* request stuff */
--- 2538,2550 ----
          result = r->connection->user;
      }
      else if (strcasecmp(var, "REMOTE_IDENT") == 0) {
!         /* We cannot use get_remote_logname(r) because
!            when IdentityCheck is used inside a virtual host section the flag is
!            not set at this time, so we always receive NULL from this function. */
!         if (r->connection->remote_logname != NULL)
!             result = r->connection->remote_logname;
!         else 
!             result = rfc1413(r->connection, r->server);
      }
  
      /* request stuff */
***************
*** 2613,2618 ****
--- 2629,2643 ----
      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 ****
--- 3250,3281 ----
          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;
  }
  
  
                                       Ralf S. Engelschall
                                       rse@engelschall.com
                                       www.engelschall.com

Mime
View raw message