dgaudet     98/01/26 11:50:30

  Modified:    .        STATUS
               htdocs/manual new_features_1_3.html
               src      CHANGES
               src/main alloc.c alloc.h http_config.h http_core.c
                        http_protocol.c http_request.c util_script.c
               src/modules/proxy mod_proxy.c
               src/modules/standard mod_alias.c mod_dir.c mod_expires.c
                        mod_imap.c mod_include.c mod_log_config.c
                        mod_negotiation.c mod_rewrite.c mod_setenvif.c
                        mod_speling.c mod_unique_id.c mod_userdir.c
                        mod_usertrack.c
  Log:
  API additions: table_setn, table_addn, table_mergen... for speed!
  POOL_DEBUG support for correctness.
  
  Submitted by: Dmitry Khrustalev <[EMAIL PROTECTED]>, Dean Gaudet
  Reviewed by:  Brian Behlendorf, Jim Jagielski
  
  Revision  Changes    Path
  1.131     +1 -0      apachen/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /export/home/cvs/apachen/STATUS,v
  retrieving revision 1.130
  retrieving revision 1.131
  diff -u -r1.130 -r1.131
  --- STATUS    1998/01/26 18:24:25     1.130
  +++ STATUS    1998/01/26 19:50:05     1.131
  @@ -138,6 +138,7 @@
       * Add more compile time diagnosis to main's -V switch
       * [Port] Fix CGI-Execution for EBCDIC hosts.
       * Martin's [PATCH] "Signing" server generated pages
  +    * Dmitry's table_*n API addition
   
   Available Patches:
   
  
  
  
  1.39      +18 -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.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- new_features_1_3.html     1998/01/26 16:53:36     1.38
  +++ new_features_1_3.html     1998/01/26 19:50:06     1.39
  @@ -293,6 +293,12 @@
        and IRIX.
       <LI><CODE><A HREF="mod/mod_log_config.html">mod_log_config</A></CODE>
        can be compile-time configured to buffer writes.
  +    <LI>Replaced <code>strncpy()</code> with <code>ap_cpystrn()</code>, a
  +     routine which doesn't have to zero-fill the entire result.  This
  +     has dramatic effects on <code>mod_include</code> speed.
  +    <LI>Additions to the internal "table" API (used for keeping lists of
  +     key/value string pairs) provide for up to 20% performance
  +     improvement in many situations.
       </UL>
   
       <P>See <A HREF="misc/perf-tuning.html">the new performance
  @@ -461,6 +467,18 @@
       is far more expensive and should only be used for testing with tools
       such as Electric Fence and Purify.  See <CODE>main/alloc.c</CODE>
       for more details.
  +
  +    <LI><strong><code>ap_cpystrn</code></strong><br>
  +    The new <code>strncpy</code> "lookalike", with slightly different
  +    semantics is much faster than <code>strncpy</code> because it
  +    doesn't have to zero-fill the entire buffer.
  +
  +    <LI><strong><code>table_addn</code>, <code>table_setn</code>,
  +    <code>table_mergen</code></strong><br>
  +    These new functions do <b>not</b> call <code>pstrdup</code>
  +    on their arguments.  This provides for big speedups.  There is
  +    also some debugging support to ensure code uses them properly.
  +    See <code>src/CHANGES</code> for more information.
   
       </UL>
   
  
  
  
  1.600     +20 -0     apachen/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/CHANGES,v
  retrieving revision 1.599
  retrieving revision 1.600
  diff -u -r1.599 -r1.600
  --- CHANGES   1998/01/25 03:52:15     1.599
  +++ CHANGES   1998/01/26 19:50:08     1.600
  @@ -1,5 +1,25 @@
   Changes with Apache 1.3b4
   
  +  *) table_add, table_merge, and table_set include implicit pstrdup()
  +     of the key and value.  But in many cases this is not required
  +     because the key/value is a constant, or the value has been built
  +     by pstrcat() or other similar means.  New routines table_addn,
  +     table_mergen, and table_setn have been added to the API, these
  +     routines do not pstrdup() their arguments.  The core code and
  +     standard modules were changed to take advantage of these routines.
  +     The resulting server is up to 20% faster in some situations.
  +
  +     Note that it is easy to get code subtly wrong if you pass a key/value
  +     which is in a pool other than the pool of the table.  The only
  +     safe thing to do is to pass key/values which are in the pool of
  +     the table, or in one of the ancestors of the pool of the table.
  +     i.e. if the table is part of a subrequest, a value from the main
  +     request's pool is OK since the subrequest pool is a sub_pool of the
  +     main request's pool (and therefore has a lifespan at most as long as
  +     the main pool).  There is debugging code which can detect improper
  +     usage, enabled by defining POOL_DEBUG.  See alloc.c for more details.
  +     [Dmitry Khrustalev <[EMAIL PROTECTED]>, Dean Gaudet]
  +
     *) More mod_mime_magic cleanup:  fewer syscalls; should handle "files"
        which don't exist on disk more gracefully; handles vhosts properly.
        Update documentation to reflect the code -- if there's no
  
  
  
  1.69      +255 -7    apachen/src/main/alloc.c
  
  Index: alloc.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/alloc.c,v
  retrieving revision 1.68
  retrieving revision 1.69
  diff -u -r1.68 -r1.69
  --- alloc.c   1998/01/24 19:00:21     1.68
  +++ alloc.c   1998/01/26 19:50:10     1.69
  @@ -88,6 +88,24 @@
    */
   /* #define ALLOC_USE_MALLOC */
   
  +/* Pool debugging support.  This is intended to detect cases where the
  + * wrong pool is used when assigning data to an object in another pool.
  + * In particular, it causes the table_{set,add,merge}n routines to check
  + * that their arguments are safe for the table they're being placed in.
  + * It currently only works with the unix multiprocess model, but could
  + * be extended to others.
  + */
  +/* #define POOL_DEBUG */
  +
  +#ifdef POOL_DEBUG
  +#ifdef ALLOC_USE_MALLOC
  +# error "sorry, no support for ALLOC_USE_MALLOC and POOL_DEBUG at the same 
