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/07/11 10:30:18 UTC

[SYNC] mod_rewrite 3.0.9

Because of an nasty deadloop which was reported by PR#841 I've created another
bugfixed release mod_rewrite 3.0.9. This supersedes the "[SYNC] mod_rewrite
3.0.8" message. Again the information: The below context diff pushes the CVS
version from 3.0.6+ to official 3.0.9. The updated ChangeLog follows again.
Please vote for this and if ok commit it to the repository.

Thanks.

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


  Changes between 3.0.8 and 3.0.9
  ===============================

  970711 - fixed a deadloop problem when you use something like
                RewriteRule a\.html b.html
                RewriteRule b\.html a.html
           in .htaccess files. Here the API workaround via internal redirects
           caused a heavy deadloop inside the rewriting engine, actually
           killing Apache's client and all memory etc.
           [Thanks to Lars Eilebrecht <sf...@unix-ag.org> for hint]

         - fixed -Wall warning under Apache 1.2.1 because of
           the recently introduced NT patches.

         - fixed a newer in the past workable for-loop in
           rewritelog(). Tz tz....

  Changes between 3.0.7 and 3.0.8
  ===============================

  970706 - incorporated a bugfix which fixes a problem with the response 
           code on redirects.
           [Thanks to Marc Slemko <ma...@znep.com> for patch]

         - slightly changed the documentation: solutions.src

         - disable the locking of the RewriteMap child pipe
           under SunOS 4.1.x because this OS does us not allow to lock pipes.
           Here without locking should work ats least _most of the time_, but
           its better this way than it does not work completely.

  970708 - allow env variables to be set even on rules with no
           substitution part ("-").
           [Thanks to Peter Hegedus <he...@iworld.com> for patch]

         - bugfix: now when HostnameLookups is off and get_host_name() returns
           NULL the logfile says "UNKNOWN-HOST" instead of passing NULL to the
           pstrdup function.

         - changed the MODULE_MAGIC_NUMBER checks because Apache 1.2.1
           has 19970622 as its value.

         - changed a few left-over static variables 
           to non-static ones to make mod_rewrite more thread-safe.
           [Thanks to Dean Gaudet <dg...@arctic.org>]

  Changes between 3.0.6 and 3.0.7
  ===============================
  
  970622 - incorporated the NT-porting changes from 
           the Apache Groups 1.3-dev version.

  970624 - fixed a problem when creating a empty
           query string via "xxx?". Now it is possible
           to actually remove an existing query string.
           [Thanks to "Taso N. Devetzis" <de...@snet.net> for hint]

         - made mod_rewrite compile again without warnings
           under "old" Apache 1.2.0.

----------------------------------------

*** mod_rewrite.c.old   Sun Jun 22 09:00:14 1997
--- mod_rewrite.c   Fri Jul 11 10:17:45 1997
***************
*** 61,67 ****
  **  |_| |_| |_|\___/ \__,_|___|_|  \___| \_/\_/ |_|  |_|\__\___|
  **                       |_____|
  **
