httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@hyperreal.org>
Subject cvs commit: apachen/src/modules/standard mod_unique_id.c mod_setenvif.c
Date Mon, 18 Aug 1997 07:17:32 GMT
dgaudet     97/08/18 00:17:31

  Modified:    htdocs/manual new_features_1_3.html
               src      CHANGES Configuration.tmpl
               src/core http_config.c http_config.h http_main.c
                        http_protocol.c http_request.c http_request.h
               src/modules/standard mod_setenvif.c
  Added:       src/modules/standard mod_unique_id.c
  Log:
  - API: added post_read_request phase
  - New module: mod_unique_id
  - open_logs is now done before init_modules, and init_modules is not called
    twice at initialization
  
  Reviewed by:	Ben Laurie, Jim Jagielski, Paul Sutton (well, they didn't
  		all give +1s but they didn't veto it either! :)
  
  Revision  Changes    Path
  1.17      +7 -0      apachen/htdocs/manual/new_features_1_3.html
  
  Index: new_features_1_3.html
  ===================================================================
  RCS file: /export/home/cvs/apachen/htdocs/manual/new_features_1_3.html,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- new_features_1_3.html	1997/08/17 11:40:10	1.16
  +++ new_features_1_3.html	1997/08/18 07:17:19	1.17
  @@ -212,6 +212,13 @@
   	and IRIX.
       </ul>
   
  +<li><strong>Unique Identifiers</strong><br>
  +    mod_uniqid can be included to generate a unique identifier that
  +    distinguishes a hit from every other hit.  ("Unique" has
  +    some restrictions on it.)  Documentation to be written.  The
  +    identifier is available in the environment variable
  +    <code>UNIQUE_ID</code>.
  +
   </ul>
   
   <!--#include virtual="footer.html" -->
  
  
  
  1.403     +17 -0     apachen/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/CHANGES,v
  retrieving revision 1.402
  retrieving revision 1.403
  diff -u -r1.402 -r1.403
  --- CHANGES	1997/08/18 07:09:16	1.402
  +++ CHANGES	1997/08/18 07:17:21	1.403
  @@ -1,5 +1,22 @@
   Changes with Apache 1.3a2
   
  +  *) API: Added post_read_request API phase which is run right after reading
  +     the request from a client, or right after an internal redirect.  It is
  +     useful for modules setting environment variables that depend only on
  +     the headers/contents of the request.  It does not run during subrequests
  +     because subrequests inherit pretty much everything from the main
  +     request. [Dean Gaudet]
  +
  +  *) Added mod_unique_id which is used to generate a unique identifier for
  +     each hit, available in the environment variable UNIQUE_ID.
  +     [Dean Gaudet]
  +
  +  *) init_modules is now called after the error logs have been opened.  This
  +     allows modules to emit information messages into the error logs.
  +     init_modules is only called once in standalone config now, previously
  +     it was called twice (once after each config file reading).
  +     [Dean Gaudet]
  +
     *) Fixed proxy-pass-through feature of mod_rewrite; Added error logging
        information for case where proxy module is not available. [Marc Slemko]
   
  
  
  
  1.72      +6 -0      apachen/src/Configuration.tmpl
  
  Index: Configuration.tmpl
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/Configuration.tmpl,v
  retrieving revision 1.71
  retrieving revision 1.72
  diff -u -r1.71 -r1.72
  --- Configuration.tmpl	1997/08/10 13:29:51	1.71
  +++ Configuration.tmpl	1997/08/18 07:17:21	1.72
  @@ -300,3 +300,9 @@
   ## should be the last (highest priority) module.
   
   AddModule modules/standard/mod_setenvif.o
  +
  +## mod_unique_id generates unique identifiers for each hit, which are
  +## available in the environment variable UNIQUE_ID.  It may not work on all
  +## systems, hence it is not included by default.
  +
  +# AddModule modules/standard/mod_unique_id.o
  
  
  
  1.73      +7 -1      apachen/src/core/http_config.c
  
  Index: http_config.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/core/http_config.c,v
  retrieving revision 1.72
  retrieving revision 1.73
  diff -u -r1.72 -r1.73
  --- http_config.c	1997/08/06 20:21:21	1.72
  +++ http_config.c	1997/08/18 07:17:24	1.73
  @@ -259,7 +259,8 @@
       XtOffsetOf (module, type_checker),
       XtOffsetOf (module, fixer_upper),
       XtOffsetOf (module, logger),
  -    XtOffsetOf (module, header_parser)
  +    XtOffsetOf (module, header_parser),
  +    XtOffsetOf (module, post_read_request)
   };
   #define NMETHODS	(sizeof (method_offsets)/sizeof (method_offsets[0]))
   
  @@ -272,6 +273,7 @@
       int fixer_upper;
       int logger;
       int header_parser;
  +    int post_read_request;
   } offsets_into_method_ptrs;
   
   /*
  @@ -370,6 +372,10 @@
   
   int header_parse (request_rec *r) {
       return run_method (r, offsets_into_method_ptrs.header_parser, 1);
  +}
  +
  +int run_post_read_request (request_rec *r) {
  +    return run_method (r, offsets_into_method_ptrs.post_read_request, 1);
   }
   
   /* Auth stuff --- anything that defines one of these will presumably
  
  
  
  1.44      +7 -8      apachen/src/core/http_config.h
  
  Index: http_config.h
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/core/http_config.h,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -u -r1.43 -r1.44
  --- http_config.h	1997/08/06 20:21:23	1.43
  +++ http_config.h	1997/08/18 07:17:24	1.44
  @@ -205,8 +205,9 @@
        *                  supposed to handle this was configured wrong).
        * type_checker --- Determine MIME type of the requested entity;
        *                  sets content_type, _encoding and _language fields.
  -     * logger --- log a transaction.  Not supported yet out of sheer
  -     *            laziness on my part.
  +     * logger --- log a transaction.
  +     * post_read_request --- run right after read_request or internal_redirect,
  +     *                  and not run during any subrequests.
        */
       
       int (*translate_handler)(request_rec *);
  @@ -230,15 +231,12 @@
        */
   #ifdef ULTRIX_BRAIN_DEATH
       void (*child_init)();
  -#else
  -    void (*child_init)(server_rec *, pool *);
  -#endif
  -#ifdef ULTRIX_BRAIN_DEATH
       void (*child_exit)();
   #else
  +    void (*child_init)(server_rec *, pool *);
       void (*child_exit)(server_rec *, pool *);
   #endif
  -
  +    int (*post_read_request)(request_rec *);
   } module;
   
   /* Initializer for the first few module slots, which are only
  @@ -248,7 +246,7 @@
    * handle it back-compatibly, or at least signal an error).
    */
   
  -#define MODULE_MAGIC_NUMBER 19970728
  +#define MODULE_MAGIC_NUMBER 19970818
   #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, -1, __FILE__, NULL
   
   /* Generic accessors for other modules to get at their own module-specific
  @@ -323,5 +321,6 @@
   int invoke_handler (request_rec *);     
   int log_transaction (request_rec *r);
   int header_parse (request_rec *);
  +int run_post_read_request (request_rec *);
   
   #endif
  
  
  
  1.204     +2 -2      apachen/src/core/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/core/http_main.c,v
  retrieving revision 1.203
  retrieving revision 1.204
  diff -u -r1.203 -r1.204
  --- http_main.c	1997/08/17 12:57:03	1.203
  +++ http_main.c	1997/08/18 07:17:25	1.204
  @@ -3082,8 +3082,8 @@
   
   	server_conf = read_config (pconf, ptrans, server_confname); 
   	setup_listeners (pconf);
  -	init_modules (pconf, server_conf);
   	open_logs (server_conf, pconf);
  +	init_modules (pconf, server_conf);
   	set_group_privs ();
   	SAFE_ACCEPT(accept_mutex_init (pconf));
   	if (!is_graceful) {
  @@ -3305,7 +3305,6 @@
   
       suexec_enabled = init_suexec();
       server_conf = read_config (pconf, ptrans, server_confname);
  -    init_modules (pconf, server_conf);
       
       if(standalone) {
           clear_pool (pconf);	/* standalone_main rereads... */
  @@ -3319,6 +3318,7 @@
   	NET_SIZE_T l;
         
   	open_logs(server_conf, pconf);
  +	init_modules (pconf, server_conf);
   	set_group_privs();
   	default_server_hostnames (server_conf);
   
  
  
  
  1.154     +7 -0      apachen/src/core/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/core/http_protocol.c,v
  retrieving revision 1.153
  retrieving revision 1.154
  diff -u -r1.153 -r1.154
  --- http_protocol.c	1997/08/17 13:42:25	1.153
  +++ http_protocol.c	1997/08/18 07:17:26	1.154
  @@ -63,6 +63,7 @@
   #include "http_core.h"
   #include "http_protocol.h"
   #include "http_main.h"
  +#include "http_request.h"
   #include "http_log.h"		/* For errors detected in basic auth
   				 * common support code...
   				 */
  @@ -797,6 +798,7 @@
   request_rec *read_request (conn_rec *conn)
   {
       request_rec *r = (request_rec *)pcalloc (conn->pool, sizeof(request_rec));
  +    int access_status;
   
       r->connection = conn;
       conn->server = conn->base_server;
  @@ -881,6 +883,11 @@
           r->method_number = M_TRACE;
       else 
           r->method_number = M_INVALID; /* Will eventually croak. */
  +
  +    if ((access_status = run_post_read_request (r))) {
  +	die (access_status, r);
  +	return NULL;
  +    }
   
       return r;
   }
  
  
  
  1.76      +11 -1     apachen/src/core/http_request.c
  
  Index: http_request.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/core/http_request.c,v
  retrieving revision 1.75
  retrieving revision 1.76
  diff -u -r1.75 -r1.76
  --- http_request.c	1997/08/17 20:21:36	1.75
  +++ http_request.c	1997/08/18 07:17:26	1.76
  @@ -913,7 +913,7 @@
   void process_request_internal (request_rec *r)
   {
       int access_status;
  -  
  +
       /* Kludge to be reading the assbackwards field outside of protocol.c,
        * but we've got to check for this sort of nonsense somewhere...
        */
  @@ -1102,6 +1102,7 @@
   {
       request_rec *new = (request_rec *)pcalloc(r->pool, sizeof(request_rec));
       char t[256];		/* Long enough... */
  +    int access_status;
     
       new->connection = r->connection;
       new->server = r->server;
  @@ -1153,6 +1154,15 @@
   
       ap_snprintf (t, sizeof(t), "%d", r->status);
       table_set (new->subprocess_env, "REDIRECT_STATUS", pstrdup (r->pool, t));
  +
  +    /* XXX: hmm.  This is because mod_setenvif and mod_unique_id really need
  +     * to do their thing on internal redirects as well.  Perhaps this is
  +     * a misnamed function.
  +     */
  +    if ((access_status = run_post_read_request (new))) {
  +	die (access_status, new);
  +	return NULL;
  +    }
   
       return new;
   }
  
  
  
  1.14      +1 -0      apachen/src/core/http_request.h
  
  Index: http_request.h
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/core/http_request.h,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- http_request.h	1997/07/15 21:39:57	1.13
  +++ http_request.h	1997/08/18 07:17:27	1.14
  @@ -92,4 +92,5 @@
   /* Function called by main.c to handle first-level request */
   void process_request (request_rec *);     
   int default_handler (request_rec *);
  +void die(int type, request_rec *r);
   #endif
  
  
  
  1.5       +5 -4      apachen/src/modules/standard/mod_setenvif.c
  
  Index: mod_setenvif.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_setenvif.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- mod_setenvif.c	1997/08/02 08:10:28	1.4
  +++ mod_setenvif.c	1997/08/18 07:17:30	1.5
  @@ -269,7 +269,7 @@
   { NULL },
   };
   
  -static int fname_translate_setenvif(request_rec *r)
  +static int match_headers(request_rec *r)
   {
       server_rec *s = r->server;
       sei_cfg_rec *sconf = (sei_cfg_rec *)get_module_config(s->module_config,
  @@ -342,7 +342,7 @@
      merge_setenvif_config,     	/* merge server configs */
      setenvif_module_cmds,	/* command table */
      NULL,			/* handlers */
  -   fname_translate_setenvif,	/* filename translation */
  +   NULL,			/* filename translation */
      NULL,			/* check_user_id */
      NULL,			/* check auth */
      NULL,			/* check access */
  @@ -350,6 +350,7 @@
      NULL,			/* fixups */
      NULL,			/* logger */
      NULL,			/* browser parse */
  -   NULL,			/* child (process) initializer */
  -   NULL				/* child (process) rundown handler */
  +   NULL,			/* child_init */
  +   NULL,			/* child_exit */
  +   match_headers		/* post_read_request */
   };
  
  
  
  1.1                  apachen/src/modules/standard/mod_unique_id.c
  
  Index: mod_unique_id.c
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1995-1997 The Apache Group.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * 4. The names "Apache Server" and "Apache Group" must not be used to
   *    endorse or promote products derived from this software without
   *    prior written permission.
   *
   * 5. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Group and was originally based
   * on public domain software written at the National Center for
   * Supercomputing Applications, University of Illinois, Urbana-Champaign.
   * For more information on the Apache Group and the Apache HTTP server
   * project, please see <http://www.apache.org/>.
   *
   */
  
  /*
   * mod_uniqueid.c: generate a unique identifier for each request
   *
   * Original author: Dean Gaudet <dgaudet@arctic.org>
   */
  
  #include "httpd.h"
  #include "http_config.h"
  #include "http_log.h"
  #include "multithread.h"
  #include <unistd.h>
  #include <netdb.h>
  
  #ifdef MULTITHREAD
  #error sorry this module does not support multithreaded servers yet
  #endif
  
  typedef struct {
      time_t stamp;
      unsigned int in_addr;
      unsigned int pid;
      unsigned short counter;
  } unique_id_rec;
  
  /* Comments:
   *
   * We want an identifier which is unique across all hits, everywhere.
   * "everywhere" includes multiple httpd instances on the same machine, or on
   * multiple machines.  Essentially "everywhere" should include all possible
   * httpds across all servers at a particular "site".  We make some assumptions
   * that if the site has a cluster of machines then their time is relatively
   * synchronized.  We also assume that the first address returned by a
   * gethostbyname (gethostname()) is unique across all the machines at the
   * "site".
   *
   * We also further assume that pids fit in 32-bits.  If something uses more
   * than 32-bits, the fix is trivial, but it requires the unrolled uuencoding
   * loop to be extended.  * A similar fix is needed to support multithreaded
   * servers, using a pid/tid combo.
   *
   * Together, the in_addr and pid are assumed to absolutely uniquely identify
   * this one child from all other currently running children on all servers
   * (including this physical server if it is running multiple httpds) from each
   * other.
   *
   * The stamp and counter are used to distinguish all hits for a particular
   * (in_addr,pid) pair.  The stamp is updated using r->request_time,
   * saving cpu cycles.  The counter is never reset, and is used to permit up to
   * 64k requests in a single second by a single child.
   *
   * The 112-bits of unique_id_rec are uuencoded using the alphabet
   * [A-Za-z0-9@-], resulting in 19 bytes of printable characters.  That is then
   * stuffed into the environment variable UNIQUE_ID so that it is available to
   * other modules.  The alphabet choice differs from normal base64 encoding
   * [A-Za-z0-9+/] because + and / are special characters in URLs and we want to
   * make it easy to use UNIQUE_ID in URLs.
   *
   * Note that UNIQUE_ID should be considered an opaque token by other
   * applications.  No attempt should be made to dissect its internal components.
   * It is an abstraction that may change in the future as the needs of this
   * module change.
   *
   * It is highly desirable that identifiers exist for "eternity".  But future
   * needs (such as much faster webservers, moving to 64-bit pids, or moving to a
   * multithreaded server) may dictate a need to change the contents of
   * unique_id_rec.  Such a future implementation should ensure that the first
   * field is still a time_t stamp.  By doing that, it is possible for a site to
   * have a "flag second" in which they stop all of their old-format servers,
   * wait one entire second, and then start all of their new-servers.  This
   * procedure will ensure that the new space of identifiers is completely unique
   * from the old space.  (Since the first four unencoded bytes always differ.)
   */
  
  static unsigned global_in_addr;
  
  static APACHE_TLS unique_id_rec cur_unique_id;
  
  static void unique_id_global_init (server_rec *s, pool *p)
  {
  #ifndef MAXHOSTNAMELEN
  #define MAXHOSTNAMELEN 256
  #endif
      char str[MAXHOSTNAMELEN+1];
      struct hostent *hent;
  #ifndef NO_GETTIMEOFDAY
      struct timeval tv;
  #endif
  
      /* First of all, verify some assumptions that have been made about
       * the contents of unique_id_rec.  We do it this way because it
       * isn't affected by trailing padding.
       */
      if (XtOffsetOf (unique_id_rec, counter) + sizeof (cur_unique_id.counter)
  	!= 14) {
  	log_error ("mod_unique_id: sorry the size assumptions are wrong in mod_unique_id.c, please
remove it from your server or fix the code!", s);
  	exit (1);
      }
  
      /* Now get the global in_addr.  Note that it is not sufficient to use
       * one of the addresses from the main_server, since those aren't as likely
       * to be unique as the physical address of the machine
       */
      if (gethostname (str, sizeof (str) - 1) != 0) {
  	log_unixerr ("gethostname", "mod_unique_id",
  	    "mod_unique_id requires the hostname of the server", s);
  	exit (1);
      }
  
      if ((hent = gethostbyname (str)) == NULL) {
  	log_printf (s, "mod_unique_id: unable to gethostbyname(\"%s\")", str);
  	exit (1);
      }
  
      global_in_addr = ((struct in_addr *)hent->h_addr_list[0])->s_addr;
  
      log_printf (s, "mod_unique_id: using ip addr %s",
  	inet_ntoa (*(struct in_addr *)hent->h_addr_list[0]));
  
      /* If the server is pummelled with restart requests we could possibly
       * end up in a situation where we're starting again during the same
       * second that has been used in previous identifiers.  Avoid that
       * situation.
       *
       * In truth, for this to actually happen not only would it have to
       * restart in the same second, but it would have to somehow get the
       * same pids as one of the other servers that was running in that second.
       * Which would mean a 64k wraparound on pids ... not very likely at
       * all.
       *
       * But protecting against it is relatively cheap.  We just sleep into
       * the next second.
       */
  #ifdef NO_GETTIMEOFDAY
      sleep (1);
  #else
      if (gettimeofday (&tv, NULL) == -1) {
  	sleep (1);
      } else if (tv.tv_usec) {
  	tv.tv_sec = 0;
  	tv.tv_usec = 1000000 - tv.tv_usec;
  	select (0, NULL, NULL, NULL, &tv);
      }
  #endif
  }
  
  static void unique_id_child_init (server_rec *s, pool *p)
  {
      pid_t pid;
  #ifndef NO_GETTIMEOFDAY
      struct timeval tv;
  #endif
  
      /* Note that we use the pid because it's possible that on the same
       * physical machine there are multiple servers (i.e. using Listen).
       * But it's guaranteed that none of them will share the same pids
       * between children.
       *
       * XXX: for multithread this needs to use a pid/tid combo and probably
       * XXX: needs to be expanded to 32 bits
       */
      pid = getpid();
      cur_unique_id.pid = pid;
  
      /* Test our assumption that the pid is 16-bits.  But note we can't just
       * test sizeof (pid_t) because on some machines pid_t is 32-bits but
       * pids are actually only 16-bits.  It would have been really nice to
       * test this during global_init ... but oh well.
       */
      if (cur_unique_id.pid != pid) {
  	log_error ("mod_unique_id: oh no! pids are greater than 16-bits!  I'm broken!", s);
      }
  
      cur_unique_id.in_addr = global_in_addr;
  
      /* If we use 0 as the initial counter we have a little less protection
       * against restart problems, and a little less protection against a
       * clock going backwards in time.
       */
  #ifndef NO_GETTIMEOFDAY
      if (gettimeofday (&tv, NULL) == -1) {
  	cur_unique_id.counter = 0;
      } else {
  	cur_unique_id.counter = tv.tv_usec;
      }
  #else
      cur_unique_id.counter = 0;
  #endif
  
      /* We must always use network ordering for these bytes, so that identifiers
       * are comparable between machines of different byte orderings.  Note
       * in_addr is already in network order.
       */
      cur_unique_id.pid = htons (cur_unique_id.pid);
      cur_unique_id.counter = htons (cur_unique_id.counter);
  }
  
  /* NOTE: This is *NOT* the same encoding used by uuencode ... the last two
   * characters should be + and /.  But those two characters have very special
   * meanings in URLs, and we want to make it easy to use identifiers in
   * URLs.  So we replace them with @ and -.
   */
  static const char uuencoder[64] = {
      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
      'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
      'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@', '-',
  };
  
  static int gen_unique_id (request_rec *r)
  {
      /* when we uuencode it will take 19 bytes plus \0 */
      char str[19 + 1];
      const unsigned char *x;
      unsigned short counter;
  
      cur_unique_id.stamp = htonl (r->request_time);
  
      /* do the uuencoding */
      x = (const unsigned char *)&cur_unique_id;
      str[0] = uuencoder[x[0] >> 2];
      str[1] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
      str[2] = uuencoder[((x[1] & 0x0f) << 2) | ((x[2] & 0xc0) >> 6)];
      str[3] = uuencoder[x[2] & 0x3f];
      x += 3;
      str[4] = uuencoder[x[0] >> 2];
      str[5] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
      str[6] = uuencoder[((x[1] & 0x0f) << 2) | ((x[2] & 0xc0) >> 6)];
      str[7] = uuencoder[x[2] & 0x3f];
      x += 3;
      str[8] = uuencoder[x[0] >> 2];
      str[9] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
      str[10] = uuencoder[((x[1] & 0x0f) << 2) | ((x[2] & 0xc0) >> 6)];
      str[11] = uuencoder[x[2] & 0x3f];
      x += 3;
      str[12] = uuencoder[x[0] >> 2];
      str[13] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
      str[14] = uuencoder[((x[1] & 0x0f) << 2) | ((x[2] & 0xc0) >> 6)];
      str[15] = uuencoder[x[2] & 0x3f];
      x += 3;
      str[16] = uuencoder[x[0] >> 2];
      str[17] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
      str[18] = uuencoder[((x[1] & 0x0f) << 2) | ((   0 & 0xc0) >> 6)];
      str[19] = '\0';
  
      table_set (r->subprocess_env, "UNIQUE_ID", str);
  
      /* and increment the identifier for the next call */
      counter = ntohs (cur_unique_id.counter) + 1;
      cur_unique_id.counter = htons (counter);
  
      return DECLINED;
  }
  
  
  module MODULE_VAR_EXPORT unique_id_module = {
     STANDARD_MODULE_STUFF,
     unique_id_global_init,	/* initializer */
     NULL,			/* dir config creater */
     NULL,			/* dir merger --- default is to override */
     NULL,			/* server config */
     NULL,			/* merge server configs */
     NULL,			/* command table */
     NULL,			/* handlers */
     NULL,			/* filename translation */
     NULL,			/* check_user_id */
     NULL,			/* check auth */
     NULL,			/* check access */
     NULL,			/* type_checker */
     NULL,			/* fixups */
     NULL,			/* logger */
     NULL,			/* header parser */
     unique_id_child_init,	/* child_init */
     NULL,			/* child_exit */
     gen_unique_id		/* post_read_request */
  };
  
  
  

Mime
View raw message