time"
  +#endif
  +#ifdef MULTITHREAD
  +# error "sorry, no support for MULTITHREAD and POOL_DEBUG at the same time"
  +#endif
  +#endif
  +
   #ifdef ALLOC_USE_MALLOC
   #undef BLOCK_MINFREE
   #undef BLOCK_MINALLOC
  @@ -124,12 +142,22 @@
        char *endp;
        union block_hdr *next;
        char *first_avail;
  +#ifdef POOL_DEBUG
  +     union block_hdr *global_next;
  +     struct pool *owning_pool;
  +#endif
       } h;
   };
   
   union block_hdr *block_freelist = NULL;
   mutex *alloc_mutex = NULL;
   mutex *spawn_mutex = NULL;
  +#ifdef POOL_DEBUG
  +static char *known_stack_point;
  +static int stack_direction;
  +static union block_hdr *global_block_list;
  +#define FREE_POOL    ((struct pool *)(-1))
  +#endif
   
   #ifdef ALLOC_DEBUG
   #define FILL_BYTE    ((char)(0xa5))
  @@ -170,16 +198,20 @@
       blok->h.next = NULL;
       blok->h.first_avail = (char *) (blok + 1);
       blok->h.endp = size + blok->h.first_avail;
  +#ifdef POOL_DEBUG
  +    blok->h.global_next = global_block_list;
  +    global_block_list = blok;
  +    blok->h.owning_pool = NULL;
  +#endif
   
       return blok;
   }
   
   
   
  -void chk_on_blk_list(union block_hdr *blok, union block_hdr *free_blk)
  +#ifdef ALLOC_DEBUG
  +static void chk_on_blk_list(union block_hdr *blok, union block_hdr *free_blk)
   {
  -    /* Debugging code.  Left in for the moment. */
  -
       while (free_blk) {
        if (free_blk == blok) {
            fprintf(stderr, "Ouch!  Freeing free block\n");
  @@ -189,6 +221,9 @@
        free_blk = free_blk->h.next;
       }
   }
  +#else
  +#define chk_on_blk_list(_x, _y)
  +#endif
   
   /* Free a chain of blocks --- must be called with alarms blocked. */
   
  @@ -226,12 +261,18 @@
        chk_on_blk_list(blok, old_free_list);
        blok->h.first_avail = (char *) (blok + 1);
        debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
  +#ifdef POOL_DEBUG
  +     blok->h.owning_pool = FREE_POOL;
  +#endif
        blok = blok->h.next;
       }
   
       chk_on_blk_list(blok, old_free_list);
       blok->h.first_avail = (char *) (blok + 1);
       debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
  +#ifdef POOL_DEBUG
  +    blok->h.owning_pool = FREE_POOL;
  +#endif
   
       /* Finally, reset next pointer to get the old free blocks back */
   
  @@ -346,6 +387,9 @@
       blok = new_block(POOL_HDR_BYTES);
       new_pool = (pool *) blok->h.first_avail;
       blok->h.first_avail += POOL_HDR_BYTES;
  +#ifdef POOL_DEBUG
  +    blok->h.owning_pool = new_pool;
  +#endif
   
       memset((char *) new_pool, '\0', sizeof(struct pool));
       new_pool->free_first_avail = blok->h.first_avail;
  @@ -365,8 +409,28 @@
       return new_pool;
   }
   
  +#ifdef POOL_DEBUG
  +static void stack_var_init(char *s)
  +{
  +    char t;
  +
  +    if (s < &t) {
  +     stack_direction = 1; /* stack grows up */
  +    }
  +    else {
  +     stack_direction = -1; /* stack grows down */
  +    }
  +}
  +#endif
  +
   void init_alloc(void)
   {
  +#ifdef POOL_DEBUG
  +    char s;
  +
  +    known_stack_point = &s;
  +    stack_var_init(&s);
  +#endif
       alloc_mutex = create_mutex(NULL);
       spawn_mutex = create_mutex(NULL);
       permanent_pool = make_sub_pool(NULL);
  @@ -442,6 +506,87 @@
   }
   
   /*****************************************************************
  + * POOL_DEBUG support
  + */
  +#ifdef POOL_DEBUG
  +
  +/* the unix linker defines this symbol as the last byte + 1 of
  + * the executable... so it includes TEXT, BSS, and DATA
  + */
  +extern char _end;
  +
  +/* is ptr in the range [lo,hi) */
  +#define is_ptr_in_range(ptr, lo, hi) \
  +    (((unsigned long)(ptr) - (unsigned long)(lo)) \
  +     < \
  +     (unsigned long)(hi) - (unsigned long)(lo))
  +
  +/* Find the pool that ts belongs to, return NULL if it doesn't
  + * belong to any pool.
  + */
  +pool *find_pool(const void *ts)
  +{
  +    const char *s = ts;
  +    union block_hdr **pb;
  +    union block_hdr *b;
  +
  +    /* short-circuit stuff which is in TEXT, BSS, or DATA */
  +    if (is_ptr_in_range(s, 0, &_end)) {
  +     return NULL;
  +    }
  +    /* consider stuff on the stack to also be in the NULL pool...
  +     * XXX: there's cases where we don't want to assume this
  +     */
  +    if ((stack_direction == -1 && is_ptr_in_range(s, &ts, known_stack_point))
  +     || (stack_direction == 1 && is_ptr_in_range(s, known_stack_point, 
&ts))) {
  +     abort();
  +     return NULL;
  +    }
  +    block_alarms();
  +    /* search the global_block_list */
  +    for (pb = &global_block_list; *pb; pb = &b->h.global_next) {
  +     b = *pb;
  +     if (is_ptr_in_range(s, b, b->h.endp)) {
  +         if (b->h.owning_pool == FREE_POOL) {
  +             fprintf(stderr,
  +                 "Ouch!  find_pool() called on pointer in a free block\n");
  +             abort();
  +             exit(1);
  +         }
  +         if (b != global_block_list) {
  +             /* promote b to front of list, this is a hack to speed
  +              * up the lookup */
  +             *pb = b->h.global_next;
  +             b->h.global_next = global_block_list;
  +             global_block_list = b;
  +         }
  +         unblock_alarms();
  +         return b->h.owning_pool;
  +     }
  +    }
  +    unblock_alarms();
  +    return NULL;
  +}
  +
  +/* return TRUE iff a is an ancestor of b
  + * NULL is considered an ancestor of all pools
  + */
  +int pool_is_ancestor(pool *a, pool *b)
  +{
  +    if (a == NULL) {
  +     return 1;
  +    }
  +    while (b) {
  +     if (a == b) {
  +         return 1;
  +     }
  +     b = b->parent;
  +    }
  +    return 0;
  +}
  +#endif
  +
  +/*****************************************************************
    *
    * Allocating stuff...
    */
  @@ -501,6 +646,9 @@
       blok = new_block(size);
       a->last->h.next = blok;
       a->last = blok;
  +#ifdef POOL_DEBUG
  +    blok->h.owning_pool = a;
  +#endif
   
       (void) release_mutex(alloc_mutex);
   
  @@ -523,10 +671,13 @@
   API_EXPORT(char *) pstrdup(struct pool *a, const char *s)
   {
       char *res;
  +    size_t len;
  +
       if (s == NULL)
        return NULL;
  -    res = palloc(a, strlen(s) + 1);
  -    strcpy(res, s);
  +    len = strlen(s) + 1;
  +    res = palloc(a, len);
  +    memcpy(res, s, len);
       return res;
   }
   
  @@ -781,6 +932,52 @@
       }
   }
   
  +API_EXPORT(void) table_setn(table *t, char *key, char *val)
  +{
  +    register int i, j, k;
  +    table_entry *elts = (table_entry *) t->a.elts;
  +    int done = 0;
  +
  +#ifdef POOL_DEBUG
  +    {
  +     if (!pool_is_ancestor(find_pool(key), t->a.pool)) {
  +         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  +         abort();
  +     }
  +     if (!pool_is_ancestor(find_pool(val), t->a.pool)) {
  +         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  +         abort();
  +     }
  +    }
  +#endif
  +
  +    for (i = 0; i < t->a.nelts; ) {
  +     if (!strcasecmp(elts[i].key, key)) {
  +         if (!done) {
  +             elts[i].val =  val;
  +             done = 1;
  +             ++i;
  +         }
  +         else {              /* delete an extraneous element */
  +             for (j = i, k = i + 1; k < t->a.nelts; ++j, ++k) {
  +                 elts[j].key = elts[k].key;
  +                 elts[j].val = elts[k].val;
  +             }
  +             --t->a.nelts;
  +         }
  +     }
  +     else {
  +         ++i;
  +     }
  +    }
  +
  +    if (!done) {
  +     elts = (table_entry *) push_array(&t->a);
  +     elts->key = key;
  +     elts->val = val;
  +    }
  +}
  +
   API_EXPORT(void) table_unset(table *t, const char *key)
   {
       register int i, j, k;
  @@ -811,18 +1008,47 @@
       table_entry *elts = (table_entry *) t->a.elts;
       int i;
   
  -    for (i = 0; i < t->a.nelts; ++i) {
  +    for (i = 0; i < t->a.nelts; ++i)
        if (!strcasecmp(elts[i].key, key)) {
            elts[i].val = pstrcat(t->a.pool, elts[i].val, ", ", val, NULL);
            return;
        }
  -    }
   
       elts = (table_entry *) push_array(&t->a);
       elts->key = pstrdup(t->a.pool, key);
       elts->val = pstrdup(t->a.pool, val);
   }
   
  +API_EXPORT(void) table_mergen(table *t, char *key, char *val)
  +{
  +    table_entry *elts = (table_entry *) t->a.elts;
  +    int i;
  +
  +#ifdef POOL_DEBUG
  +    {
  +     if (!pool_is_ancestor(find_pool(key), t->a.pool)) {
  +         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  +         abort();
  +     }
  +     if (!pool_is_ancestor(find_pool(val), t->a.pool)) {
  +         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  +         abort();
  +     }
  +    }
  +#endif
  +
  +    for (i = 0; i < t->a.nelts; ++i) {
  +     if (!strcasecmp(elts[i].key, key)) {
  +         elts[i].val = pstrcat(t->a.pool, elts[i].val, ", ", val, NULL);
  +         return;
  +     }
  +    }
  +
  +    elts = (table_entry *) push_array(&t->a);
  +    elts->key = key;
  +    elts->val = val;
  +}
  +
   API_EXPORT(void) table_add(table *t, const char *key, const char *val)
   {
       table_entry *elts = (table_entry *) t->a.elts;
  @@ -830,6 +1056,28 @@
       elts = (table_entry *) push_array(&t->a);
       elts->key = pstrdup(t->a.pool, key);
       elts->val = pstrdup(t->a.pool, val);
  +}
  +
  +API_EXPORT(void) table_addn(table *t, char *key, char *val)
  +{
  +    table_entry *elts = (table_entry *) t->a.elts;
  +
  +#ifdef POOL_DEBUG
  +    {
  +     if (!pool_is_ancestor(find_pool(key), t->a.pool)) {
  +         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  +         abort();
  +     }
  +     if (!pool_is_ancestor(find_pool(val), t->a.pool)) {
  +         fprintf(stderr, "table_set: key not in ancestor pool of t\n");
  +         abort();
  +     }
  +    }
  +#endif
  +
  +    elts = (table_entry *) push_array(&t->a);
  +    elts->key = key;
  +    elts->val = val;
   }
   
   API_EXPORT(table *) overlay_tables(pool *p, const table *overlay, const 
table *base)
  
  
  
  1.43      +3 -0      apachen/src/main/alloc.h
  
  Index: alloc.h
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/alloc.h,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- alloc.h   1998/01/24 20:02:19     1.42
  +++ alloc.h   1998/01/26 19:50:10     1.43
  @@ -155,9 +155,12 @@
   API_EXPORT(void) clear_table(table *);
   API_EXPORT(char *) table_get(const table *, const char *);
   API_EXPORT(void) table_set(table *, const char *name, const char *val);
  +API_EXPORT(void) table_setn(table *, char *name, char *val);
   API_EXPORT(void) table_merge(table *, const char *name, const char 
*more_val);
  +API_EXPORT(void) table_mergen(table *, char *name, char *more_val);
   API_EXPORT(void) table_unset(table *, const char *key);
   API_EXPORT(void) table_add(table *, const char *name, const char *val);
  +API_EXPORT(void) table_addn(table *, char *name, char *val);
   API_EXPORT(void) table_do(int (*comp) (void *, const char *, const char *), 
void *rec,
                          const table *t,...);
   
  
  
  
  1.62      +1 -1      apachen/src/main/http_config.h
  
  Index: http_config.h
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/http_config.h,v
  retrieving revision 1.61
  retrieving revision 1.62
  diff -u -r1.61 -r1.62
  --- http_config.h     1998/01/21 19:17:37     1.61
  +++ http_config.h     1998/01/26 19:50:11     1.62
  @@ -253,7 +253,7 @@
    * handle it back-compatibly, or at least signal an error).
    */
   
  -#define MODULE_MAGIC_NUMBER 19971226
  +#define MODULE_MAGIC_NUMBER 19980126
   #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, -1, __FILE__, NULL
   
   /* Generic accessors for other modules to get at their own module-specific
  
  
  
  1.150     +2 -2      apachen/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/http_core.c,v
  retrieving revision 1.149
  retrieving revision 1.150
  diff -u -r1.149 -r1.150
  --- http_core.c       1998/01/26 18:24:31     1.149
  +++ http_core.c       1998/01/26 19:50:12     1.150
  @@ -1931,7 +1931,7 @@
   #endif
   
        if (d->content_md5 & 1) {
  -         table_set (r->headers_out, "Content-MD5", ap_md5digest(r->pool, f));
  +         table_setn(r->headers_out, "Content-MD5", ap_md5digest(r->pool, f));
        }
   
        rangestatus = set_byterange(r);
  @@ -1975,7 +1975,7 @@
            
            MD5Init(&context);
            MD5Update(&context, (void *)mm, r->finfo.st_size);
  -         table_set (r->headers_out, "Content-MD5",
  +         table_setn(r->headers_out, "Content-MD5",
                ap_md5contextTo64(r->pool, &context));
        }
   
  
  
  
  1.181     +30 -27    apachen/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/http_protocol.c,v
  retrieving revision 1.180
  retrieving revision 1.181
  diff -u -r1.180 -r1.181
  --- http_protocol.c   1998/01/26 18:24:33     1.180
  +++ http_protocol.c   1998/01/26 19:50:13     1.181
  @@ -138,7 +138,7 @@
           range = table_get(r->headers_in, "Request-Range");
   
       if (!range || strncmp(range, "bytes=", 6)) {
  -        table_set(r->headers_out, "Accept-Ranges", "bytes");
  +        table_setn(r->headers_out, "Accept-Ranges", "bytes");
           return 0;
       }
   
  @@ -165,9 +165,9 @@
   
           ap_snprintf(ts, sizeof(ts), "bytes %ld-%ld/%ld",
                       range_start, range_end, r->clength);
  -        table_set(r->headers_out, "Content-Range", ts);
  +        table_setn(r->headers_out, "Content-Range", pstrdup(r->pool, ts));
           ap_snprintf(ts, sizeof(ts), "%ld", range_end - range_start + 1);
  -        table_set(r->headers_out, "Content-Length", ts);
  +        table_setn(r->headers_out, "Content-Length", pstrdup(r->pool, ts));
       }
       else {
           /* a multiple range */
  @@ -181,7 +181,7 @@
           r->boundary = pstrdup(r->pool, boundary);
           while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL));
           ap_snprintf(ts, sizeof(ts), "%ld", tlength);
  -        table_set(r->headers_out, "Content-Length", ts);
  +        table_setn(r->headers_out, "Content-Length", pstrdup(r->pool, ts));
       }
   
       r->status = PARTIAL_CONTENT;
  @@ -259,7 +259,7 @@
       r->clength = clength;
   
       ap_snprintf(ts, sizeof(ts), "%ld", clength);
  -    table_set(r->headers_out, "Content-Length", ts);
  +    table_setn(r->headers_out, "Content-Length", pstrdup(r->pool, ts));
   
       return 0;
   }
  @@ -331,8 +331,8 @@
               else
                   ap_snprintf(header, sizeof(header), "timeout=%d",
                               r->server->keep_alive_timeout);
  -            table_set(r->headers_out, "Keep-Alive", header);
  -            table_merge(r->headers_out, "Connection", "Keep-Alive");
  +            table_setn(r->headers_out, "Keep-Alive", pstrdup(r->pool, 
header));
  +            table_mergen(r->headers_out, "Connection", "Keep-Alive");
           }
   
           return 1;
  @@ -347,7 +347,7 @@
        * to a HTTP/1.1 client. Better safe than sorry.
        */
       if (!wimpy)
  -      table_merge(r->headers_out, "Connection", "close");
  +     table_mergen(r->headers_out, "Connection", "close");
   
       r->connection->keepalive = 0;
   
  @@ -502,7 +502,7 @@
       }
   
       etag = weak_etag + ((r->request_time - r->mtime > 1) ? 2 : 0);
  -    table_set(r->headers_out, "ETag", etag);
  +    table_setn(r->headers_out, "ETag", pstrdup(r->pool, etag));
   }
   
   /*
  @@ -514,7 +514,7 @@
   {
       time_t mod_time = rationalize_mtime(r, r->mtime);
   
  -    table_set(r->headers_out, "Last-Modified",
  +    table_setn(r->headers_out, "Last-Modified",
                 gm_timestr_822(r->pool, mod_time));
   }
   
  @@ -753,8 +753,10 @@
        * overflow (len == MAX_STRING_LEN-1)?
        */
       while ((len = getline(field, MAX_STRING_LEN, c->client, 1)) > 0) {
  +        char *copy = palloc(r->pool, len + 1);
  +        memcpy(copy, field, len + 1);
   
  -        if (!(value = strchr(field, ':')))      /* Find the colon separator 
*/
  +        if (!(value = strchr(copy, ':')))      /* Find the colon separator */
               continue;           /* or should puke 400 here */
   
           *value = '\0';
  @@ -762,7 +764,7 @@
           while (isspace(*value))
               ++value;            /* Skip to start of value   */
   
  -        table_merge(r->headers_in, field, value);
  +        table_mergen(r->headers_in, copy, value);
       }
   }
   
  @@ -909,7 +911,7 @@
       if (strcasecmp(auth_type(r), "Basic"))
           note_auth_failure(r);
       else
  -        table_set(r->err_headers_out,
  +        table_setn(r->err_headers_out,
                     r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
                     pstrcat(r->pool, "Basic realm=\"", auth_name(r), "\"",
                             NULL));
  @@ -920,7 +922,7 @@
       char nonce[256];
   
       ap_snprintf(nonce, sizeof(nonce), "%lu", r->request_time);
  -    table_set(r->err_headers_out,
  +    table_setn(r->err_headers_out,
                 r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
                 pstrcat(r->pool, "Digest realm=\"", auth_name(r),
                         "\", nonce=\"", nonce, "\"", NULL));
  @@ -1187,8 +1189,8 @@
   
       basic_http_header(r);
   
  -    table_set(r->headers_out, "Content-Length", "0");
  -    table_set(r->headers_out, "Allow", make_allow(r));
  +    table_setn(r->headers_out, "Content-Length", "0");
  +    table_setn(r->headers_out, "Allow", make_allow(r));
       set_keepalive(r);
   
       table_do((int (*) (void *, const char *, const char *)) 
send_header_field,
  @@ -1252,37 +1254,37 @@
       set_keepalive(r);
   
       if (r->chunked) {
  -        table_merge(r->headers_out, "Transfer-Encoding", "chunked");
  +        table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
           table_unset(r->headers_out, "Content-Length");
       }
   
       if (r->byterange > 1)
  -        table_set(r->headers_out, "Content-Type",
  +        table_setn(r->headers_out, "Content-Type",
                     pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/",
                             "byteranges; boundary=", r->boundary, NULL));
       else if (r->content_type)
  -        table_set(r->headers_out, "Content-Type", r->content_type);
  +        table_setn(r->headers_out, "Content-Type", r->content_type);
       else
  -        table_set(r->headers_out, "Content-Type", default_type(r));
  +        table_setn(r->headers_out, "Content-Type", default_type(r));
   
       if (r->content_encoding)
  -        table_set(r->headers_out, "Content-Encoding", r->content_encoding);
  +        table_setn(r->headers_out, "Content-Encoding", r->content_encoding);
   
       if (r->content_languages && r->content_languages->nelts) {
           for (i = 0; i < r->content_languages->nelts; ++i) {
  -            table_merge(r->headers_out, "Content-Language",
  +            table_mergen(r->headers_out, "Content-Language",
                           ((char **) (r->content_languages->elts))[i]);
           }
       }
       else if (r->content_language)
  -        table_set(r->headers_out, "Content-Language", r->content_language);
  +        table_setn(r->headers_out, "Content-Language", r->content_language);
   
       /*
        * Control cachability for non-cachable responses if not already set by
        * some other part of the server configuration.
        */
       if (r->no_cache && !table_get(r->headers_out, "Expires"))
  -        table_add(r->headers_out, "Expires",
  +        table_addn(r->headers_out, "Expires",
                     gm_timestr_822(r->pool, r->request_time));
   
       /* Send the entire table of header fields, terminated by an empty line. 
*/
  @@ -1511,7 +1513,8 @@
                   get_mime_headers(r);
                   ap_snprintf(buffer, bufsiz, "%ld", r->read_length);
                   table_unset(r->headers_in, "Transfer-Encoding");
  -                table_set(r->headers_in, "Content-Length", buffer);
  +                table_setn(r->headers_in, "Content-Length",
  +                    pstrdup(r->pool, buffer));
                   return 0;
               }
               r->remaining = -1;  /* Indicate footers in-progress */
  @@ -1996,7 +1999,7 @@
   
           if (location && *location
               && (is_HTTP_REDIRECT(status) || status == HTTP_CREATED))
  -            table_set(r->headers_out, "Location", location);
  +            table_setn(r->headers_out, "Location", location);
   
           r->content_language = NULL;
           r->content_languages = NULL;
  @@ -2005,7 +2008,7 @@
           r->content_type = "text/html";
   
           if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
  -            table_set(r->headers_out, "Allow", make_allow(r));
  +            table_setn(r->headers_out, "Allow", make_allow(r));
   
           send_http_header(r);
   
  
  
  
  1.101     +4 -4      apachen/src/main/http_request.c
  
  Index: http_request.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/http_request.c,v
  retrieving revision 1.100
  retrieving revision 1.101
  diff -u -r1.100 -r1.101
  --- http_request.c    1998/01/21 22:48:13     1.100
  +++ http_request.c    1998/01/26 19:50:13     1.101
  @@ -903,7 +903,7 @@
                * status...
                */
               r->status = REDIRECT;
  -            table_set(r->headers_out, "Location", custom_response);
  +            table_setn(r->headers_out, "Location", custom_response);
           }
           else if (custom_response[0] == '/') {
               r->no_local_copy = 1;       /* Do NOT send USE_LOCAL_COPY for
  @@ -912,7 +912,7 @@
                * This redirect needs to be a GET no matter what the original
                * method was.
                */
  -            table_set(r->subprocess_env, "REQUEST_METHOD", r->method);
  +            table_setn(r->subprocess_env, "REQUEST_METHOD", r->method);
               r->method = pstrdup(r->pool, "GET");
               r->method_number = M_GET;
               internal_redirect(custom_response, r);
  @@ -1168,7 +1168,7 @@
       for (i = 0; i < env_arr->nelts; ++i) {
           if (!elts[i].key)
               continue;
  -        table_set(new, pstrcat(p, "REDIRECT_", elts[i].key, NULL),
  +        table_setn(new, pstrcat(p, "REDIRECT_", elts[i].key, NULL),
                     elts[i].val);
       }
   
  @@ -1228,7 +1228,7 @@
       new->read_length     = r->read_length;     /* We can only read it once */
   
       ap_snprintf(t, sizeof(t), "%d", r->status);
  -    table_set(new->subprocess_env, "REDIRECT_STATUS", t);
  +    table_setn(new->subprocess_env, "REDIRECT_STATUS", pstrdup(r->pool, t));
   
       /*
        * XXX: hmm.  This is because mod_setenvif and mod_unique_id really need
  
  
  
  1.93      +40 -40    apachen/src/main/util_script.c
  
  Index: util_script.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/main/util_script.c,v
  retrieving revision 1.92
  retrieving revision 1.93
  diff -u -r1.92 -r1.93
  --- util_script.c     1998/01/21 22:31:46     1.92
  +++ util_script.c     1998/01/26 19:50:14     1.93
  @@ -205,9 +205,9 @@
         */
   
        if (!strcasecmp(hdrs[i].key, "Content-type"))
  -         table_set(e, "CONTENT_TYPE", hdrs[i].val);
  +         table_setn(e, "CONTENT_TYPE", hdrs[i].val);
        else if (!strcasecmp(hdrs[i].key, "Content-length"))
  -         table_set(e, "CONTENT_LENGTH", hdrs[i].val);
  +         table_setn(e, "CONTENT_LENGTH", hdrs[i].val);
        /*
         * You really don't want to disable this check, since it leaves you
         * wide open to CGIs stealing passwords and people viewing them
  @@ -218,7 +218,7 @@
            continue;
   #endif
        else
  -         table_set(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
  +         table_setn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
       }
   
       ap_snprintf(port, sizeof(port), "%u", s->port);
  @@ -228,42 +228,42 @@
   
   #ifdef WIN32
       if (env_temp = getenv("SystemRoot"))
  -        table_set(e, "SystemRoot", env_temp);         
  +        table_setn(e, "SystemRoot", env_temp);         
       if (env_temp = getenv("COMSPEC"))
  -        table_set(e, "COMSPEC", env_temp);            
  +        table_setn(e, "COMSPEC", env_temp);            
       if (env_temp = getenv("WINDIR"))
  -        table_set(e, "WINDIR", env_temp);             
  +        table_setn(e, "WINDIR", env_temp);             
   #endif
   
  -    table_set(e, "PATH", env_path);
  -    table_set(e, "SERVER_SOFTWARE", SERVER_VERSION);
  -    table_set(e, "SERVER_NAME", s->server_hostname);
  -    table_set(e, "SERVER_PORT", port);
  -    table_set(e, "REMOTE_HOST",
  -           get_remote_host(c, r->per_dir_config, REMOTE_NAME));
  -    table_set(e, "REMOTE_ADDR", c->remote_ip);
  -    table_set(e, "DOCUMENT_ROOT", document_root(r)); /* Apache */
  -    table_set(e, "SERVER_ADMIN", s->server_admin);   /* Apache */
  -    table_set(e, "SCRIPT_FILENAME", r->filename);    /* Apache */
  +    table_setn(e, "PATH", env_path);
  +    table_setn(e, "SERVER_SOFTWARE", SERVER_VERSION);
  +    table_setn(e, "SERVER_NAME", s->server_hostname);
  +    table_setn(e, "SERVER_PORT", pstrdup(r->pool,port));
  +    table_setn(e, "REMOTE_HOST",
  +        pstrdup(r->pool, get_remote_host(c, r->per_dir_config, 
REMOTE_NAME)));
  +    table_setn(e, "REMOTE_ADDR", c->remote_ip);
  +    table_setn(e, "DOCUMENT_ROOT", document_root(r));        /* Apache */
  +    table_setn(e, "SERVER_ADMIN", s->server_admin);  /* Apache */
  +    table_setn(e, "SCRIPT_FILENAME", r->filename);   /* Apache */
   
       ap_snprintf(port, sizeof(port), "%d", ntohs(c->remote_addr.sin_port));
  -    table_set(e, "REMOTE_PORT", port);       /* Apache */
  +    table_setn(e, "REMOTE_PORT", pstrdup(r->pool, port)); /* Apache */
   
       if (c->user)
  -     table_set(e, "REMOTE_USER", c->user);
  +     table_setn(e, "REMOTE_USER", c->user);
       if (c->auth_type)
  -     table_set(e, "AUTH_TYPE", c->auth_type);
  +     table_setn(e, "AUTH_TYPE", c->auth_type);
       rem_logname = get_remote_logname(r);
       if (rem_logname)
  -     table_set(e, "REMOTE_IDENT", rem_logname);
  +     table_setn(e, "REMOTE_IDENT", pstrdup(r->pool, rem_logname));
   
       /* Apache custom error responses. If we have redirected set two new vars 
*/
   
       if (r->prev) {
        if (r->prev->args)
  -         table_set(e, "REDIRECT_QUERY_STRING", r->prev->args);
  +         table_setn(e, "REDIRECT_QUERY_STRING", r->prev->args);
        if (r->prev->uri)
  -         table_set(e, "REDIRECT_URL", r->prev->uri);
  +         table_setn(e, "REDIRECT_URL", r->prev->uri);
       }
   }
   
  @@ -316,11 +316,11 @@
   {
       table *e = r->subprocess_env;
   
  -    table_set(e, "GATEWAY_INTERFACE", "CGI/1.1");
  -    table_set(e, "SERVER_PROTOCOL", r->protocol);
  -    table_set(e, "REQUEST_METHOD", r->method);
  -    table_set(e, "QUERY_STRING", r->args ? r->args : "");
  -    table_set(e, "REQUEST_URI", original_uri(r));
  +    table_setn(e, "GATEWAY_INTERFACE", "CGI/1.1");
  +    table_setn(e, "SERVER_PROTOCOL", r->protocol);
  +    table_setn(e, "REQUEST_METHOD", r->method);
  +    table_setn(e, "QUERY_STRING", r->args ? r->args : "");
  +    table_setn(e, "REQUEST_URI", original_uri(r));
   
       /* Note that the code below special-cases scripts run from includes,
        * because it "knows" that the sub_request has been hacked to have the
  @@ -329,20 +329,20 @@
        */
   
       if (!strcmp(r->protocol, "INCLUDED")) {
  -     table_set(e, "SCRIPT_NAME", r->uri);
  +     table_setn(e, "SCRIPT_NAME", r->uri);
        if (r->path_info && *r->path_info)
  -         table_set(e, "PATH_INFO", r->path_info);
  +         table_setn(e, "PATH_INFO", r->path_info);
       }
       else if (!r->path_info || !*r->path_info) {
  -     table_set(e, "SCRIPT_NAME", r->uri);
  +     table_setn(e, "SCRIPT_NAME", r->uri);
       }
       else {
        int path_info_start = find_path_info(r->uri, r->path_info);
   
  -     table_set(e, "SCRIPT_NAME", pstrndup(r->pool, r->uri,
  +     table_setn(e, "SCRIPT_NAME", pstrndup(r->pool, r->uri,
                                             path_info_start));
   
  -     table_set(e, "PATH_INFO", r->path_info);
  +     table_setn(e, "PATH_INFO", r->path_info);
       }
   
       if (r->path_info && r->path_info[0]) {
  @@ -370,9 +370,9 @@
   #ifdef WIN32
            /* We need to make this a real Windows path name */
            GetFullPathName(pt, HUGE_STRING_LEN, buffer, NULL);
  -         table_set(e, "PATH_TRANSLATED", buffer);
  +         table_setn(e, "PATH_TRANSLATED", pstrdup(r->pool, buffer));
   #else
  -         table_set(e, "PATH_TRANSLATED", pt);
  +         table_setn(e, "PATH_TRANSLATED", pt);
   #endif
        }
       }
  @@ -471,13 +471,13 @@
            r->status_line = pstrdup(r->pool, l);
        }
        else if (!strcasecmp(w, "Location")) {
  -         table_set(r->headers_out, w, l);
  +         table_setn(r->headers_out, pstrdup(r->pool,w), pstrdup(r->pool,l));
        }
        else if (!strcasecmp(w, "Content-Length")) {
  -         table_set(r->headers_out, w, l);
  +         table_setn(r->headers_out, pstrdup(r->pool,w), pstrdup(r->pool,l));
        }
        else if (!strcasecmp(w, "Transfer-Encoding")) {
  -         table_set(r->headers_out, w, l);
  +         table_setn(r->headers_out, pstrdup(r->pool,w), pstrdup(r->pool,l));
        }
        /*
         * If the script gave us a Last-Modified header, we can't just
  @@ -494,7 +494,7 @@
         * we'll use - otherwise we assume 200 OK.
         */
        else if (!strcasecmp(w, "Status")) {
  -         table_set(r->headers_out, w, l);
  +         table_setn(r->headers_out, pstrdup(r->pool,w), pstrdup(r->pool,l));
            cgi_status = atoi(l);
        }
   
  @@ -504,10 +504,10 @@
         * separately.  Lets humour those browsers.
         */
        else if (!strcasecmp(w, "Set-Cookie")) {
  -         table_add(r->err_headers_out, w, l);
  +         table_addn(r->err_headers_out, pstrdup(r->pool,w), 
pstrdup(r->pool,l));
        }
        else {
  -         table_merge(r->err_headers_out, w, l);
  +         table_mergen(r->err_headers_out, pstrdup(r->pool,w), 
pstrdup(r->pool,l));
        }
       }
   }
  
  
  
  1.33      +1 -1      apachen/src/modules/proxy/mod_proxy.c
  
  Index: mod_proxy.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/proxy/mod_proxy.c,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- mod_proxy.c       1998/01/24 20:30:07     1.32
  +++ mod_proxy.c       1998/01/26 19:50:17     1.33
  @@ -251,7 +251,7 @@
                       host, domain, strport, "/", path,
                       NULL);
   
  -     table_set(r->headers_out, "Location", nuri);
  +     table_setn(r->headers_out, "Location", nuri);
        aplog_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server,
            "Domain missing: %s sent to %s from %s", r->uri, nuri,
            ref ? ref : "-");
  
  
  
  1.30      +3 -3      apachen/src/modules/standard/mod_alias.c
  
  Index: mod_alias.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_alias.c,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- mod_alias.c       1998/01/07 16:46:43     1.29
  +++ mod_alias.c       1998/01/26 19:50:19     1.30
  @@ -328,7 +328,7 @@
        if (found) {
            if (p->handler) {   /* Set handler, and leave a note for mod_cgi */
                r->handler = pstrdup(r->pool, p->handler);
  -             table_set(r->notes, "alias-forced-type", p->handler);
  +             table_setn(r->notes, "alias-forced-type", r->handler);
            }
   
            *status = p->redir_status;
  @@ -363,7 +363,7 @@
            if (r->args) {
                ret = pstrcat(r->pool, ret, "?", r->args, NULL);
            }
  -         table_set(r->headers_out, "Location", ret);
  +         table_setn(r->headers_out, "Location", ret);
        }
        return status;
       }
  @@ -388,7 +388,7 @@
   
       if ((ret = try_alias_list(r, dirconf->redirects, 1, &status)) != NULL) {
        if (is_HTTP_REDIRECT(status))
  -         table_set(r->headers_out, "Location", ret);
  +         table_setn(r->headers_out, "Location", ret);
        return status;
       }
   
  
  
  
  1.45      +1 -1      apachen/src/modules/standard/mod_dir.c
  
  Index: mod_dir.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_dir.c,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -r1.44 -r1.45
  --- mod_dir.c 1998/01/07 16:46:47     1.44
  +++ mod_dir.c 1998/01/26 19:50:19     1.45
  @@ -117,7 +117,7 @@
               ifile = pstrcat(r->pool, escape_uri(r->pool, r->uri),
                               "/", NULL);
   
  -        table_set(r->headers_out, "Location",
  +        table_setn(r->headers_out, "Location",
                     construct_url(r->pool, ifile, r->server));
           return HTTP_MOVED_PERMANENTLY;
       }
  
  
  
  1.22      +2 -2      apachen/src/modules/standard/mod_expires.c
  
  Index: mod_expires.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_expires.c,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- mod_expires.c     1998/01/07 16:46:49     1.21
  +++ mod_expires.c     1998/01/26 19:50:20     1.22
  @@ -473,11 +473,11 @@
   
       expires = base + additional;
       ap_snprintf(age, sizeof(age), "max-age=%d", (int) expires - (int) 
r->request_time);
  -    table_set(r->headers_out, "Cache-Control", age);
  +    table_setn(r->headers_out, "Cache-Control", pstrdup(r->pool, age));
       tzset();                    /* redundant? called implicitly by 
localtime, at least 
                                    * under FreeBSD
                                    */
  -    table_set(r->headers_out, "Expires", gm_timestr_822(r->pool, expires));
  +    table_setn(r->headers_out, "Expires", gm_timestr_822(r->pool, expires));
       return OK;
   }
   
  
  
  
  1.40      +1 -1      apachen/src/modules/standard/mod_imap.c
  
  Index: mod_imap.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_imap.c,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- mod_imap.c        1998/01/22 23:18:07     1.39
  +++ mod_imap.c        1998/01/26 19:50:20     1.40
  @@ -543,7 +543,7 @@
           return HTTP_NO_CONTENT; /* tell the client to keep the page it has */
       }
       if (redirect && *redirect) {
  -        table_set(r->headers_out, "Location", redirect);
  +        table_setn(r->headers_out, "Location", redirect);
           return REDIRECT;        /* must be a URL, so redirect to it */
       }
       return SERVER_ERROR;
  
  
  
  1.67      +20 -20    apachen/src/modules/standard/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_include.c,v
  retrieving revision 1.66
  retrieving revision 1.67
  diff -u -r1.66 -r1.67
  --- mod_include.c     1998/01/26 16:46:14     1.66
  +++ mod_include.c     1998/01/26 19:50:21     1.67
  @@ -112,36 +112,36 @@
       char *t;
       time_t date = r->request_time;
   
  -    table_set(e, "DATE_LOCAL", ht_time(r->pool, date, timefmt, 0));
  -    table_set(e, "DATE_GMT", ht_time(r->pool, date, timefmt, 1));
  -    table_set(e, "LAST_MODIFIED",
  +    table_setn(e, "DATE_LOCAL", ht_time(r->pool, date, timefmt, 0));
  +    table_setn(e, "DATE_GMT", ht_time(r->pool, date, timefmt, 1));
  +    table_setn(e, "LAST_MODIFIED",
                 ht_time(r->pool, r->finfo.st_mtime, timefmt, 0));
  -    table_set(e, "DOCUMENT_URI", r->uri);
  -    table_set(e, "DOCUMENT_PATH_INFO", r->path_info);
  +    table_setn(e, "DOCUMENT_URI", r->uri);
  +    table_setn(e, "DOCUMENT_PATH_INFO", r->path_info);
   #ifndef WIN32
       pw = getpwuid(r->finfo.st_uid);
       if (pw) {
  -        table_set(e, "USER_NAME", pw->pw_name);
  +        table_setn(e, "USER_NAME", pstrdup(r->pool, pw->pw_name));
       }
       else {
           char uid[16];
           ap_snprintf(uid, sizeof(uid), "user#%lu",
                       (unsigned long) r->finfo.st_uid);
  -        table_set(e, "USER_NAME", uid);
  +        table_setn(e, "USER_NAME", pstrdup(r->pool, uid));
       }
   #endif /* ndef WIN32 */
   
       if ((t = strrchr(r->filename, '/'))) {
  -        table_set(e, "DOCUMENT_NAME", ++t);
  +        table_setn(e, "DOCUMENT_NAME", ++t);
       }
       else {
  -        table_set(e, "DOCUMENT_NAME", r->uri);
  +        table_setn(e, "DOCUMENT_NAME", r->uri);
       }
       if (r->args) {
           char *arg_copy = pstrdup(r->pool, r->args);
   
           unescape_url(arg_copy);
  -        table_set(e, "QUERY_STRING_UNESCAPED",
  +        table_setn(e, "QUERY_STRING_UNESCAPED",
                     escape_shell_cmd(r->pool, arg_copy));
       }
   }
  @@ -740,11 +740,11 @@
       if (r->path_info && r->path_info[0] != '\0') {
           request_rec *pa_req;
   
  -        table_set(env, "PATH_INFO", escape_shell_cmd(r->pool, r->path_info));
  +        table_setn(env, "PATH_INFO", escape_shell_cmd(r->pool, 
r->path_info));
   
           pa_req = sub_req_lookup_uri(escape_uri(r->pool, r->path_info), r);
           if (pa_req->filename) {
  -            table_set(env, "PATH_TRANSLATED",
  +            table_setn(env, "PATH_TRANSLATED",
                         pstrcat(r->pool, pa_req->filename, pa_req->path_info,
                                 NULL));
           }
  @@ -753,9 +753,9 @@
       if (r->args) {
           char *arg_copy = pstrdup(r->pool, r->args);
   
  -        table_set(env, "QUERY_STRING", r->args);
  +        table_setn(env, "QUERY_STRING", r->args);
           unescape_url(arg_copy);
  -        table_set(env, "QUERY_STRING_UNESCAPED",
  +        table_setn(env, "QUERY_STRING_UNESCAPED",
                     escape_shell_cmd(r->pool, arg_copy));
       }
   
  @@ -941,9 +941,9 @@
               time_t date = r->request_time;
   
               parse_string(r, tag_val, tf, MAX_STRING_LEN, 0);
  -            table_set(env, "DATE_LOCAL", ht_time(r->pool, date, tf, 0));
  -            table_set(env, "DATE_GMT", ht_time(r->pool, date, tf, 1));
  -            table_set(env, "LAST_MODIFIED",
  +            table_setn(env, "DATE_LOCAL", ht_time(r->pool, date, tf, 0));
  +            table_setn(env, "DATE_GMT", ht_time(r->pool, date, tf, 1));
  +            table_setn(env, "LAST_MODIFIED",
                         ht_time(r->pool, r->finfo.st_mtime, tf, 0));
           }
           else if (!strcmp(tag, "sizefmt")) {
  @@ -2005,7 +2005,7 @@
                   return -1;
               }
               parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 
0);
  -            table_set(r->subprocess_env, var, parsed_string);
  +            table_setn(r->subprocess_env, var, pstrdup(r->pool, 
parsed_string));
           }
           else {
               aplog_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
  @@ -2070,9 +2070,9 @@
       if (r->args) {              /* add QUERY stuff to env cause it ain't yet 
*/
           char *arg_copy = pstrdup(r->pool, r->args);
   
  -        table_set(r->subprocess_env, "QUERY_STRING", r->args);
  +        table_setn(r->subprocess_env, "QUERY_STRING", r->args);
           unescape_url(arg_copy);
  -        table_set(r->subprocess_env, "QUERY_STRING_UNESCAPED",
  +        table_setn(r->subprocess_env, "QUERY_STRING_UNESCAPED",
                     escape_shell_cmd(r->pool, arg_copy));
       }
   
  
  
  
  1.43      +1 -1      apachen/src/modules/standard/mod_log_config.c
  
  Index: mod_log_config.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_log_config.c,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- mod_log_config.c  1998/01/07 16:46:52     1.42
  +++ mod_log_config.c  1998/01/26 19:50:21     1.43
  @@ -764,7 +764,7 @@
       mls->default_format = NULL;
       mls->server_config_logs = NULL;
       mls->formats = make_table(p, 4);
  -    table_set(mls->formats, "CLF", DEFAULT_LOG_FORMAT);
  +    table_setn(mls->formats, "CLF", DEFAULT_LOG_FORMAT);
   
       return mls;
   }
  
  
  
  1.65      +21 -14    apachen/src/modules/standard/mod_negotiation.c
  
  Index: mod_negotiation.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_negotiation.c,v
  retrieving revision 1.64
  retrieving revision 1.65
  diff -u -r1.64 -r1.65
  --- mod_negotiation.c 1998/01/24 19:00:25     1.64
  +++ mod_negotiation.c 1998/01/26 19:50:22     1.65
  @@ -1889,24 +1889,24 @@
           rec = pstrcat(r->pool, rec, "}", NULL);
   
           if (na_result != na_not_applied) {
  -            table_merge(hdrs, "Alternates", rec);
  +            table_mergen(hdrs, "Alternates", rec);
           }
       }
   
       if (na_result != na_not_applied) {
  -        table_merge(hdrs, "Vary", "negotiate");
  +        table_mergen(hdrs, "Vary", "negotiate");
       }
       if (vary_by_type) {
  -        table_merge(hdrs, "Vary", "accept");
  +        table_mergen(hdrs, "Vary", "accept");
       }
       if (vary_by_language) {
  -        table_merge(hdrs, "Vary", "accept-language");
  +        table_mergen(hdrs, "Vary", "accept-language");
       }
       if (vary_by_charset) {
  -        table_merge(hdrs, "Vary", "accept-charset");
  +        table_mergen(hdrs, "Vary", "accept-charset");
       }
       if (vary_by_encoding && na_result == na_not_applied) {
  -        table_merge(hdrs, "Vary", "accept-encoding");
  +        table_mergen(hdrs, "Vary", "accept-encoding");
       }
   }
   
  @@ -1955,10 +1955,10 @@
   static void store_variant_list(request_rec *r, negotiation_state *neg)
   {
       if (r->main == NULL) {
  -        table_set(r->notes, "variant-list", make_variant_list(r, neg));
  +        table_setn(r->notes, "variant-list", make_variant_list(r, neg));
       }
       else {
  -        table_set(r->main->notes, "variant-list",
  +        table_setn(r->main->notes, "variant-list",
                     make_variant_list(r->main, neg));
       }
   }
  @@ -2004,9 +2004,10 @@
       }
   
       if ((sub_vary = table_get(sub_req->err_headers_out, "Vary")) != NULL) {
  -        table_set(r->err_headers_out, "Variant-Vary", sub_vary);
  +        table_setn(r->err_headers_out, "Variant-Vary", sub_vary);
       }
  -    table_set(r->err_headers_out, "Content-Location", variant->file_name);
  +    table_setn(r->err_headers_out, "Content-Location",
  +             pstrdup(r->pool, variant->file_name));
       set_neg_headers(r, neg, na_choice);         /* add Alternates and Vary */
       /* to do: add Expires */
   
  @@ -2189,13 +2190,19 @@
       r->content_language = sub_req->content_language;
       r->finfo = sub_req->finfo;
       r->per_dir_config = sub_req->per_dir_config;
  +    /* You may wonder why we're using the sub_req->pool here.  It's to 
support
  +     * POOL_DEBUG in alloc.c.  sub_req->pool will have the same lifetime as
  +     * r->pool, we guarantee that by not destroying the sub request below.
  +     * We have to guarantee that because we've "promoted" some of the values
  +     * from sub_req->pool to r->foobar, like r->filename.
  +     */
       /* copy output headers from subrequest, but leave negotiation headers */
  -    r->notes = overlay_tables(r->pool, sub_req->notes, r->notes);
  -    r->headers_out = overlay_tables(r->pool, sub_req->headers_out,
  +    r->notes = overlay_tables(sub_req->pool, sub_req->notes, r->notes);
  +    r->headers_out = overlay_tables(sub_req->pool, sub_req->headers_out,
                                       r->headers_out);
  -    r->err_headers_out = overlay_tables(r->pool, sub_req->err_headers_out,
  +    r->err_headers_out = overlay_tables(sub_req->pool, 
sub_req->err_headers_out,
                                           r->err_headers_out);
  -    r->subprocess_env = overlay_tables(r->pool, sub_req->subprocess_env,
  +    r->subprocess_env = overlay_tables(sub_req->pool, 
sub_req->subprocess_env,
                                          r->subprocess_env);
       avail_recs = (var_rec *) neg->avail_vars->elts;
       for (j = 0; j < neg->avail_vars->nelts; ++j) {
  
  
  
  1.63      +7 -7      apachen/src/modules/standard/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_rewrite.c,v
  retrieving revision 1.62
  retrieving revision 1.63
  diff -u -r1.62 -r1.63
  --- mod_rewrite.c     1998/01/20 00:27:20     1.62
  +++ mod_rewrite.c     1998/01/26 19:50:23     1.63
  @@ -908,13 +908,13 @@
            var = pstrcat(r->pool, "REDIRECT_", ENVVAR_SCRIPT_URL, NULL);
            var = table_get(r->subprocess_env, var);
            if (var == NULL) 
  -             table_set(r->subprocess_env, ENVVAR_SCRIPT_URL, r->uri);
  +             table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, r->uri);
            else 
  -             table_set(r->subprocess_env, ENVVAR_SCRIPT_URL, var);
  +             table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, var);
       } 
       else {
            var = table_get(r->main->subprocess_env, ENVVAR_SCRIPT_URL);
  -         table_set(r->subprocess_env, ENVVAR_SCRIPT_URL, var);
  +         table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, var);
       }
   
       /*
  @@ -943,7 +943,7 @@
   #else
       var = pstrcat(r->pool, "http://";, thisserver, thisport, thisurl, NULL);
   #endif
  -    table_set(r->subprocess_env, ENVVAR_SCRIPT_URI, var);
  +    table_setn(r->subprocess_env, ENVVAR_SCRIPT_URI, var);
   
   
       /* if filename was not initially set,
  @@ -1028,7 +1028,7 @@
                   n = REDIRECT;
   
               /* now do the redirection */
  -            table_set(r->headers_out, "Location", r->filename);
  +            table_setn(r->headers_out, "Location", r->filename);
               rewritelog(r, 1, "redirect to %s [REDIRECT/%d]", r->filename, n);
               return n;
           }
  @@ -1298,7 +1298,7 @@
                   n = REDIRECT;
   
               /* now do the redirection */
  -            table_set(r->headers_out, "Location", r->filename);
  +            table_setn(r->headers_out, "Location", r->filename);
               rewritelog(r, 1, "[per-dir %s] redirect to %s [REDIRECT/%d]",
                          dconf->directory, r->filename, n);
               return n;
  @@ -1873,7 +1873,7 @@
        *  MIME API-hook function.
        */
       if (p->forced_mimetype != NULL) {
  -        table_set(r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR,
  +        table_setn(r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR,
                     p->forced_mimetype);
           if (perdir == NULL)
               rewritelog(r, 2, "remember %s to have MIME-type '%s'",
  
  
  
  1.13      +1 -1      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.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- mod_setenvif.c    1998/01/24 19:00:26     1.12
  +++ mod_setenvif.c    1998/01/26 19:50:24     1.13
  @@ -310,7 +310,7 @@
                       table_unset(r->subprocess_env, elts[j].key);
                   }
                   else {
  -                    table_set(r->subprocess_env, elts[j].key, elts[j].val);
  +                    table_setn(r->subprocess_env, elts[j].key, elts[j].val);
                   }
               }
           }
  
  
  
  1.12      +2 -2      apachen/src/modules/standard/mod_speling.c
  
  Index: mod_speling.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_speling.c,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- mod_speling.c     1998/01/13 23:29:13     1.11
  +++ mod_speling.c     1998/01/26 19:50:24     1.12
  @@ -338,7 +338,7 @@
               nuri = pstrcat(r->pool, url, variant[0].name,
                              r->path_info, NULL);
   
  -            table_set(r->headers_out, "Location",
  +            table_setn(r->headers_out, "Location",
                         construct_url(r->pool, nuri, r->server));
   
               aplog_error(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, r->server,
  @@ -408,7 +408,7 @@
                   ref, "\">referring page</a> about the broken link.\n", NULL);
   
               /* Pass our table to http_protocol.c (see mod_negotiation): */
  -            table_set(notes, "variant-list", t);
  +            table_setn(notes, "variant-list", t);
   
               aplog_error(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, r->server,
                           ref ? "Spelling fix: %s: %d candidates from %s"
  
  
  
  1.10      +1 -1      apachen/src/modules/standard/mod_unique_id.c
  
  Index: mod_unique_id.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_unique_id.c,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- mod_unique_id.c   1998/01/07 16:46:58     1.9
  +++ mod_unique_id.c   1998/01/26 19:50:25     1.10
  @@ -311,7 +311,7 @@
       str[18] = uuencoder[((x[1] & 0x0f) << 2) | ((0 & 0xc0) >> 6)];
       str[19] = '\0';
   
  -    table_set(r->subprocess_env, "UNIQUE_ID", str);
  +    table_setn(r->subprocess_env, "UNIQUE_ID", pstrdup(r->pool, str));
   
       /* and increment the identifier for the next call */
       counter = ntohs(cur_unique_id.counter) + 1;
  
  
  
  1.26      +4 -3      apachen/src/modules/standard/mod_userdir.c
  
  Index: mod_userdir.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_userdir.c,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- mod_userdir.c     1998/01/07 16:46:58     1.25
  +++ mod_userdir.c     1998/01/26 19:50:25     1.26
  @@ -194,7 +194,8 @@
       (userdir_config *) get_module_config(server_conf, &userdir_module);
       char *name = r->uri;
       const char *userdirs = pstrdup(r->pool, s_cfg->userdir);
  -    const char *w, *dname, *redirect;
  +    const char *w, *dname;
  +    char *redirect;
       char *x = NULL;
       struct stat statbuf;
   
  @@ -277,7 +278,7 @@
                   if (strchr(x, ':')) {
   #endif                          /* WIN32 */
                       redirect = pstrcat(r->pool, x, w, userdir, dname, NULL);
  -                    table_set(r->headers_out, "Location", redirect);
  +                    table_setn(r->headers_out, "Location", redirect);
                       return REDIRECT;
                   }
                   else
  @@ -288,7 +289,7 @@
           }
           else if (strchr(userdir, ':')) {
               redirect = pstrcat(r->pool, userdir, "/", w, dname, NULL);
  -            table_set(r->headers_out, "Location", redirect);
  +            table_setn(r->headers_out, "Location", redirect);
               return REDIRECT;
           }
           else {
  
  
  
  1.25      +5 -5      apachen/src/modules/standard/mod_usertrack.c
  
  Index: mod_usertrack.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/modules/standard/mod_usertrack.c,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- mod_usertrack.c   1998/01/07 16:46:59     1.24
  +++ mod_usertrack.c   1998/01/26 19:50:26     1.25
  @@ -135,8 +135,8 @@
       struct timezone tz = {0, 0};
   #endif
       /* 1024 == hardcoded constants */
  -    char *new_cookie = palloc(r->pool, 1024);
  -    char *cookiebuf = palloc(r->pool, 1024);
  +    char new_cookie[1024];
  +    char cookiebuf[1024];
       char *dot;
       const char *rname = pstrdup(r->pool,
                              get_remote_host(r->connection, r->per_dir_config,
  @@ -200,8 +200,8 @@
       else
           ap_snprintf(new_cookie, 1024, "%s%s; path=/", COOKIE_NAME, 
cookiebuf);
   
  -    table_set(r->headers_out, "Set-Cookie", new_cookie);
  -    table_set(r->notes, "cookie", cookiebuf);   /* log first time */
  +    table_setn(r->headers_out, "Set-Cookie", pstrdup(r->pool, new_cookie));
  +    table_setn(r->notes, "cookie", pstrdup(r->pool, cookiebuf));   /* log 
first time */
       return;
   }
   
  @@ -226,7 +226,7 @@
                   *cookieend = '\0';      /* Ignore anything after a ; */
   
               /* Set the cookie in a note, for logging */
  -            table_set(r->notes, "cookie", cookiebuf);
  +            table_setn(r->notes, "cookie", cookiebuf);
   
               return DECLINED;    /* Theres already a cookie, no new one */
           }
  
  
  

Reply via email to