You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ma...@apache.org on 2002/04/09 14:02:50 UTC

cvs commit: apache-1.3/src/modules/proxy proxy_cache.c

martin      02/04/09 05:02:50

  Modified:    src/modules/proxy proxy_cache.c
  Log:
  Do a "proper" indent by moving some curly braces outside of #if's.
  Fix an error message to print the correct filename (not tempfile).
  Remove the tempfile for Win32 on a failed rename(2).
  
  Revision  Changes    Path
  1.85      +938 -941  apache-1.3/src/modules/proxy/proxy_cache.c
  
  Index: proxy_cache.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_cache.c,v
  retrieving revision 1.84
  retrieving revision 1.85
  diff -u -r1.84 -r1.85
  --- proxy_cache.c	7 Apr 2002 18:57:36 -0000	1.84
  +++ proxy_cache.c	9 Apr 2002 12:02:49 -0000	1.85
  @@ -89,7 +89,7 @@
   typedef struct {
       long lower;                 /* lower 30 bits of result */
       long upper;                 /* upper 31 bits of result */
  -}      long61_t;
  +} long61_t;
   
   /* FIXME: The block size can be different on a `per file system' base.
    * This would make automatic detection highly OS specific.
  @@ -159,7 +159,7 @@
   }
   
   
  -static void add_long61(long61_t * accu, long val)
  +static void add_long61(long61_t *accu, long val)
   {
       /* Add in lower 30 bits */
       accu->lower += (val & 0x3FFFFFFFL);
  @@ -169,7 +169,7 @@
       accu->lower &= 0x3FFFFFFFL;
   }
   
  -static void sub_long61(long61_t * accu, long val)
  +static void sub_long61(long61_t *accu, long val)
   {
       int carry = (val & 0x3FFFFFFFL) > accu->lower;
       /* Subtract lower 30 bits */
  @@ -183,7 +183,7 @@
    * return  0 when left == right
    * return >0 when left > right
    */
  -static long cmp_long61(long61_t * left, long61_t * right)
  +static long cmp_long61(long61_t *left, long61_t *right)
   {
       return (left->upper == right->upper) ? (left->lower - right->lower)
       : (left->upper - right->upper);
  @@ -471,126 +471,127 @@
   #if defined(OS2) || defined(TPF)
   /* is it a directory? */
   #ifdef OS2
  -        if (ent->d_attr & A_DIR) {
  +        if (ent->d_attr & A_DIR)
   #elif defined(TPF)
               if (stat(filename, &buf) == -1) {
                   if (errno != ENOENT)
                       ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
                                    "proxy gc: stat(%s)", filename);
               }
  -            if (S_ISDIR(buf.st_mode)) {
  +        if (S_ISDIR(buf.st_mode))
   #endif
  -                char newcachedir[HUGE_STRING_LEN];
  +        {
  +            char newcachedir[HUGE_STRING_LEN];
  +            ap_snprintf(newcachedir, sizeof(newcachedir),
  +                        "%s%s/", cachesubdir, ent->d_name);
  +            if (!sub_garbage_coll(r, files, cachebasedir, newcachedir)) {
                   ap_snprintf(newcachedir, sizeof(newcachedir),
  -                            "%s%s/", cachesubdir, ent->d_name);
  -                if (!sub_garbage_coll(r, files, cachebasedir, newcachedir)) {
  -                    ap_snprintf(newcachedir, sizeof(newcachedir),
  -                                "%s%s", cachedir, ent->d_name);
  +                            "%s%s", cachedir, ent->d_name);
   #if TESTING
  -                    fprintf(stderr, "Would remove directory %s\n", newcachedir);
  +                fprintf(stderr, "Would remove directory %s\n", newcachedir);
   #else
  -                    rmdir(newcachedir);
  +                rmdir(newcachedir);
   #endif
  -                    --nfiles;
  -                }
  -                continue;
  +                --nfiles;
               }
  +            continue;
  +        }
   #endif
   
   /* read the file */
   #if defined(WIN32)
  -            /*
  -             * On WIN32 open does not work for directories, so we us stat
  -             * instead of fstat to determine if the file is a directory
  -             */
  -            if (stat(filename, &buf) == -1) {
  -                ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  -                             "proxy gc: stat(%s)", filename);
  -                continue;
  -            }
  -            fd = -1;
  +        /*
  +         * On WIN32 open does not work for directories, so we us stat instead
  +         * of fstat to determine if the file is a directory
  +         */
  +        if (stat(filename, &buf) == -1) {
  +            ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  +                         "proxy gc: stat(%s)", filename);
  +            continue;
  +        }
  +        fd = -1;
   #else
  -            fd = open(filename, O_RDONLY | O_BINARY);
  -            if (fd == -1) {
  -                if (errno != ENOENT)
  -                    ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  -                                 "proxy gc: open(%s)", filename);
  -                continue;
  -            }
  -            if (fstat(fd, &buf) == -1) {
  +        fd = open(filename, O_RDONLY | O_BINARY);
  +        if (fd == -1) {
  +            if (errno != ENOENT)
                   ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  -                             "proxy gc: fstat(%s)", filename);
  -                close(fd);
  -                continue;
  -            }
  +                             "proxy gc: open(%s)", filename);
  +            continue;
  +        }
  +        if (fstat(fd, &buf) == -1) {
  +            ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  +                         "proxy gc: fstat(%s)", filename);
  +            close(fd);
  +            continue;
  +        }
   #endif
   
   /* In OS/2 and TPF this has already been done above */
   #if !defined(OS2) && !defined(TPF)
  -            if (S_ISDIR(buf.st_mode)) {
  -                char newcachedir[HUGE_STRING_LEN];
  +        if (S_ISDIR(buf.st_mode)) {
  +            char newcachedir[HUGE_STRING_LEN];
   #if !defined(WIN32)
  -                /* Win32 used stat, no file to close */
  -                close(fd);
  +            /* Win32 used stat, no file to close */
  +            close(fd);
   #endif
  +            ap_snprintf(newcachedir, sizeof(newcachedir),
  +                        "%s%s/", cachesubdir, ent->d_name);
  +            if (!sub_garbage_coll(r, files, cachebasedir, newcachedir)) {
                   ap_snprintf(newcachedir, sizeof(newcachedir),
  -                            "%s%s/", cachesubdir, ent->d_name);
  -                if (!sub_garbage_coll(r, files, cachebasedir, newcachedir)) {
  -                    ap_snprintf(newcachedir, sizeof(newcachedir),
  -                                "%s%s", cachedir, ent->d_name);
  +                            "%s%s", cachedir, ent->d_name);
   #if TESTING
  -                    fprintf(stderr, "Would remove directory %s\n", newcachedir);
  +                fprintf(stderr, "Would remove directory %s\n", newcachedir);
   #else
  -                    rmdir(newcachedir);
  +                rmdir(newcachedir);
   #endif
  -                    --nfiles;
  -                }
  -                else {
  -                    /* Directory is not empty. Account for its size: */
  -                    add_long61(&curbytes, ROUNDUP2BLOCKS(buf.st_size));
  -                }
  -                continue;
  +                --nfiles;
  +            }
  +            else {
  +                /* Directory is not empty. Account for its size: */
  +                add_long61(&curbytes, ROUNDUP2BLOCKS(buf.st_size));
               }
  +            continue;
  +        }
   #endif
   
   #if defined(WIN32)
  -            /*
  -             * Since we have determined above that the file is not a
  -             * directory, it should be safe to open it now
  -             */
  -            fd = open(filename, O_RDONLY | O_BINARY);
  -            if (fd == -1) {
  -                if (errno != ENOENT)
  -                    ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  -                                 "proxy gc: open(%s) = %d", filename, errno);
  -                continue;
  -            }
  +        /*
  +         * Since we have determined above that the file is not a directory,
  +         * it should be safe to open it now
  +         */
  +        fd = open(filename, O_RDONLY | O_BINARY);
  +        if (fd == -1) {
  +            if (errno != ENOENT)
  +                ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  +                             "proxy gc: open(%s) = %d", filename, errno);
  +            continue;
  +        }
   #endif
   
  -            i = read(fd, line, 17 * (3) - 1);
  -            close(fd);
  -            if (i == -1) {
  -                ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  -                             "proxy gc: read(%s)", filename);
  -                continue;
  -            }
  -            line[i] = '\0';
  -            garbage_expire = ap_proxy_hex2sec(line + 17 * (2));
  -            if (!ap_checkmask(line, "&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&") ||
  -                garbage_expire == BAD_DATE) {
  -                /* bad file */
  -                if (garbage_now != -1 && buf.st_atime > garbage_now + SEC_ONE_DAY &&
  -                    buf.st_mtime > garbage_now + SEC_ONE_DAY) {
  -                    ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, r->server,
  -                                 "proxy: deleting bad cache file with future date: %s", filename);
  +        i = read(fd, line, 17 * (3) - 1);
  +        close(fd);
  +        if (i == -1) {
  +            ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
  +                         "proxy gc: read(%s)", filename);
  +            continue;
  +        }
  +        line[i] = '\0';
  +        garbage_expire = ap_proxy_hex2sec(line + 17 * (2));
  +        if (!ap_checkmask(line, "&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&") ||
  +            garbage_expire == BAD_DATE) {
  +            /* bad file */
  +            if (garbage_now != -1 && buf.st_atime > garbage_now + SEC_ONE_DAY &&
  +                buf.st_mtime > garbage_now + SEC_ONE_DAY) {
  +                ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, r->server,
  +                             "proxy: deleting bad cache file with future date: %s", filename);
   #if TESTING
  -                    fprintf(stderr, "Would unlink bad file %s\n", filename);
  +                fprintf(stderr, "Would unlink bad file %s\n", filename);
   #else
  -                    unlink(filename);
  +                unlink(filename);
   #endif
  -                }
  -                continue;
               }
  +            continue;
  +        }
   
   /*
    * we need to calculate an 'old' factor, and remove the 'oldest' files
  @@ -598,21 +599,21 @@
    * file.
    *
    */
  -            fent = (struct gc_ent *) ap_push_array(files);
  -            fent->len = buf.st_size;
  -            fent->expire = garbage_expire;
  -            strcpy(fent->file, cachesubdir);
  -            strcat(fent->file, ent->d_name);
  +        fent = (struct gc_ent *) ap_push_array(files);
  +        fent->len = buf.st_size;
  +        fent->expire = garbage_expire;
  +        strcpy(fent->file, cachesubdir);
  +        strcat(fent->file, ent->d_name);
   
   /* accumulate in blocks, to cope with directories > 4Gb */
  -            add_long61(&curbytes, ROUNDUP2BLOCKS(buf.st_size));
  -        }
  +        add_long61(&curbytes, ROUNDUP2BLOCKS(buf.st_size));
  +    }
   
  -        closedir(dir);
  +    closedir(dir);
   
  -        return nfiles;
  +    return nfiles;
   
  -    }
  +}
   
   
   /*
  @@ -626,89 +627,90 @@
    * pointing at the start of the message body itself, ready to be
    * shipped to the client later on, if appropriate.
    */
  -    static int rdcache(request_rec *r, BUFF *cachefp, cache_req *c){
  -        char urlbuff[HUGE_STRING_LEN], *strp;
  -        int len;
  +static int rdcache(request_rec *r, BUFF *cachefp, cache_req *c)
  +{
  +    char urlbuff[HUGE_STRING_LEN], *strp;
  +    int len;
   
  -        /* read the data from the cache file */
  +    /* read the data from the cache file */
   
  -        /*
  -         * Format:
  -         * 
  -         * The cache needs to keep track of the following information: - Date,
  -         * LastMod, Version, ReqTime, RespTime, ContentLength - The original
  -         * request headers (for Vary) - The original response headers (for
  -         * returning with a cached response) - The body of the message
  -         * 
  -         * date SP lastmod SP expire SP count SP request-time SP response-time
  -         * SP content-lengthCRLF (dates are stored as hex seconds since 1970)
  -         * Original URLCRLF Original Request Headers CRLF Original Response
  -         * Headers CRLF Body
  -         * 
  -         */
  +    /*
  +     * Format:
  +     * 
  +     * The cache needs to keep track of the following information: - Date,
  +     * LastMod, Version, ReqTime, RespTime, ContentLength - The original
  +     * request headers (for Vary) - The original response headers (for
  +     * returning with a cached response) - The body of the message
  +     * 
  +     * date SP lastmod SP expire SP count SP request-time SP response-time SP
  +     * content-lengthCRLF (dates are stored as hex seconds since 1970)
  +     * Original URLCRLF Original Request Headers CRLF Original Response
  +     * Headers CRLF Body
  +     * 
  +     */
   
  -        /* retrieve cachefile information values */
  -            len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
  -        if  (len == -1)
  -                return -1;
  -        if  (len == 0 || urlbuff[len - 1] != '\n')
  -                return 0;
  -            urlbuff[len - 1] = '\0';
  -
  -        if  (!ap_checkmask(urlbuff,
  -                               "&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&"))
  -                return 0;
  -
  -            c->date = ap_proxy_hex2sec(urlbuff + 17 * (0));
  -            c->lmod = ap_proxy_hex2sec(urlbuff + 17 * (1));
  -            c->expire = ap_proxy_hex2sec(urlbuff + 17 * (2));
  -            c->version = ap_proxy_hex2sec(urlbuff + 17 * (3));
  -            c->req_time = ap_proxy_hex2sec(urlbuff + 17 * (4));
  -            c->resp_time = ap_proxy_hex2sec(urlbuff + 17 * (5));
  -            c->len = ap_proxy_hex2sec(urlbuff + 17 * (6));
  -
  -        /* check that we have the same URL */
  -            len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
  -        if  (len == -1)
  -                return -1;
  -        if  (len == 0 || strncmp(urlbuff, "X-URL: ", 7) != 0 ||
  -                 urlbuff[len - 1] != '\n')
  -                return 0;
  -            urlbuff[len - 1] = '\0';
  -        if  (strcmp(urlbuff + 7, c->url) != 0)
  -                return 0;
  -
  -        /* then the original request headers */
  -            c->req_hdrs = ap_proxy_read_headers(r, urlbuff, sizeof urlbuff, cachefp);
  -        if  (c->req_hdrs == NULL)
  -                return -1;
  -
  -        /* then the original response headers */
  -            len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
  -        if  (len == -1)
  -                return -1;
  -        if  (len == 0 || urlbuff[len - 1] != '\n')
  -                return 0;
  -            urlbuff[--len] = '\0';
  -
  -            c->resp_line = ap_pstrdup(r->pool, urlbuff);
  -            strp = strchr(urlbuff, ' ');
  -        if  (strp == NULL)
  -                return 0;
  -
  -            c->status = atoi(strp);
  -            c->hdrs = ap_proxy_read_headers(r, urlbuff, sizeof urlbuff, cachefp);
  -        if  (c->hdrs == NULL)
  -                return -1;
  -        if  (c->len != -1)      /* add a content-length header */
  -            if  (ap_table_get(c->hdrs, "Content-Length") == NULL) {
  -                ap_table_set(c->hdrs, "Content-Length",
  -                        ap_psprintf(r->pool, "%lu", (unsigned long)c->len));
  -            }
  +    /* retrieve cachefile information values */
  +    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
  +    if (len == -1)
  +        return -1;
  +    if (len == 0 || urlbuff[len - 1] != '\n')
  +        return 0;
  +    urlbuff[len - 1] = '\0';
   
  +    if (!ap_checkmask(urlbuff,
  +                      "&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&"))
  +        return 0;
   
  -            return 1;
  -    }
  +    c->date = ap_proxy_hex2sec(urlbuff + 17 * (0));
  +    c->lmod = ap_proxy_hex2sec(urlbuff + 17 * (1));
  +    c->expire = ap_proxy_hex2sec(urlbuff + 17 * (2));
  +    c->version = ap_proxy_hex2sec(urlbuff + 17 * (3));
  +    c->req_time = ap_proxy_hex2sec(urlbuff + 17 * (4));
  +    c->resp_time = ap_proxy_hex2sec(urlbuff + 17 * (5));
  +    c->len = ap_proxy_hex2sec(urlbuff + 17 * (6));
  +
  +    /* check that we have the same URL */
  +    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
  +    if (len == -1)
  +        return -1;
  +    if (len == 0 || strncmp(urlbuff, "X-URL: ", 7) != 0 ||
  +        urlbuff[len - 1] != '\n')
  +        return 0;
  +    urlbuff[len - 1] = '\0';
  +    if (strcmp(urlbuff + 7, c->url) != 0)
  +        return 0;
  +
  +    /* then the original request headers */
  +    c->req_hdrs = ap_proxy_read_headers(r, urlbuff, sizeof urlbuff, cachefp);
  +    if (c->req_hdrs == NULL)
  +        return -1;
  +
  +    /* then the original response headers */
  +    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
  +    if (len == -1)
  +        return -1;
  +    if (len == 0 || urlbuff[len - 1] != '\n')
  +        return 0;
  +    urlbuff[--len] = '\0';
  +
  +    c->resp_line = ap_pstrdup(r->pool, urlbuff);
  +    strp = strchr(urlbuff, ' ');
  +    if (strp == NULL)
  +        return 0;
  +
  +    c->status = atoi(strp);
  +    c->hdrs = ap_proxy_read_headers(r, urlbuff, sizeof urlbuff, cachefp);
  +    if (c->hdrs == NULL)
  +        return -1;
  +    if (c->len != -1)           /* add a content-length header */
  +        if (ap_table_get(c->hdrs, "Content-Length") == NULL) {
  +            ap_table_set(c->hdrs, "Content-Length",
  +                         ap_psprintf(r->pool, "%lu", (unsigned long)c->len));
  +        }
  +
  +
  +    return 1;
  +}
   
   /*
    * Call this to check the possible conditional status of
  @@ -719,187 +721,188 @@
    *
    * We don't yet understand If-Range, but we will...
    */
  -    int ap_proxy_cache_conditional(request_rec *r, cache_req *c, BUFF *cachefp) {
  -        const char *etag, *wetag = NULL;
  +int ap_proxy_cache_conditional(request_rec *r, cache_req *c, BUFF *cachefp)
  +{
  +    const char *etag, *wetag = NULL;
   
  -        /* get etag */
  -        if   ((etag = ap_table_get(c->hdrs, "Etag"))) {
  -            wetag = ap_pstrcat(r->pool, "W/", etag, NULL);
  -        }
  +    /* get etag */
  +    if ((etag = ap_table_get(c->hdrs, "Etag"))) {
  +        wetag = ap_pstrcat(r->pool, "W/", etag, NULL);
  +    }
   
  -        /* check for If-Match, If-Unmodified-Since */
  -        while (1) {
  +    /* check for If-Match, If-Unmodified-Since */
  +    while (1) {
   
  -            /*
  -             * check If-Match and If-Unmodified-Since exist
  -             * 
  -             * If neither of these exist, the request is not conditional, and we
  -             * serve it normally
  -             */
  -            if (!c->im && BAD_DATE == c->ius) {
  -                break;
  -            }
  +        /*
  +         * check If-Match and If-Unmodified-Since exist
  +         * 
  +         * If neither of these exist, the request is not conditional, and we
  +         * serve it normally
  +         */
  +        if (!c->im && BAD_DATE == c->ius) {
  +            break;
  +        }
   
  -            /*
  -             * check If-Match
  -             * 
  -             * we check if the Etag on the cached file is in the list of Etags
  -             * in the If-Match field. The comparison must be a strong
  -             * comparison, so the Etag cannot be marked as weak. If the
  -             * comparision fails we return 412 Precondition Failed.
  -             * 
  -             * if If-Match is specified AND If-Match is not a "*" AND Etag is
  -             * missing or weak or not in the list THEN return 412
  -             * Precondition Failed
  -             */
  +        /*
  +         * check If-Match
  +         * 
  +         * we check if the Etag on the cached file is in the list of Etags in
  +         * the If-Match field. The comparison must be a strong comparison, so
  +         * the Etag cannot be marked as weak. If the comparision fails we
  +         * return 412 Precondition Failed.
  +         * 
  +         * if If-Match is specified AND If-Match is not a "*" AND Etag is
  +         * missing or weak or not in the list THEN return 412 Precondition
  +         * Failed
  +         */
   
  -            if (c->im) {
  -                if (strcmp(c->im, "*") &&
  -                    (!etag || (strlen(etag) > 1 && 'W' == etag[0] && '/' == etag[1]) || !ap_proxy_liststr(c->im, etag, NULL))) {
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Match specified, and it didn't - return 412");
  -                }
  -                else {
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Match specified, and it matched");
  -                    break;
  -                }
  +        if (c->im) {
  +            if (strcmp(c->im, "*") &&
  +                (!etag || (strlen(etag) > 1 && 'W' == etag[0] && '/' == etag[1]) || !ap_proxy_liststr(c->im, etag, NULL))) {
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Match specified, and it didn't - return 412");
               }
  -
  -            /*
  -             * check If-Unmodified-Since
  -             * 
  -             * if If-Unmodified-Since is specified AND Last-Modified is
  -             * specified somewhere AND If-Unmodified-Since is in the past
  -             * compared to Last-Modified THEN return 412 Precondition Failed
  -             */
  -            if (BAD_DATE != c->ius && BAD_DATE != c->lmod) {
  -                if (c->ius < c->lmod) {
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, but it wasn't - return 412");
  -                }
  -                else {
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, and it was unmodified");
  -                    break;
  -                }
  +            else {
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Match specified, and it matched");
  +                break;
               }
  +        }
   
  -            /* if cache file is being updated */
  -            if (c->origfp) {
  -                ap_proxy_write_headers(c, c->resp_line, c->hdrs);
  -                ap_proxy_send_fb(c->origfp, r, c, c->len, 1, 0, IOBUFSIZE);
  -                ap_proxy_cache_tidy(c);
  +        /*
  +         * check If-Unmodified-Since
  +         * 
  +         * if If-Unmodified-Since is specified AND Last-Modified is specified
  +         * somewhere AND If-Unmodified-Since is in the past compared to
  +         * Last-Modified THEN return 412 Precondition Failed
  +         */
  +        if (BAD_DATE != c->ius && BAD_DATE != c->lmod) {
  +            if (c->ius < c->lmod) {
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, but it wasn't - return 412");
               }
  -            else
  -                ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
  +            else {
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, and it was unmodified");
  +                break;
  +            }
  +        }
   
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Use your cached copy, conditional precondition failed.");
  -            return HTTP_PRECONDITION_FAILED;
  +        /* if cache file is being updated */
  +        if (c->origfp) {
  +            ap_proxy_write_headers(c, c->resp_line, c->hdrs);
  +            ap_proxy_send_fb(c->origfp, r, c, c->len, 1, 0, IOBUFSIZE);
  +            ap_proxy_cache_tidy(c);
           }
  +        else
  +            ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
   
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Use your cached copy, conditional precondition failed.");
  +        return HTTP_PRECONDITION_FAILED;
  +    }
   
  -        /* check for If-None-Match, If-Modified-Since */
  -        while (1) {
   
  -            /*
  -             * check for existance of If-None-Match and If-Modified-Since
  -             * 
  -             * if neither of these headers have been set, then the request is
  -             * not conditional, and we just send the cached response and be
  -             * done with it.
  -             */
  -            if (!c->inm && BAD_DATE == c->ims) {
  -                break;
  -            }
  +    /* check for If-None-Match, If-Modified-Since */
  +    while (1) {
   
  -            /*
  -             * check If-None-Match
  -             * 
  -             * we check if the Etag on the cached file is in the list of Etags
  -             * in the If-None-Match field. The comparison must be a strong
  -             * comparison, so the Etag cannot be marked as weak. If the
  -             * comparision fails we return 412 Precondition Failed.
  -             * 
  -             * if If-None-Match is specified: if If-None-Match is a "*" THEN 304
  -             * else if Etag is specified AND we get a match THEN 304 else if
  -             * Weak Etag is specified AND we get a match THEN 304 else sent
  -             * the original object
  -             */
  -            if (c->inm) {
  -                if (!strcmp(c->inm, "*")) {
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match: * specified, return 304");
  -                }
  -                else if (etag && ap_proxy_liststr(c->inm, etag, NULL)) {
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match: specified and we got a strong match - return 304");
  -                }
  -                else if (wetag && ap_proxy_liststr(c->inm, wetag, NULL)) {
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match specified, and we got a weak match - return 304");
  -                }
  -                else
  -                    break;
  -            }
  +        /*
  +         * check for existance of If-None-Match and If-Modified-Since
  +         * 
  +         * if neither of these headers have been set, then the request is not
  +         * conditional, and we just send the cached response and be done with
  +         * it.
  +         */
  +        if (!c->inm && BAD_DATE == c->ims) {
  +            break;
  +        }
   
  -            /*
  -             * check If-Modified-Since
  -             * 
  -             * if If-Modified-Since is specified AND Last-Modified is specified
  -             * somewhere: if last modification date is earlier than
  -             * If-Modified-Since THEN 304 else send the original object
  -             */
  -            if (BAD_DATE != c->ims && BAD_DATE != c->lmod) {
  -                if (c->ims >= c->lmod) {
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Modified-Since specified and not modified, try return 304");
  -                }
  -                else
  -                    break;
  +        /*
  +         * check If-None-Match
  +         * 
  +         * we check if the Etag on the cached file is in the list of Etags in
  +         * the If-None-Match field. The comparison must be a strong
  +         * comparison, so the Etag cannot be marked as weak. If the
  +         * comparision fails we return 412 Precondition Failed.
  +         * 
  +         * if If-None-Match is specified: if If-None-Match is a "*" THEN 304
  +         * else if Etag is specified AND we get a match THEN 304 else if Weak
  +         * Etag is specified AND we get a match THEN 304 else sent the
  +         * original object
  +         */
  +        if (c->inm) {
  +            if (!strcmp(c->inm, "*")) {
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match: * specified, return 304");
               }
  -
  -
  -            /* are we updating the cache file? */
  -            if (c->origfp) {
  -                ap_proxy_write_headers(c, c->resp_line, c->hdrs);
  -                ap_proxy_send_fb(c->origfp, r, c, c->len, 1, 0, IOBUFSIZE);
  -                ap_proxy_cache_tidy(c);
  +            else if (etag && ap_proxy_liststr(c->inm, etag, NULL)) {
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match: specified and we got a strong match - return 304");
  +            }
  +            else if (wetag && ap_proxy_liststr(c->inm, wetag, NULL)) {
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match specified, and we got a weak match - return 304");
               }
               else
  -                ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
  -
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Use local copy, cached file hasn't changed");
  -            return HTTP_NOT_MODIFIED;
  +                break;
           }
   
  +        /*
  +         * check If-Modified-Since
  +         * 
  +         * if If-Modified-Since is specified AND Last-Modified is specified
  +         * somewhere: if last modification date is earlier than
  +         * If-Modified-Since THEN 304 else send the original object
  +         */
  +        if (BAD_DATE != c->ims && BAD_DATE != c->lmod) {
  +            if (c->ims >= c->lmod) {
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Modified-Since specified and not modified, try return 304");
  +            }
  +            else
  +                break;
  +        }
   
  -        /* No conditional - just send it cousin! */
  -        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Local copy modified, send it");
  -        r->status_line = strchr(c->resp_line, ' ') + 1;
  -        r->status = c->status;
  -
  -        /* Prepare and send headers to client */
  -        ap_proxy_table_replace(r->headers_out, c->hdrs);
  -        /* make sure our X-Cache header does not stomp on a previous header */
  -        ap_table_mergen(r->headers_out, "X-Cache", c->xcache);
  -
  -        /* content type is already set in the headers */
  -        r->content_type = ap_table_get(r->headers_out, "Content-Type");
  -
  -        ap_send_http_header(r);
   
  -        /* are we rewriting the cache file? */
  +        /* are we updating the cache file? */
           if (c->origfp) {
               ap_proxy_write_headers(c, c->resp_line, c->hdrs);
  -            ap_proxy_send_fb(c->origfp, r, c, c->len, r->header_only, 0, IOBUFSIZE);
  +            ap_proxy_send_fb(c->origfp, r, c, c->len, 1, 0, IOBUFSIZE);
               ap_proxy_cache_tidy(c);
  -            return OK;
  -        }
  -
  -        /* no, we not */
  -        if (!r->header_only) {
  -            ap_proxy_send_fb(cachefp, r, NULL, c->len, 0, 0, IOBUFSIZE);
           }
  -        else {
  +        else
               ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
  -        }
   
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Use local copy, cached file hasn't changed");
  +        return HTTP_NOT_MODIFIED;
  +    }
  +
  +
  +    /* No conditional - just send it cousin! */
  +    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Local copy modified, send it");
  +    r->status_line = strchr(c->resp_line, ' ') + 1;
  +    r->status = c->status;
  +
  +    /* Prepare and send headers to client */
  +    ap_proxy_table_replace(r->headers_out, c->hdrs);
  +    /* make sure our X-Cache header does not stomp on a previous header */
  +    ap_table_mergen(r->headers_out, "X-Cache", c->xcache);
  +
  +    /* content type is already set in the headers */
  +    r->content_type = ap_table_get(r->headers_out, "Content-Type");
  +
  +    ap_send_http_header(r);
  +
  +    /* are we rewriting the cache file? */
  +    if (c->origfp) {
  +        ap_proxy_write_headers(c, c->resp_line, c->hdrs);
  +        ap_proxy_send_fb(c->origfp, r, c, c->len, r->header_only, 0, IOBUFSIZE);
  +        ap_proxy_cache_tidy(c);
           return OK;
       }
   
  +    /* no, we not */
  +    if (!r->header_only) {
  +        ap_proxy_send_fb(cachefp, r, NULL, c->len, 0, 0, IOBUFSIZE);
  +    }
  +    else {
  +        ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
  +    }
  +
  +    return OK;
  +}
  +
   
   /*
    * Call this to test for a resource in the cache
  @@ -915,83 +918,81 @@
    *         if last modified after if-modified-since then add
    *            last modified date to request
    */
  -    int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf * conf,
  -                                 cache_req **cr){
  -        const char *datestr, *pragma_req = NULL, *pragma_cresp = NULL,
  -            *cc_req = NULL, *cc_cresp = NULL, *vary = NULL;
  -        cache_req *c;
  -        time_t now;
  -        BUFF *cachefp;
  -        int i;
  -        void *sconf = r->server->module_config;
  -        proxy_server_conf *pconf =
  -        (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
  -                          const char *agestr = NULL;
  -        char *val;
  -        time_t age_c = 0;
  -        time_t age, maxage_req, maxage_cresp, maxage, smaxage, maxstale,
  -               minfresh;
  -
  -               c = ap_pcalloc(r->pool, sizeof(cache_req));
  -              *cr = c;
  -               c->req = r;
  -               c->url = ap_pstrdup(r->pool, url);
  -               c->filename = NULL;
  -               c->tempfile = NULL;
  -               c->fp = NULL;
  -               c->origfp = NULL;
  -               c->version = 0;
  -               c->len = -1;
  -               c->req_hdrs = NULL;
  -               c->hdrs = NULL;
  -               c->xcache = NULL;
  -
  -        /* get the If-Modified-Since date of the request, if it exists */
  -               c->ims = BAD_DATE;
  -               datestr = ap_table_get(r->headers_in, "If-Modified-Since");
  -        if     (datestr != NULL) {
  -            /* this may modify the value in the original table */
  -            datestr = ap_proxy_date_canon(r->pool, datestr);
  -            c->ims = ap_parseHTTPdate(datestr);
  -            if (c->ims == BAD_DATE)     /* bad or out of range date; remove
  -                                         * it */
  -                ap_table_unset(r->headers_in, "If-Modified-Since");
  -        }
  +int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf * conf,
  +                             cache_req **cr)
  +{
  +    const char *datestr, *pragma_req = NULL, *pragma_cresp = NULL, *cc_req = NULL,
  +        *cc_cresp = NULL, *vary = NULL;
  +    cache_req *c;
  +    time_t now;
  +    BUFF *cachefp;
  +    int i;
  +    void *sconf = r->server->module_config;
  +    proxy_server_conf *pconf =
  +    (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
  +    const char *agestr = NULL;
  +    char *val;
  +    time_t age_c = 0;
  +    time_t age, maxage_req, maxage_cresp, maxage, smaxage, maxstale, minfresh;
  +
  +    c = ap_pcalloc(r->pool, sizeof(cache_req));
  +    *cr = c;
  +    c->req = r;
  +    c->url = ap_pstrdup(r->pool, url);
  +    c->filename = NULL;
  +    c->tempfile = NULL;
  +    c->fp = NULL;
  +    c->origfp = NULL;
  +    c->version = 0;
  +    c->len = -1;
  +    c->req_hdrs = NULL;
  +    c->hdrs = NULL;
  +    c->xcache = NULL;
  +
  +    /* get the If-Modified-Since date of the request, if it exists */
  +    c->ims = BAD_DATE;
  +    datestr = ap_table_get(r->headers_in, "If-Modified-Since");
  +    if (datestr != NULL) {
  +        /* this may modify the value in the original table */
  +        datestr = ap_proxy_date_canon(r->pool, datestr);
  +        c->ims = ap_parseHTTPdate(datestr);
  +        if (c->ims == BAD_DATE) /* bad or out of range date; remove it */
  +            ap_table_unset(r->headers_in, "If-Modified-Since");
  +    }
   
   /* get the If-Unmodified-Since date of the request, if it exists */
  -            c->ius = BAD_DATE;
  -        datestr = ap_table_get(r->headers_in, "If-Unmodified-Since");
  -        if (datestr != NULL) {
  -            /* this may modify the value in the original table */
  -            datestr = ap_proxy_date_canon(r->pool, datestr);
  -            c->ius = ap_parseHTTPdate(datestr);
  -            if (c->ius == BAD_DATE)     /* bad or out of range date; remove
  -                                         * it */
  -                ap_table_unset(r->headers_in, "If-Unmodified-Since");
  -        }
  +    c->ius = BAD_DATE;
  +    datestr = ap_table_get(r->headers_in, "If-Unmodified-Since");
  +    if (datestr != NULL) {
  +        /* this may modify the value in the original table */
  +        datestr = ap_proxy_date_canon(r->pool, datestr);
  +        c->ius = ap_parseHTTPdate(datestr);
  +        if (c->ius == BAD_DATE) /* bad or out of range date; remove it */
  +            ap_table_unset(r->headers_in, "If-Unmodified-Since");
  +    }
   
   /* get the If-Match of the request, if it exists */
  -        c->im = ap_table_get(r->headers_in, "If-Match");
  +    c->im = ap_table_get(r->headers_in, "If-Match");
   
   /* get the If-None-Match of the request, if it exists */
  -        c->inm = ap_table_get(r->headers_in, "If-None-Match");
  +    c->inm = ap_table_get(r->headers_in, "If-None-Match");
   
   /* find the filename for this cache entry */
  -        if (conf->root != NULL) {
  -            char hashfile[66];
  -            ap_proxy_hash(url, hashfile, pconf->cache.dirlevels, pconf->cache.dirlength);
  -            c->filename = ap_pstrcat(r->pool, conf->root, "/", hashfile, NULL);
  -        }
  -        else {
  -            c->filename = NULL;
  -            c->fp = NULL;
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "No CacheRoot, so no caching. Declining.");
  -            return DECLINED;
  -        }
  +    if (conf->root != NULL) {
  +        char hashfile[66];
  +        ap_proxy_hash(url, hashfile, pconf->cache.dirlevels, pconf->cache.dirlength);
  +        c->filename = ap_pstrcat(r->pool, conf->root, "/", hashfile, NULL);
  +    }
  +    else {
  +        c->filename = NULL;
  +        c->fp = NULL;
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "No CacheRoot, so no caching. Declining.");
  +        return DECLINED;
  +    }
   
   /* find certain cache controlling headers */
  -        pragma_req = ap_table_get(r->headers_in, "Pragma");
  -        cc_req = ap_table_get(r->headers_in, "Cache-Control");
  +    pragma_req = ap_table_get(r->headers_in, "Pragma");
  +    cc_req = ap_table_get(r->headers_in, "Cache-Control");
   
   /* first things first - does the request allow us to return
    * cached information at all? If not, just decline the request.
  @@ -1006,291 +1007,288 @@
    * we are not supposed to store this request at all. Behave as a tunnel.
    *
    */
  -        if (ap_proxy_liststr(cc_req, "no-store", NULL)) {
  +    if (ap_proxy_liststr(cc_req, "no-store", NULL)) {
   
   /* delete the previously cached file */
  -            if (c->filename)
  -                unlink(c->filename);
  -            c->fp = NULL;
  -            c->filename = NULL;
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "no-store forbids caching. Declining.");
  -            return DECLINED;
  -        }
  +        if (c->filename)
  +            unlink(c->filename);
  +        c->fp = NULL;
  +        c->filename = NULL;
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "no-store forbids caching. Declining.");
  +        return DECLINED;
  +    }
   
   /* if the cache file exists, open it */
  -        cachefp = NULL;
  -        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Request for %s, pragma_req=%s, ims=%ld", url,
  -                     pragma_req, c->ims);
  +    cachefp = NULL;
  +    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Request for %s, pragma_req=%s, ims=%ld", url,
  +                 pragma_req, c->ims);
   /* find out about whether the request can access the cache */
  -        if (c->filename != NULL && r->method_number == M_GET &&
  -            strlen(url) < 1024) {
  -            cachefp = ap_proxy_open_cachefile(r, c->filename);
  -        }
  +    if (c->filename != NULL && r->method_number == M_GET &&
  +        strlen(url) < 1024) {
  +        cachefp = ap_proxy_open_cachefile(r, c->filename);
  +    }
   
   
  -        /*
  -         * if a cache file exists, try reading body and headers from cache
  -         * file
  -         */
  -        if (cachefp != NULL) {
  -            i = rdcache(r, cachefp, c);
  -            if (i == -1)
  -                ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  -                              "proxy: error reading cache file %s",
  -                              c->filename);
  -            else if (i == 0)
  -                ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r,
  -                         "proxy: bad (short?) cache file: %s", c->filename);
  -            if (i != 1) {
  -                ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
  -                cachefp = NULL;
  -            }
  -            if (c->hdrs) {
  -                cc_cresp = ap_table_get(c->hdrs, "Cache-Control");
  -                pragma_cresp = ap_table_get(c->hdrs, "Pragma");
  -                vary = ap_table_get(c->hdrs, "Vary");
  -                if ((agestr = ap_table_get(c->hdrs, "Age"))) {
  -                    age_c = atoi(agestr);
  -                }
  +    /*
  +     * if a cache file exists, try reading body and headers from cache file
  +     */
  +    if (cachefp != NULL) {
  +        i = rdcache(r, cachefp, c);
  +        if (i == -1)
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  +                          "proxy: error reading cache file %s",
  +                          c->filename);
  +        else if (i == 0)
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r,
  +                          "proxy: bad (short?) cache file: %s", c->filename);
  +        if (i != 1) {
  +            ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
  +            cachefp = NULL;
  +        }
  +        if (c->hdrs) {
  +            cc_cresp = ap_table_get(c->hdrs, "Cache-Control");
  +            pragma_cresp = ap_table_get(c->hdrs, "Pragma");
  +            vary = ap_table_get(c->hdrs, "Vary");
  +            if ((agestr = ap_table_get(c->hdrs, "Age"))) {
  +                age_c = atoi(agestr);
               }
           }
  +    }
   
  -        /* if a cache file does not exist, create empty header array */
  +    /* if a cache file does not exist, create empty header array */
   /* fixed?  in this case, we want to get the headers from the remote server
      it will be handled later if we don't do this (I hope ;-)
   
       if (cachefp == NULL)
           c->hdrs = ap_make_table(r->pool, 20);
   */
  -        /* FIXME: Shouldn't we check the URL somewhere? */
  +    /* FIXME: Shouldn't we check the URL somewhere? */
   
  -        /*
  -         * Check Content-Negotiation - Vary
  -         * 
  -         * At this point we need to make sure that the object we found in the
  -         * cache is the same object that would be delivered to the client,
  -         * when the effects of content negotiation are taken into effect.
  -         * 
  -         * In plain english, we want to make sure that a language-negotiated
  -         * document in one language is not given to a client asking for a
  -         * language negotiated document in a different language by mistake.
  -         * 
  -         * RFC2616 13.6 and 14.44 describe the Vary mechanism.
  -         */
  -        if (c->hdrs && c->req_hdrs) {
  -            char *vary = ap_pstrdup(r->pool, ap_table_get(c->hdrs, "Vary"));
  +    /*
  +     * Check Content-Negotiation - Vary
  +     * 
  +     * At this point we need to make sure that the object we found in the cache
  +     * is the same object that would be delivered to the client, when the
  +     * effects of content negotiation are taken into effect.
  +     * 
  +     * In plain english, we want to make sure that a language-negotiated
  +     * document in one language is not given to a client asking for a
  +     * language negotiated document in a different language by mistake.
  +     * 
  +     * RFC2616 13.6 and 14.44 describe the Vary mechanism.
  +     */
  +    if (c->hdrs && c->req_hdrs) {
  +        char *vary = ap_pstrdup(r->pool, ap_table_get(c->hdrs, "Vary"));
   
  -            while (vary && *vary) {
  -                char *name = vary;
  -                const char *h1, *h2;
  -
  -                /* isolate header name */
  -                while (*vary && !ap_isspace(*vary) && (*vary != ','))
  -                    ++vary;
  -                while (*vary && (ap_isspace(*vary) || (*vary == ','))) {
  -                    *vary = '\0';
  -                    ++vary;
  -                }
  -
  -                /*
  -                 * is this header in the request and the header in the cached
  -                 * request identical? If not, we give up and do a straight
  -                 * get
  -                 */
  -                h1 = ap_table_get(r->headers_in, name);
  -                h2 = ap_table_get(c->req_hdrs, name);
  -                if (h1 == h2) {
  -                    /* both headers NULL, so a match - do nothing */
  -                }
  -                else if (h1 && h2 && !strcmp(h1, h2)) {
  -                    /* both headers exist and are equal - do nothing */
  -                }
  -                else {
  -
  -                    /* headers do not match, so Vary failed */
  -                    c->fp = cachefp;
  -                    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Vary header mismatch - object must be fetched from scratch. Declining.");
  -                    return DECLINED;
  -                }
  +        while (vary && *vary) {
  +            char *name = vary;
  +            const char *h1, *h2;
  +
  +            /* isolate header name */
  +            while (*vary && !ap_isspace(*vary) && (*vary != ','))
  +                ++vary;
  +            while (*vary && (ap_isspace(*vary) || (*vary == ','))) {
  +                *vary = '\0';
  +                ++vary;
               }
  -        }
   
  +            /*
  +             * is this header in the request and the header in the cached
  +             * request identical? If not, we give up and do a straight get
  +             */
  +            h1 = ap_table_get(r->headers_in, name);
  +            h2 = ap_table_get(c->req_hdrs, name);
  +            if (h1 == h2) {
  +                /* both headers NULL, so a match - do nothing */
  +            }
  +            else if (h1 && h2 && !strcmp(h1, h2)) {
  +                /* both headers exist and are equal - do nothing */
  +            }
  +            else {
  +
  +                /* headers do not match, so Vary failed */
  +                c->fp = cachefp;
  +                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Vary header mismatch - object must be fetched from scratch. Declining.");
  +                return DECLINED;
  +            }
  +        }
  +    }
   
  -        /*
  -         * We now want to check if our cached data is still fresh. This
  -         * depends on a few things, in this order:
  -         * 
  -         * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache no-cache
  -         * in either the request or the cached response means that we must
  -         * revalidate the request unconditionally, overriding any expiration
  -         * mechanism. It's equivalent to max-age=0,must-revalidate.
  -         * 
  -         * - RFC2616 14.32 Pragma: no-cache This is treated the same as
  -         * Cache-Control: no-cache.
  -         * 
  -         * - RFC2616 14.9.3 Cache-Control: max-stale, must-revalidate,
  -         * proxy-revalidate if the max-stale request header exists, modify
  -         * the stale calculations below so that an object can be at most
  -         * <max-stale> seconds stale before we request a revalidation,
  -         * _UNLESS_ a must-revalidate or proxy-revalidate cached response
  -         * header exists to stop us doing this.
  -         * 
  -         * - RFC2616 14.9.3 Cache-Control: s-maxage the origin server specifies
  -         * the maximum age an object can be before it is considered stale.
  -         * This directive has the effect of proxy|must revalidate, which in
  -         * turn means simple ignore any max-stale setting.
  -         * 
  -         * - RFC2616 14.9.4 Cache-Control: max-age this header can appear in
  -         * both requests and responses. If both are specified, the smaller of
  -         * the two takes priority.
  -         * 
  -         * - RFC2616 14.21 Expires: if this request header exists in the cached
  -         * entity, and it's value is in the past, it has expired.
  -         * 
  -         */
   
  -        /* calculate age of object */
  -        age = ap_proxy_current_age(c, age_c);
  +    /*
  +     * We now want to check if our cached data is still fresh. This depends
  +     * on a few things, in this order:
  +     * 
  +     * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache no-cache in
  +     * either the request or the cached response means that we must
  +     * revalidate the request unconditionally, overriding any expiration
  +     * mechanism. It's equivalent to max-age=0,must-revalidate.
  +     * 
  +     * - RFC2616 14.32 Pragma: no-cache This is treated the same as
  +     * Cache-Control: no-cache.
  +     * 
  +     * - RFC2616 14.9.3 Cache-Control: max-stale, must-revalidate,
  +     * proxy-revalidate if the max-stale request header exists, modify the
  +     * stale calculations below so that an object can be at most <max-stale>
  +     * seconds stale before we request a revalidation, _UNLESS_ a
  +     * must-revalidate or proxy-revalidate cached response header exists to
  +     * stop us doing this.
  +     * 
  +     * - RFC2616 14.9.3 Cache-Control: s-maxage the origin server specifies the
  +     * maximum age an object can be before it is considered stale. This
  +     * directive has the effect of proxy|must revalidate, which in turn means
  +     * simple ignore any max-stale setting.
  +     * 
  +     * - RFC2616 14.9.4 Cache-Control: max-age this header can appear in both
  +     * requests and responses. If both are specified, the smaller of the two
  +     * takes priority.
  +     * 
  +     * - RFC2616 14.21 Expires: if this request header exists in the cached
  +     * entity, and it's value is in the past, it has expired.
  +     * 
  +     */
   
  -        /* extract s-maxage */
  -        if (cc_cresp && ap_proxy_liststr(cc_cresp, "s-maxage", &val))
  -            smaxage = atoi(val);
  -        else
  -            smaxage = -1;
  +    /* calculate age of object */
  +    age = ap_proxy_current_age(c, age_c);
   
  -        /* extract max-age from request */
  -        if (cc_req && ap_proxy_liststr(cc_req, "max-age", &val))
  -            maxage_req = atoi(val);
  -        else
  -            maxage_req = -1;
  +    /* extract s-maxage */
  +    if (cc_cresp && ap_proxy_liststr(cc_cresp, "s-maxage", &val))
  +        smaxage = atoi(val);
  +    else
  +        smaxage = -1;
   
  -        /* extract max-age from response */
  -        if (cc_cresp && ap_proxy_liststr(cc_cresp, "max-age", &val))
  -            maxage_cresp = atoi(val);
  -        else
  -            maxage_cresp = -1;
  +    /* extract max-age from request */
  +    if (cc_req && ap_proxy_liststr(cc_req, "max-age", &val))
  +        maxage_req = atoi(val);
  +    else
  +        maxage_req = -1;
   
  -        /*
  -         * if both maxage request and response, the smaller one takes
  -         * priority
  -         */
  -        if (-1 == maxage_req)
  -            maxage = maxage_cresp;
  -        else if (-1 == maxage_cresp)
  -            maxage = maxage_req;
  -        else
  -            maxage = MIN(maxage_req, maxage_cresp);
  +    /* extract max-age from response */
  +    if (cc_cresp && ap_proxy_liststr(cc_cresp, "max-age", &val))
  +        maxage_cresp = atoi(val);
  +    else
  +        maxage_cresp = -1;
   
  -        /* extract max-stale */
  -        if (cc_req && ap_proxy_liststr(cc_req, "max-stale", &val))
  -            maxstale = atoi(val);
  -        else
  -            maxstale = 0;
  +    /*
  +     * if both maxage request and response, the smaller one takes priority
  +     */
  +    if (-1 == maxage_req)
  +        maxage = maxage_cresp;
  +    else if (-1 == maxage_cresp)
  +        maxage = maxage_req;
  +    else
  +        maxage = MIN(maxage_req, maxage_cresp);
   
  -        /* extract min-fresh */
  -        if (cc_req && ap_proxy_liststr(cc_req, "min-fresh", &val))
  -            minfresh = atoi(val);
  -        else
  -            minfresh = 0;
  +    /* extract max-stale */
  +    if (cc_req && ap_proxy_liststr(cc_req, "max-stale", &val))
  +        maxstale = atoi(val);
  +    else
  +        maxstale = 0;
   
  -        /* override maxstale if must-revalidate or proxy-revalidate */
  -        if (maxstale && ((cc_cresp && ap_proxy_liststr(cc_cresp, "must-revalidate", NULL)) || (cc_cresp && ap_proxy_liststr(cc_cresp, "proxy-revalidate", NULL))))
  -            maxstale = 0;
  -
  -        now = time(NULL);
  -        if (cachefp != NULL &&
  -
  -        /* handle no-cache */
  -            !((cc_req && ap_proxy_liststr(cc_req, "no-cache", NULL)) ||
  -           (pragma_req && ap_proxy_liststr(pragma_req, "no-cache", NULL)) ||
  -              (cc_cresp && ap_proxy_liststr(cc_cresp, "no-cache", NULL)) ||
  -              (pragma_cresp && ap_proxy_liststr(pragma_cresp, "no-cache", NULL))) &&
  -
  -        /* handle expiration */
  -            ((-1 < smaxage && age < (smaxage - minfresh)) ||
  -             (-1 < maxage && age < (maxage + maxstale - minfresh)) ||
  -             (c->expire != BAD_DATE && age < (c->expire - c->date + maxstale - minfresh)))
  -            ) {
  -
  -            /* it's fresh darlings... */
  -
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Unexpired data available");
  -
  -            /* set age header on response */
  -            ap_table_set(c->hdrs, "Age",
  -                         ap_psprintf(r->pool, "%lu", (unsigned long)age));
  -
  -            /* add warning if maxstale overrode freshness calculation */
  -            if (!((-1 < smaxage && age < smaxage) ||
  -                  (-1 < maxage && age < maxage) ||
  -                  (c->expire != BAD_DATE && (c->expire - c->date) > age))) {
  -                /* make sure we don't stomp on a previous warning */
  -                ap_table_merge(c->hdrs, "Warning", "110 Response is stale");
  -            }
  -
  -            /* check conditionals (If-Modified-Since, etc) */
  -            c->xcache = ap_pstrcat(r->pool, "HIT from ", ap_get_server_name(r), NULL);
  -            return ap_proxy_cache_conditional(r, c, cachefp);
  +    /* extract min-fresh */
  +    if (cc_req && ap_proxy_liststr(cc_req, "min-fresh", &val))
  +        minfresh = atoi(val);
  +    else
  +        minfresh = 0;
   
  +    /* override maxstale if must-revalidate or proxy-revalidate */
  +    if (maxstale && ((cc_cresp && ap_proxy_liststr(cc_cresp, "must-revalidate", NULL)) || (cc_cresp && ap_proxy_liststr(cc_cresp, "proxy-revalidate", NULL))))
  +        maxstale = 0;
  +
  +    now = time(NULL);
  +    if (cachefp != NULL &&
  +
  +    /* handle no-cache */
  +        !((cc_req && ap_proxy_liststr(cc_req, "no-cache", NULL)) ||
  +          (pragma_req && ap_proxy_liststr(pragma_req, "no-cache", NULL)) ||
  +          (cc_cresp && ap_proxy_liststr(cc_cresp, "no-cache", NULL)) ||
  +      (pragma_cresp && ap_proxy_liststr(pragma_cresp, "no-cache", NULL))) &&
  +
  +    /* handle expiration */
  +        ((-1 < smaxage && age < (smaxage - minfresh)) ||
  +         (-1 < maxage && age < (maxage + maxstale - minfresh)) ||
  +         (c->expire != BAD_DATE && age < (c->expire - c->date + maxstale - minfresh)))
  +        ) {
  +
  +        /* it's fresh darlings... */
  +
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Unexpired data available");
  +
  +        /* set age header on response */
  +        ap_table_set(c->hdrs, "Age",
  +                     ap_psprintf(r->pool, "%lu", (unsigned long)age));
  +
  +        /* add warning if maxstale overrode freshness calculation */
  +        if (!((-1 < smaxage && age < smaxage) ||
  +              (-1 < maxage && age < maxage) ||
  +              (c->expire != BAD_DATE && (c->expire - c->date) > age))) {
  +            /* make sure we don't stomp on a previous warning */
  +            ap_table_merge(c->hdrs, "Warning", "110 Response is stale");
  +        }
  +
  +        /* check conditionals (If-Modified-Since, etc) */
  +        c->xcache = ap_pstrcat(r->pool, "HIT from ", ap_get_server_name(r), NULL);
  +        return ap_proxy_cache_conditional(r, c, cachefp);
   
  -        }
   
  -        /*
  -         * at this point we have determined our cached data needs
  -         * revalidation but first - we check 1 thing:
  -         * 
  -         * RFC2616 14.9.4 - if "only-if-cached" specified, send a 504 Gateway
  -         * Timeout - we're not allowed to revalidate the object
  -         */
  -        if (ap_proxy_liststr(cc_req, "only-if-cached", NULL)) {
  -            if (cachefp)
  -                ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
  -            return HTTP_GATEWAY_TIME_OUT;
  -        }
  +    }
   
  +    /*
  +     * at this point we have determined our cached data needs revalidation
  +     * but first - we check 1 thing:
  +     * 
  +     * RFC2616 14.9.4 - if "only-if-cached" specified, send a 504 Gateway
  +     * Timeout - we're not allowed to revalidate the object
  +     */
  +    if (ap_proxy_liststr(cc_req, "only-if-cached", NULL)) {
  +        if (cachefp)
  +            ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
  +        return HTTP_GATEWAY_TIME_OUT;
  +    }
   
  -        /*
  -         * If we already have cached data and a last-modified date, and it is
  -         * not a head request, then add an If-Modified-Since.
  -         * 
  -         * If we also have an Etag, then the object must have come from an
  -         * HTTP/1.1 server. Add an If-None-Match as well.
  -         * 
  -         * See RFC2616 13.3.4
  -         */
   
  -        if (cachefp != NULL && !r->header_only) {
  +    /*
  +     * If we already have cached data and a last-modified date, and it is not
  +     * a head request, then add an If-Modified-Since.
  +     * 
  +     * If we also have an Etag, then the object must have come from an HTTP/1.1
  +     * server. Add an If-None-Match as well.
  +     * 
  +     * See RFC2616 13.3.4
  +     */
   
  -            const char *etag = ap_table_get(c->hdrs, "Etag");
  +    if (cachefp != NULL && !r->header_only) {
   
  -            /* If-Modified-Since */
  -            if (c->lmod != BAD_DATE) {
  -                /*
  -                 * use the later of the one from the request and the
  -                 * last-modified date from the cache
  -                 */
  -                if (c->ims == BAD_DATE || c->ims < c->lmod) {
  -                    const char *q;
  +        const char *etag = ap_table_get(c->hdrs, "Etag");
   
  -                    if ((q = ap_table_get(c->hdrs, "Last-Modified")) != NULL)
  -                        ap_table_set(r->headers_in, "If-Modified-Since", (char *)q);
  -                }
  -            }
  +        /* If-Modified-Since */
  +        if (c->lmod != BAD_DATE) {
  +            /*
  +             * use the later of the one from the request and the
  +             * last-modified date from the cache
  +             */
  +            if (c->ims == BAD_DATE || c->ims < c->lmod) {
  +                const char *q;
   
  -            /* If-None-Match */
  -            if (etag) {
  -                ap_table_set(r->headers_in, "If-None-Match", etag);
  +                if ((q = ap_table_get(c->hdrs, "Last-Modified")) != NULL)
  +                    ap_table_set(r->headers_in, "If-Modified-Since", (char *)q);
               }
  +        }
   
  +        /* If-None-Match */
  +        if (etag) {
  +            ap_table_set(r->headers_in, "If-None-Match", etag);
           }
   
  +    }
   
  -        c->fp = cachefp;
   
  -        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Local copy not present or expired. Declining.");
  +    c->fp = cachefp;
   
  -        return DECLINED;
  -    }
  +    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Local copy not present or expired. Declining.");
  +
  +    return DECLINED;
  +}
   
   /*
    * Having read the response from the client, decide what to do
  @@ -1304,183 +1302,182 @@
    *  from the cache, maybe updating the header line
    *  otherwise, delete the old cached file and open a new temporary file
    */
  -    int ap_proxy_cache_update(cache_req *c, table *resp_hdrs,
  -                                  const int is_HTTP1, int nocache){
  +int ap_proxy_cache_update(cache_req *c, table *resp_hdrs,
  +                              const int is_HTTP1, int nocache)
  +{
   #if defined(ULTRIX_BRAIN_DEATH) || defined(SINIX_D_RESOLVER_BUG)
  -        extern char *mktemp(char *template);
  +    extern char *mktemp(char *template);
   #endif
  -        request_rec *r = c->req;
  -        char *p;
  -             const char *expire, *lmods, *dates, *clen;
  -        time_t expc, date, lmod, now;
  -        char buff[17 * 7 + 1];
  -        void *sconf = r->server->module_config;
  -        proxy_server_conf *conf =
  -        (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
  -                          const char *cc_resp;
  -        table *req_hdrs;
  +    request_rec *r = c->req;
  +    char *p;
  +    const char *expire, *lmods, *dates, *clen;
  +    time_t expc, date, lmod, now;
  +    char buff[17 * 7 + 1];
  +    void *sconf = r->server->module_config;
  +    proxy_server_conf *conf =
  +    (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
  +    const char *cc_resp;
  +    table *req_hdrs;
   
  -              cc_resp = ap_table_get(resp_hdrs, "Cache-Control");
  +    cc_resp = ap_table_get(resp_hdrs, "Cache-Control");
   
  -              c->tempfile = NULL;
  +    c->tempfile = NULL;
   
  -        /* we've received the response from the origin server */
  +    /* we've received the response from the origin server */
   
  -        /*
  -         * read expiry date; if a bad date, then leave it so the client can
  -         * read it
  -         */
  -              expire = ap_table_get(resp_hdrs, "Expires");
  -        if    (expire != NULL)
  -                  expc = ap_parseHTTPdate(expire);
  -        else
  -                  expc = BAD_DATE;
  +    /*
  +     * read expiry date; if a bad date, then leave it so the client can read
  +     * it
  +     */
  +    expire = ap_table_get(resp_hdrs, "Expires");
  +    if (expire != NULL)
  +        expc = ap_parseHTTPdate(expire);
  +    else
  +        expc = BAD_DATE;
   
  -        /* read the last-modified date; if the date is bad, then delete it */
  -              lmods = ap_table_get(resp_hdrs, "Last-Modified");
  -        if    (lmods != NULL) {
  -            lmod = ap_parseHTTPdate(lmods);
  -            if (lmod == BAD_DATE) {
  -                /* kill last modified date */
  -                lmods = NULL;
  -            }
  +    /* read the last-modified date; if the date is bad, then delete it */
  +    lmods = ap_table_get(resp_hdrs, "Last-Modified");
  +    if (lmods != NULL) {
  +        lmod = ap_parseHTTPdate(lmods);
  +        if (lmod == BAD_DATE) {
  +            /* kill last modified date */
  +            lmods = NULL;
           }
  -        else
  -                lmod = BAD_DATE;
  -
  +    }
  +    else
  +        lmod = BAD_DATE;
   
  -        /*
  -         * what responses should we not cache?
  -         * 
  -         * At this point we decide based on the response headers whether it is
  -         * appropriate _NOT_ to cache the data from the server. There are a
  -         * whole lot of conditions that prevent us from caching this data.
  -         * They are tested here one by one to be clear and unambiguous.
  -         */
   
  -        /*
  -         * RFC2616 13.4 we are allowed to cache 200, 203, 206, 300, 301 or
  -         * 410 We don't cache 206, because we don't (yet) cache partial
  -         * responses. We include 304 Not Modified here too as this is the
  -         * origin server telling us to serve the cached copy.
  -         */
  -        if ((r->status != HTTP_OK && r->status != HTTP_NON_AUTHORITATIVE && r->status != HTTP_MULTIPLE_CHOICES && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) ||
  +    /*
  +     * what responses should we not cache?
  +     * 
  +     * At this point we decide based on the response headers whether it is
  +     * appropriate _NOT_ to cache the data from the server. There are a whole
  +     * lot of conditions that prevent us from caching this data. They are
  +     * tested here one by one to be clear and unambiguous.
  +     */
   
  -        /* if a broken Expires header is present, don't cache it */
  -            (expire != NULL && expc == BAD_DATE) ||
  +    /*
  +     * RFC2616 13.4 we are allowed to cache 200, 203, 206, 300, 301 or 410 We
  +     * don't cache 206, because we don't (yet) cache partial responses. We
  +     * include 304 Not Modified here too as this is the origin server telling
  +     * us to serve the cached copy.
  +     */
  +    if ((r->status != HTTP_OK && r->status != HTTP_NON_AUTHORITATIVE && r->status != HTTP_MULTIPLE_CHOICES && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) ||
   
  -        /*
  -         * if the server said 304 Not Modified but we have no cache file -
  -         * pass this untouched to the user agent, it's not for us.
  -         */
  -         (r->status == HTTP_NOT_MODIFIED && (c == NULL || c->fp == NULL)) ||
  +    /* if a broken Expires header is present, don't cache it */
  +        (expire != NULL && expc == BAD_DATE) ||
   
  -        /*
  -         * 200 OK response from HTTP/1.0 and up without a Last-Modified
  -         * header
  -         */
  -            (r->status == HTTP_OK && lmods == NULL && is_HTTP1) ||
  +    /*
  +     * if the server said 304 Not Modified but we have no cache file - pass
  +     * this untouched to the user agent, it's not for us.
  +     */
  +        (r->status == HTTP_NOT_MODIFIED && (c == NULL || c->fp == NULL)) ||
   
  -        /* HEAD requests */
  -            r->header_only ||
  +    /*
  +     * 200 OK response from HTTP/1.0 and up without a Last-Modified header
  +     */
  +        (r->status == HTTP_OK && lmods == NULL && is_HTTP1) ||
   
  -        /*
  -         * RFC2616 14.9.2 Cache-Control: no-store response indicating do not
  -         * cache, or stop now if you are trying to cache it
  -         */
  -            ap_proxy_liststr(cc_resp, "no-store", NULL) ||
  +    /* HEAD requests */
  +        r->header_only ||
   
  -        /*
  -         * RFC2616 14.9.1 Cache-Control: private this object is marked for
  -         * this user's eyes only. Behave as a tunnel.
  -         */
  -            ap_proxy_liststr(cc_resp, "private", NULL) ||
  +    /*
  +     * RFC2616 14.9.2 Cache-Control: no-store response indicating do not
  +     * cache, or stop now if you are trying to cache it
  +     */
  +        ap_proxy_liststr(cc_resp, "no-store", NULL) ||
   
  -        /*
  -         * RFC2616 14.8 Authorisation: if authorisation is included in the
  -         * request, we don't cache, but we can cache if the following
  -         * exceptions are true: 1) If Cache-Control: s-maxage is included 2)
  -         * If Cache-Control: must-revalidate is included 3) If Cache-Control:
  -         * public is included
  -         */
  -            (ap_table_get(r->headers_in, "Authorization") != NULL
  +    /*
  +     * RFC2616 14.9.1 Cache-Control: private this object is marked for this
  +     * user's eyes only. Behave as a tunnel.
  +     */
  +        ap_proxy_liststr(cc_resp, "private", NULL) ||
   
  -             && !(ap_proxy_liststr(cc_resp, "s-maxage", NULL) || ap_proxy_liststr(cc_resp, "must-revalidate", NULL) || ap_proxy_liststr(cc_resp, "public", NULL))
  -             ) ||
  +    /*
  +     * RFC2616 14.8 Authorisation: if authorisation is included in the
  +     * request, we don't cache, but we can cache if the following exceptions
  +     * are true: 1) If Cache-Control: s-maxage is included 2) If
  +     * Cache-Control: must-revalidate is included 3) If Cache-Control: public
  +     * is included
  +     */
  +        (ap_table_get(r->headers_in, "Authorization") != NULL
   
  -        /* or we've been asked not to cache it above */
  -            nocache) {
  +         && !(ap_proxy_liststr(cc_resp, "s-maxage", NULL) || ap_proxy_liststr(cc_resp, "must-revalidate", NULL) || ap_proxy_liststr(cc_resp, "public", NULL))
  +         ) ||
   
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Response is not cacheable, unlinking %s", c->filename);
  +    /* or we've been asked not to cache it above */
  +        nocache) {
   
  -            /* close the file */
  -            if (c->fp != NULL) {
  -                ap_pclosef(r->pool, ap_bfileno(c->fp, B_WR));
  -                c->fp = NULL;
  -            }
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Response is not cacheable, unlinking %s", c->filename);
   
  -            /* delete the previously cached file */
  -            if (c->filename)
  -                unlink(c->filename);
  -            return DECLINED;    /* send data to client but not cache */
  +        /* close the file */
  +        if (c->fp != NULL) {
  +            ap_pclosef(r->pool, ap_bfileno(c->fp, B_WR));
  +            c->fp = NULL;
           }
   
  +        /* delete the previously cached file */
  +        if (c->filename)
  +            unlink(c->filename);
  +        return DECLINED;        /* send data to client but not cache */
  +    }
   
  -        /*
  -         * It's safe to cache the response.
  -         * 
  -         * We now want to update the cache file header information with the new
  -         * date, last modified, expire and content length and write it away
  -         * to our cache file. First, we determine these values from the
  -         * response, using heuristics if appropriate.
  -         * 
  -         * In addition, we make HTTP/1.1 age calculations and write them away
  -         * too.
  -         */
   
  -        /* Read the date. Generate one if one is not supplied */
  -        dates = ap_table_get(resp_hdrs, "Date");
  -        if (dates != NULL)
  -            date = ap_parseHTTPdate(dates);
  -        else
  -            date = BAD_DATE;
  +    /*
  +     * It's safe to cache the response.
  +     * 
  +     * We now want to update the cache file header information with the new
  +     * date, last modified, expire and content length and write it away to
  +     * our cache file. First, we determine these values from the response,
  +     * using heuristics if appropriate.
  +     * 
  +     * In addition, we make HTTP/1.1 age calculations and write them away too.
  +     */
   
  -        now = time(NULL);
  +    /* Read the date. Generate one if one is not supplied */
  +    dates = ap_table_get(resp_hdrs, "Date");
  +    if (dates != NULL)
  +        date = ap_parseHTTPdate(dates);
  +    else
  +        date = BAD_DATE;
   
  -        if (date == BAD_DATE) { /* No, or bad date */
  +    now = time(NULL);
  +
  +    if (date == BAD_DATE) {     /* No, or bad date */
   /* no date header! */
   /* add one; N.B. use the time _now_ rather than when we were checking the cache
    */
  -            date = now;
  -            dates = ap_gm_timestr_822(r->pool, now);
  -            ap_table_set(resp_hdrs, "Date", dates);
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Added date header");
  -        }
  +        date = now;
  +        dates = ap_gm_timestr_822(r->pool, now);
  +        ap_table_set(resp_hdrs, "Date", dates);
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Added date header");
  +    }
   
   /* set response_time for HTTP/1.1 age calculations */
  -        c->resp_time = now;
  +    c->resp_time = now;
   
   /* check last-modified date */
  -        if (lmod != BAD_DATE && lmod > date)
  +    if (lmod != BAD_DATE && lmod > date)
   /* if its in the future, then replace by date */
  -        {
  -            lmod = date;
  -            lmods = dates;
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Last modified is in the future, replacing with now");
  -        }
  +    {
  +        lmod = date;
  +        lmods = dates;
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Last modified is in the future, replacing with now");
  +    }
   /* if the response did not contain the header, then use the cached version */
  -        if (lmod == BAD_DATE && c->fp != NULL) {
  -            lmod = c->lmod;
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Reusing cached last modified");
  -        }
  +    if (lmod == BAD_DATE && c->fp != NULL) {
  +        lmod = c->lmod;
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Reusing cached last modified");
  +    }
   
   /* we now need to calculate the expire data for the object. */
  -        if (expire == NULL && c->fp != NULL) {  /* no expiry data sent in
  +    if (expire == NULL && c->fp != NULL) {      /* no expiry data sent in
                                                    * response */
  -            expire = ap_table_get(c->hdrs, "Expires");
  -            if (expire != NULL)
  -                expc = ap_parseHTTPdate(expire);
  -        }
  +        expire = ap_table_get(c->hdrs, "Expires");
  +        if (expire != NULL)
  +            expc = ap_parseHTTPdate(expire);
  +    }
   /* so we now have the expiry date */
   /* if no expiry date then
    *   if lastmod
  @@ -1488,44 +1485,44 @@
    *   else
    *      expire date = now + defaultexpire
    */
  -        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Expiry date is %ld", (long)expc);
  -        if (expc == BAD_DATE) {
  -            if (lmod != BAD_DATE) {
  -                double x = (double)(date - lmod) * conf->cache.lmfactor;
  -                double maxex = conf->cache.maxexpire;
  -                if (x > maxex)
  -                    x = maxex;
  -                expc = now + (int)x;
  -            }
  -            else
  -                expc = now + conf->cache.defaultexpire;
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Expiry date calculated %ld", (long)expc);
  +    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Expiry date is %ld", (long)expc);
  +    if (expc == BAD_DATE) {
  +        if (lmod != BAD_DATE) {
  +            double x = (double)(date - lmod) * conf->cache.lmfactor;
  +            double maxex = conf->cache.maxexpire;
  +            if (x > maxex)
  +                x = maxex;
  +            expc = now + (int)x;
           }
  +        else
  +            expc = now + conf->cache.defaultexpire;
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Expiry date calculated %ld", (long)expc);
  +    }
   
   /* get the content-length header */
  -        clen = ap_table_get(resp_hdrs, "Content-Length");
  -        if (clen == NULL)
  -            c->len = -1;
  -        else
  -            c->len = atoi(clen);
  +    clen = ap_table_get(resp_hdrs, "Content-Length");
  +    if (clen == NULL)
  +        c->len = -1;
  +    else
  +        c->len = atoi(clen);
   
   /* we have all the header information we need - write it to the cache file */
  -        c->version++;
  -        ap_proxy_sec2hex(date, buff + 17 * (0));
  -        buff[17 * (1) - 1] = ' ';
  -        ap_proxy_sec2hex(lmod, buff + 17 * (1));
  -        buff[17 * (2) - 1] = ' ';
  -        ap_proxy_sec2hex(expc, buff + 17 * (2));
  -        buff[17 * (3) - 1] = ' ';
  -        ap_proxy_sec2hex(c->version, buff + 17 * (3));
  -        buff[17 * (4) - 1] = ' ';
  -        ap_proxy_sec2hex(c->req_time, buff + 17 * (4));
  -        buff[17 * (5) - 1] = ' ';
  -        ap_proxy_sec2hex(c->resp_time, buff + 17 * (5));
  -        buff[17 * (6) - 1] = ' ';
  -        ap_proxy_sec2hex(c->len, buff + 17 * (6));
  -        buff[17 * (7) - 1] = '\n';
  -        buff[17 * (7)] = '\0';
  +    c->version++;
  +    ap_proxy_sec2hex(date, buff + 17 * (0));
  +    buff[17 * (1) - 1] = ' ';
  +    ap_proxy_sec2hex(lmod, buff + 17 * (1));
  +    buff[17 * (2) - 1] = ' ';
  +    ap_proxy_sec2hex(expc, buff + 17 * (2));
  +    buff[17 * (3) - 1] = ' ';
  +    ap_proxy_sec2hex(c->version, buff + 17 * (3));
  +    buff[17 * (4) - 1] = ' ';
  +    ap_proxy_sec2hex(c->req_time, buff + 17 * (4));
  +    buff[17 * (5) - 1] = ' ';
  +    ap_proxy_sec2hex(c->resp_time, buff + 17 * (5));
  +    buff[17 * (6) - 1] = ' ';
  +    ap_proxy_sec2hex(c->len, buff + 17 * (6));
  +    buff[17 * (7) - 1] = '\n';
  +    buff[17 * (7)] = '\0';
   
   /* Was the server response a 304 Not Modified?
    *
  @@ -1535,28 +1532,28 @@
    */
   
   /* if response from server 304 not modified */
  -        if (r->status == HTTP_NOT_MODIFIED) {
  +    if (r->status == HTTP_NOT_MODIFIED) {
   
   /* Have the headers changed?
    *
    * if not - we fulfil the request and return now.
    */
   
  -            if (c->hdrs) {
  -                if (!ap_proxy_table_replace(c->hdrs, resp_hdrs)) {
  -                    c->xcache = ap_pstrcat(r->pool, "HIT from ", ap_get_server_name(r), " (with revalidation)", NULL);
  -                    return ap_proxy_cache_conditional(r, c, c->fp);
  -                }
  +        if (c->hdrs) {
  +            if (!ap_proxy_table_replace(c->hdrs, resp_hdrs)) {
  +                c->xcache = ap_pstrcat(r->pool, "HIT from ", ap_get_server_name(r), " (with revalidation)", NULL);
  +                return ap_proxy_cache_conditional(r, c, c->fp);
               }
  -            else
  -                c->hdrs = resp_hdrs;
  +        }
  +        else
  +            c->hdrs = resp_hdrs;
   /* if we get here - the headers have changed. Go through the motions
    * of creating a new temporary cache file below, we'll then serve
    * the request like we would have in ap_proxy_cache_conditional()
    * above, and at the same time we will also rewrite the contents
    * to the new temporary file.
    */
  -        }
  +    }
   
   /*
    * Ok - lets prepare and open the cached file
  @@ -1573,78 +1570,78 @@
    */
   
   /* if a cache file was already open */
  -        if (c->fp != NULL) {
  -            c->origfp = c->fp;
  -        }
  +    if (c->fp != NULL) {
  +        c->origfp = c->fp;
  +    }
   
  -        while (1) {
  +    while (1) {
   /* create temporary filename */
   #ifndef TPF
   #define TMPFILESTR    "/tmpXXXXXX"
  -            if (conf->cache.root == NULL) {
  -                c = ap_proxy_cache_error(c);
  -                break;
  -            }
  -            c->tempfile = ap_palloc(r->pool, strlen(conf->cache.root) + sizeof(TMPFILESTR));
  -            strcpy(c->tempfile, conf->cache.root);
  -            strcat(c->tempfile, TMPFILESTR);
  +        if (conf->cache.root == NULL) {
  +            c = ap_proxy_cache_error(c);
  +            break;
  +        }
  +        c->tempfile = ap_palloc(r->pool, strlen(conf->cache.root) + sizeof(TMPFILESTR));
  +        strcpy(c->tempfile, conf->cache.root);
  +        strcat(c->tempfile, TMPFILESTR);
   #undef TMPFILESTR
  -            p = mktemp(c->tempfile);
  +        p = mktemp(c->tempfile);
   #else
  -            if (conf->cache.root == NULL) {
  -                c = ap_proxy_cache_error(c);
  -                break;
  -            }
  -            c->tempfile = ap_palloc(r->pool, strlen(conf->cache.root) + 1 + L_tmpnam);
  -            strcpy(c->tempfile, conf->cache.root);
  -            strcat(c->tempfile, "/");
  -            p = tmpnam(NULL);
  -            strcat(c->tempfile, p);
  +        if (conf->cache.root == NULL) {
  +            c = ap_proxy_cache_error(c);
  +            break;
  +        }
  +        c->tempfile = ap_palloc(r->pool, strlen(conf->cache.root) + 1 + L_tmpnam);
  +        strcpy(c->tempfile, conf->cache.root);
  +        strcat(c->tempfile, "/");
  +        p = tmpnam(NULL);
  +        strcat(c->tempfile, p);
   #endif
  -            if (p == NULL) {
  -                c = ap_proxy_cache_error(c);
  -                break;
  -            }
  +        if (p == NULL) {
  +            c = ap_proxy_cache_error(c);
  +            break;
  +        }
   
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Create temporary file %s", c->tempfile);
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Create temporary file %s", c->tempfile);
   
   /* create the new file */
  -            c->fp = ap_proxy_create_cachefile(r, c->tempfile);
  -            if (NULL == c->fp) {
  -                c = ap_proxy_cache_error(c);
  -                break;
  -            }
  +        c->fp = ap_proxy_create_cachefile(r, c->tempfile);
  +        if (NULL == c->fp) {
  +            c = ap_proxy_cache_error(c);
  +            break;
  +        }
   
   /* write away the cache header and the URL */
  -            if (ap_bvputs(c->fp, buff, "X-URL: ", c->url, "\n", NULL) == -1) {
  -                ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  +        if (ap_bvputs(c->fp, buff, "X-URL: ", c->url, "\n", NULL) == -1) {
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
                           "proxy: error writing cache file(%s)", c->tempfile);
  -                c = ap_proxy_cache_error(c);
  -                break;
  -            }
  +            c = ap_proxy_cache_error(c);
  +            break;
  +        }
   
   /* get original request headers */
  -            if (c->req_hdrs)
  -                req_hdrs = ap_copy_table(r->pool, c->req_hdrs);
  -            else
  -                req_hdrs = ap_copy_table(r->pool, r->headers_in);
  +        if (c->req_hdrs)
  +            req_hdrs = ap_copy_table(r->pool, c->req_hdrs);
  +        else
  +            req_hdrs = ap_copy_table(r->pool, r->headers_in);
   
   /* remove hop-by-hop headers */
  -            ap_proxy_clear_connection(r->pool, req_hdrs);
  +        ap_proxy_clear_connection(r->pool, req_hdrs);
   
   /* save original request headers */
  -            if (c->req_hdrs)
  -                ap_table_do(ap_proxy_send_hdr_line, c, c->req_hdrs, NULL);
  -            else
  -                ap_table_do(ap_proxy_send_hdr_line, c, r->headers_in, NULL);
  -            if (ap_bputs(CRLF, c->fp) == -1) {
  -                ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
  -                              "proxy: error writing request headers terminating CRLF to %s", c->tempfile);
  -                c = ap_proxy_cache_error(c);
  -                break;
  -            }
  +        if (c->req_hdrs)
  +            ap_table_do(ap_proxy_send_hdr_line, c, c->req_hdrs, NULL);
  +        else
  +            ap_table_do(ap_proxy_send_hdr_line, c, r->headers_in, NULL);
  +        if (ap_bputs(CRLF, c->fp) == -1) {
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
  +                          "proxy: error writing request headers terminating CRLF to %s", c->tempfile);
  +            c = ap_proxy_cache_error(c);
               break;
           }
  +        break;
  +    }
   
   /* Was the server response a 304 Not Modified?
    *
  @@ -1654,38 +1651,39 @@
    */
   
   /* if response from server 304 not modified */
  -        if (r->status == HTTP_NOT_MODIFIED) {
  +    if (r->status == HTTP_NOT_MODIFIED) {
   
   /* fulfil the request */
  -            c->xcache = ap_pstrcat(r->pool, "HIT from ", ap_get_server_name(r), " (with revalidation)", NULL);
  -            return ap_proxy_cache_conditional(r, c, c->fp);
  +        c->xcache = ap_pstrcat(r->pool, "HIT from ", ap_get_server_name(r), " (with revalidation)", NULL);
  +        return ap_proxy_cache_conditional(r, c, c->fp);
   
  -        }
  -        return DECLINED;
       }
  +    return DECLINED;
  +}
   
  -    void ap_proxy_cache_tidy(cache_req *c){
  -        server_rec *s;
  -        long int bc;
  +void ap_proxy_cache_tidy(cache_req *c)
  +{
  +    server_rec *s;
  +    long int bc;
   
  -        if  (!c || !c->fp)
  -                return;
  +    if (!c || !c->fp)
  +        return;
   
  -            s = c->req->server;
  +    s = c->req->server;
   
   /* don't care how much was sent, but rather how much was written to cache
       ap_bgetopt(c->req->connection->client, BO_BYTECT, &bc);
    */
  -            bc = c->written;
  +    bc = c->written;
   
  -        if  (c->len != -1) {
  +    if (c->len != -1) {
   /* file lengths don't match; don't cache it */
  -            if (bc != c->len) {
  -                ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR));      /* no need to flush */
  -                unlink(c->tempfile);
  -                return;
  -            }
  +        if (bc != c->len) {
  +            ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR));  /* no need to flush */
  +            unlink(c->tempfile);
  +            return;
           }
  +    }
   /* don't care if aborted, cache it if fully retrieved from host!
       else if (c->req->connection->aborted) {
           ap_pclosef(c->req->pool, c->fp->fd);    / no need to flush /
  @@ -1693,86 +1691,85 @@
           return;
       }
   */
  -        else {
  +    else {
   /* update content-length of file */
  -            char buff[17];
  -            off_t curpos;
  +        char buff[17];
  +        off_t curpos;
   
  -            c->len = bc;
  -            ap_bflush(c->fp);
  -            ap_proxy_sec2hex(c->len, buff);
  -            curpos = lseek(ap_bfileno(c->fp, B_WR), 17 * 6, SEEK_SET);
  -            if (curpos == -1)
  -                ap_log_error(APLOG_MARK, APLOG_ERR, s,
  +        c->len = bc;
  +        ap_bflush(c->fp);
  +        ap_proxy_sec2hex(c->len, buff);
  +        curpos = lseek(ap_bfileno(c->fp, B_WR), 17 * 6, SEEK_SET);
  +        if (curpos == -1)
  +            ap_log_error(APLOG_MARK, APLOG_ERR, s,
                         "proxy: error seeking on cache file %s", c->tempfile);
  -            else if (write(ap_bfileno(c->fp, B_WR), buff, sizeof(buff) - 1) == -1)
  -                ap_log_error(APLOG_MARK, APLOG_ERR, s,
  -                        "proxy: error updating cache file %s", c->tempfile);
  -        }
  -
  -        if (ap_bflush(c->fp) == -1) {
  +        else if (write(ap_bfileno(c->fp, B_WR), buff, sizeof(buff) - 1) == -1)
               ap_log_error(APLOG_MARK, APLOG_ERR, s,
  -                         "proxy: error writing to cache file %s",
  -                         c->tempfile);
  -            ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR));
  -            unlink(c->tempfile);
  -            return;
  -        }
  +                         "proxy: error updating cache file %s", c->tempfile);
  +    }
   
  -        if (ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR))== -1) {
  -            ap_log_error(APLOG_MARK, APLOG_ERR, s,
  -                         "proxy: error closing cache file %s", c->tempfile);
  -            unlink(c->tempfile);
  -            return;
  -        }
  +    if (ap_bflush(c->fp) == -1) {
  +        ap_log_error(APLOG_MARK, APLOG_ERR, s,
  +                     "proxy: error writing to cache file %s",
  +                     c->tempfile);
  +        ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR));
  +        unlink(c->tempfile);
  +        return;
  +    }
   
  -        if (unlink(c->filename) == -1 && errno != ENOENT) {
  -            ap_log_error(APLOG_MARK, APLOG_ERR, s,
  -                         "proxy: error deleting old cache file %s",
  -                         c->tempfile);
  -        }
  -        else {
  -            char *p;
  -            proxy_server_conf *conf =
  -            (proxy_server_conf *)ap_get_module_config(s->module_config, &proxy_module);
  -
  -            for (p = c->filename + strlen(conf->cache.root) + 1;;) {
  -                p = strchr(p, '/');
  -                if (!p)
  -                    break;
  -                *p = '\0';
  +    if (ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR))== -1) {
  +        ap_log_error(APLOG_MARK, APLOG_ERR, s,
  +                     "proxy: error closing cache file %s", c->tempfile);
  +        unlink(c->tempfile);
  +        return;
  +    }
  +
  +    if (unlink(c->filename) == -1 && errno != ENOENT) {
  +        ap_log_error(APLOG_MARK, APLOG_ERR, s,
  +                     "proxy: error deleting old cache file %s",
  +                     c->filename);
  +        (void)unlink(c->tempfile);
  +    }
  +    else {
  +        char *p;
  +        proxy_server_conf *conf =
  +        (proxy_server_conf *)ap_get_module_config(s->module_config, &proxy_module);
  +
  +        for (p = c->filename + strlen(conf->cache.root) + 1;;) {
  +            p = strchr(p, '/');
  +            if (!p)
  +                break;
  +            *p = '\0';
   #if defined(WIN32) || defined(NETWARE)
  -                if (mkdir(c->filename) < 0 && errno != EEXIST)
  +            if (mkdir(c->filename) < 0 && errno != EEXIST)
   #elif defined(__TANDEM)
  -                    if (mkdir(c->filename, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST)
  +                if (mkdir(c->filename, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST)
   #else
  -                if (mkdir(c->filename, S_IREAD | S_IWRITE | S_IEXEC) < 0 && errno != EEXIST)
  +            if (mkdir(c->filename, S_IREAD | S_IWRITE | S_IEXEC) < 0 && errno != EEXIST)
   #endif                          /* WIN32 */
  -                    ap_log_error(APLOG_MARK, APLOG_ERR, s,
  -                                 "proxy: error creating cache directory %s",
  -                                 c->filename);
  -                *p = '/';
  -                ++p;
  -            }
  -#if defined(OS2) || defined(WIN32) || defined(NETWARE) || defined(MPE)
  -            /* Under OS/2 use rename. */
  -            if (rename(c->tempfile, c->filename) == -1)
                   ap_log_error(APLOG_MARK, APLOG_ERR, s,
  -                             "proxy: error renaming cache file %s to %s",
  -                             c->tempfile, c->filename);
  +                             "proxy: error creating cache directory %s",
  +                             c->filename);
  +            *p = '/';
  +            ++p;
           }
  +#if defined(OS2) || defined(WIN32) || defined(NETWARE) || defined(MPE)
  +        /* Under OS/2 use rename. */
  +        if (rename(c->tempfile, c->filename) == -1) {
  +            ap_log_error(APLOG_MARK, APLOG_ERR, s,
  +                         "proxy: error renaming cache file %s to %s",
  +                         c->tempfile, c->filename);
  +            (void)unlink(c->tempfile);
  +	}
   #else
   
  -            if (link(c->tempfile, c->filename) == -1)
  -                ap_log_error(APLOG_MARK, APLOG_ERR, s,
  -                             "proxy: error linking cache file %s to %s",
  -                             c->tempfile, c->filename);
  -        }
  -
  +        if (link(c->tempfile, c->filename) == -1)
  +            ap_log_error(APLOG_MARK, APLOG_ERR, s,
  +                         "proxy: error linking cache file %s to %s",
  +                         c->tempfile, c->filename);
           if (unlink(c->tempfile) == -1)
               ap_log_error(APLOG_MARK, APLOG_ERR, s,
                            "proxy: error deleting temp file %s", c->tempfile);
   #endif
  -
       }
  -/**INDENT** Error@1753: Stuff missing from end of file. */
  +}