! **  URL Rewriting Module, Version 3.0.6 (15-Jun-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.9 (11-Jul-1997)
  **
  **  This module uses a rule-based rewriting engine (based on a
  **  regular-expression parser) to rewrite requested URLs on the fly. 
***************
*** 1116,1121 ****
--- 1116,1122 ----
      char *prefix;
      int l;
      int n;
+     char *ofilename;
  
      dconf = (rewrite_perdir_conf *)get_module_config(r->per_dir_config, &rewrite_module);
  
***************
*** 1149,1154 ****
--- 1150,1162 ----
      }
  
      /*
+      *  remember the current filename before rewriting for later check
+      *  to prevent deadlooping because of internal redirects
+      *  on final URL/filename which can be equal to the inital one.
+      */
+     ofilename = r->filename;
+ 
+     /*
       *  now apply the rules ... 
       */
      if (apply_rewrite_list(r, dconf->rewriterules, dconf->directory)) {
***************
*** 1262,1267 ****
--- 1270,1287 ----
              if (r->filename[0] != '/')
                  return BAD_REQUEST;
  
+             /* Check for deadlooping:
+              * At this point we KNOW that at least one rewriting
+              * rule was applied, but when the resulting URL is
+              * the same as the initial URL, we are not allowed to
+              * use the following internal redirection stuff because
+              * this would lead to a deadloop.
+              */
+             if (strcmp(r->filename, ofilename) == 0) {
+                 rewritelog(r, 1, "[per-dir %s] initial URL equal rewritten URL: %s [IGNORING REWRITE]", dconf->directory, r->filename);
+                 return OK;
+             }
+ 
              /* if there is a valid base-URL then substitute
                 the per-dir prefix with this base-URL if the
                 current filename still is inside this per-dir 
***************
*** 1503,1510 ****
              return 0; /* if any condition fails this complete rule fails */
  
          /* if this is a pure matching rule we return immediately */
!         if (strcmp(output, "-") == 0) 
              return 2;
  
          /* if this is a forced proxy request ... */
          if (p->flags & RULEFLAG_PROXY) {
--- 1523,1539 ----
              return 0; /* if any condition fails this complete rule fails */
  
          /* if this is a pure matching rule we return immediately */
!         if (strcmp(output, "-") == 0) {
!             /* but before we set the env variables... */
!             for (i = 0; p->env[i] != NULL; i++) {
!                 strncpy(env2, p->env[i], sizeof(env2)-1);
!                 EOS_PARANOIA(env2);
!                 strncpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch), sizeof(env)-1);    /* substitute in output */
!                 EOS_PARANOIA(env);
!                 add_env_variable(r, env);
!             }
              return 2;
+         }
  
          /* if this is a forced proxy request ... */
          if (p->flags & RULEFLAG_PROXY) {
***************
*** 1624,1629 ****
--- 1653,1659 ----
             and the current URL still is not a fully qualified one we
             finally prefix it with http[s]://<ourname> explicitly */
          if (flags & RULEFLAG_FORCEREDIRECT) {
+             r->status = p->forced_responsecode;
              if (  !(strlen(r->filename) > 7 &&
                      strncmp(r->filename, "http://", 7) == 0)
                 && !(strlen(r->filename) > 8 &&
***************
*** 1659,1665 ****
                  else
                      rewritelog(r, 2, "[per-dir %s] prepare forced redirect %s -> %s", perdir, r->filename, newuri);
                  r->filename = pstrdup(r->pool, newuri);
-                 r->status = p->forced_responsecode;
                  return 1;
              }
          }
--- 1689,1694 ----
***************
*** 1808,1816 ****
              r->args = pstrcat(r->pool, q, "&", r->args, NULL);
          else
              r->args = pstrdup(r->pool, q);
!         if (r->args[strlen(r->args)-1] == '&')
!             r->args[strlen(r->args)-1] = '\0';
!         rewritelog(r, 3, "split uri=%s -> uri=%s, args=%s", olduri, r->filename, r->args);
      }
      return;            
  }
--- 1837,1851 ----
              r->args = pstrcat(r->pool, q, "&", r->args, NULL);
          else
              r->args = pstrdup(r->pool, q);
!         if (strlen(r->args) == 0) {
!             r->args = NULL;
!             rewritelog(r, 3, "split uri=%s -> uri=%s, args=<none>", olduri, r->filename);
!         }
!         else {
!             if (r->args[strlen(r->args)-1] == '&')
!                 r->args[strlen(r->args)-1] = '\0';
!             rewritelog(r, 3, "split uri=%s -> uri=%s, args=%s", olduri, r->filename, r->args);
!         }
      }
      return;            
  }
***************
*** 2213,2219 ****
--- 2248,2256 ----
      int i;
  
      /* lock the channel */
+ #ifdef USE_PIPE_LOCKING
      fd_lock(fpin);
+ #endif
  
      /* write out the request key */
      write(fpin, key, strlen(key));
***************
*** 2229,2235 ****
--- 2266,2274 ----
      buf[i] = '\0';
  
      /* unlock the channel */
+ #ifdef USE_PIPE_LOCKING
      fd_unlock(fpin);
+ #endif
  
      if (strcasecmp(buf, "NULL") == 0)
          return NULL;
***************
*** 2254,2261 ****
      rewrite_server_conf *conf;
      char *fname;
      FILE *fp;
!     static int    rewritelog_flags = ( O_WRONLY|O_APPEND|O_CREAT );
!     static mode_t rewritelog_mode  = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
    
      conf = get_module_config(s->module_config, &rewrite_module);
      
--- 2293,2300 ----
      rewrite_server_conf *conf;
      char *fname;
      FILE *fp;
!     int    rewritelog_flags = ( O_WRONLY|O_APPEND|O_CREAT );
!     mode_t rewritelog_mode  = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
    
      conf = get_module_config(s->module_config, &rewrite_module);
      
***************
*** 2288,2296 ****
--- 2327,2341 ----
  }
  
  /* Child process code for 'RewriteLog "|..."' */
+ #if MODULE_MAGIC_NUMBER > 19970622
  static int rewritelog_child(void *cmd)
+ #else
+ static void rewritelog_child(void *cmd)
+ #endif
  {
+ #if MODULE_MAGIC_NUMBER > 19970622
      int child_pid = 1;
+ #endif
  
      cleanup_for_exec();
      signal(SIGHUP, SIG_IGN);
***************
*** 2302,2308 ****
--- 2347,2357 ----
  #else
      execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
  #endif
+ #if MODULE_MAGIC_NUMBER > 19970622
      return(child_pid);
+ #else
+     return;
+ #endif
  }
  
  static void rewritelog(request_rec *r, int level, const char *text, ...)
***************
*** 2310,2323 ****
      rewrite_server_conf *conf;
      conn_rec *connect;
      char *str1;
!     static char str2[HUGE_STRING_LEN];
!     static char str3[HUGE_STRING_LEN];
!     static char type[20];
!     static char redir[20];
      va_list ap;
      int i;
      request_rec *req;
      char *ruser;
      
      va_start(ap, text);
      conf = get_module_config(r->server->module_config, &rewrite_module);
--- 2359,2373 ----
      rewrite_server_conf *conf;
      conn_rec *connect;
      char *str1;
!     char str2[512];
!     char str3[1024];
!     char type[20];
!     char redir[20];
      va_list ap;
      int i;
      request_rec *req;
      char *ruser;
+     const char *rhost;
      
      va_start(ap, text);
      conf = get_module_config(r->server->module_config, &rewrite_module);
***************
*** 2343,2349 ****
          ruser = "\"\"";
      }
  
!     str1 = pstrcat(r->pool, get_remote_host(connect, r->server->module_config, REMOTE_NAME), " ",
                              (connect->remote_logname != NULL ? connect->remote_logname : "-"), " ",
                              ruser, NULL);
      ap_vsnprintf(str2, sizeof(str2), text, ap);
--- 2393,2403 ----
          ruser = "\"\"";
      }
  
!     rhost = get_remote_host(connect, r->server->module_config, REMOTE_NAME);
!     if (rhost == NULL)
!         rhost = "UNKNOWN-HOST";
! 
!     str1 = pstrcat(r->pool, rhost, " ",
                              (connect->remote_logname != NULL ? connect->remote_logname : "-"), " ",
                              ruser, NULL);
      ap_vsnprintf(str2, sizeof(str2), text, ap);
***************
*** 2353,2360 ****
      else
          strcpy(type, "subreq");
  
!     for (i = 0, req = r->prev; req != NULL; req = req->prev) 
!         ;
      if (i == 0)
          redir[0] = '\0';
      else
--- 2407,2414 ----
      else
          strcpy(type, "subreq");
  
!     for (i = 0, req = r; req->prev != NULL; req = req->prev) 
!         i++;
      if (i == 0)
          redir[0] = '\0';
      else
***************
*** 2439,2447 ****
--- 2493,2507 ----
  }
  
  /* child process code */
+ #if MODULE_MAGIC_NUMBER > 19970622
  static int rewritemap_program_child(void *cmd)
+ #else
+ static void rewritemap_program_child(void *cmd)
+ #endif
  {
+ #if MODULE_MAGIC_NUMBER > 19970622
      int child_pid = 1;
+ #endif
      
      cleanup_for_exec();
      signal(SIGHUP, SIG_IGN);
***************
*** 2453,2459 ****
--- 2513,2523 ----
  #else
      execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
  #endif
+ #if MODULE_MAGIC_NUMBER > 19970622
      return(child_pid);
+ #else
+     return;
+ #endif
  }
  
  
*** mod_rewrite.h.old   Sun Jun 22 09:00:14 1997
--- mod_rewrite.h   Fri Jul 11 09:14:30 1997
***************
*** 64,70 ****
  **  |_| |_| |_|\___/ \__,_|___|_|  \___| \_/\_/ |_|  |_|\__\___|
  **                       |_____|
  **
! **  URL Rewriting Module, Version 3.0.6 (15-Jun-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.9 (11-Jul-1997)
  **
  **  This module uses a rule-based rewriting engine (based on a
  **  regular-expression parser) to rewrite requested URLs on the fly. 
***************
*** 137,143 ****
  #include <fcntl.h>
  #endif
  
! 
  
  
  /*
--- 137,150 ----
  #include <fcntl.h>
  #endif
  
!     /* The locking support for the RewriteMap programs:
!        Locking a pipe to the child works fine under most
!        Unix derivates, but braindead SunOS 4.1.x has 
!        problems with this approach... */
! #define USE_PIPE_LOCKING 1
! #ifdef SUNOS4
! #undef USE_PIPE_LOCKING
! #endif
  
  
  /*
***************
*** 350,362 ****
--- 357,377 ----
  
      /* rewriting logfile support */
  static void  open_rewritelog(server_rec *s, pool *p);
+ #if MODULE_MAGIC_NUMBER > 19970622
  static int   rewritelog_child(void *cmd);
+ #else
+ static void  rewritelog_child(void *cmd);
+ #endif
  static void  rewritelog(request_rec *r, int level, const char *text, ...);
  static char *current_logtime(request_rec *r);
  
      /* program map support */
  static void  run_rewritemap_programs(server_rec *s, pool *p);
+ #if MODULE_MAGIC_NUMBER > 19970622
  static int   rewritemap_program_child(void *cmd);
+ #else
+ static void  rewritemap_program_child(void *cmd);
+ #endif
  
      /* env variable support */
  static void  expand_variables_inbuffer(request_rec *r, char *buf, int buf_len);