From a610148aaa4b1a0538c6cd45589de6d48d6be1f3 Mon Sep 17 00:00:00 2001 From: Martin Kraemer Date: Tue, 9 Apr 2002 12:02:49 +0000 Subject: [PATCH] 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). PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@94580 13f79535-47bb-0310-9956-ffa450edef68 --- src/modules/proxy/proxy_cache.c | 1869 +++++++++++++++---------------- 1 file changed, 933 insertions(+), 936 deletions(-) diff --git a/src/modules/proxy/proxy_cache.c b/src/modules/proxy/proxy_cache.c index 36cd686d276..6e92c07fc42 100644 --- a/src/modules/proxy/proxy_cache.c +++ b/src/modules/proxy/proxy_cache.c @@ -89,7 +89,7 @@ struct gc_ent { 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 @@ void ap_proxy_garbage_coll(request_rec *r) } -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 @@ static void add_long61(long61_t * accu, long val) 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 @@ static void sub_long61(long61_t * accu, long val) * 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, #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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, * 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, * 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, * * 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, * 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, * 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")); - - 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; - } + /* + * 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 { - /* - * 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 - * 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); + /* 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; + } + } + } - /* extract s-maxage */ - if (cc_cresp && ap_proxy_liststr(cc_cresp, "s-maxage", &val)) - smaxage = atoi(val); - else - smaxage = -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; + /* + * 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 + * 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 max-age from response */ - if (cc_cresp && ap_proxy_liststr(cc_cresp, "max-age", &val)) - maxage_cresp = atoi(val); - else - maxage_cresp = -1; + /* calculate age of object */ + age = ap_proxy_current_age(c, age_c); - /* - * 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 s-maxage */ + if (cc_cresp && ap_proxy_liststr(cc_cresp, "s-maxage", &val)) + smaxage = atoi(val); + else + smaxage = -1; - /* extract max-stale */ - if (cc_req && ap_proxy_liststr(cc_req, "max-stale", &val)) - maxstale = atoi(val); - else - maxstale = 0; + /* 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 min-fresh */ - if (cc_req && ap_proxy_liststr(cc_req, "min-fresh", &val)) - minfresh = atoi(val); - else - minfresh = 0; + /* extract max-age from response */ + if (cc_cresp && ap_proxy_liststr(cc_cresp, "max-age", &val)) + maxage_cresp = atoi(val); + else + maxage_cresp = -1; - /* 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; + /* + * 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); - now = time(NULL); - if (cachefp != NULL && + /* extract max-stale */ + if (cc_req && ap_proxy_liststr(cc_req, "max-stale", &val)) + maxstale = atoi(val); + else + maxstale = 0; - /* 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))) && + /* extract min-fresh */ + if (cc_req && ap_proxy_liststr(cc_req, "min-fresh", &val)) + minfresh = atoi(val); + else + minfresh = 0; - /* handle expiration */ - ((-1 < smaxage && age < (smaxage - minfresh)) || - (-1 < maxage && age < (maxage + maxstale - minfresh)) || - (c->expire != BAD_DATE && age < (c->expire - c->date + maxstale - minfresh))) - ) { + /* 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; - /* it's fresh darlings... */ + now = time(NULL); + if (cachefp != NULL && - ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Unexpired data available"); + /* 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))) && - /* set age header on response */ - ap_table_set(c->hdrs, "Age", - ap_psprintf(r->pool, "%lu", (unsigned long)age)); + /* handle expiration */ + ((-1 < smaxage && age < (smaxage - minfresh)) || + (-1 < maxage && age < (maxage + maxstale - minfresh)) || + (c->expire != BAD_DATE && age < (c->expire - c->date + maxstale - minfresh))) + ) { - /* 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"); - } + /* it's fresh darlings... */ - /* 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); + 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"); } - /* - * 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; - } + /* 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); - /* - * 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 - */ + } + + /* + * 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 (cachefp != NULL && !r->header_only) { - const char *etag = ap_table_get(c->hdrs, "Etag"); + /* + * 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-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 (cachefp != NULL && !r->header_only) { - if ((q = ap_table_get(c->hdrs, "Last-Modified")) != NULL) - ap_table_set(r->headers_in, "If-Modified-Since", (char *)q); - } - } + const char *etag = ap_table_get(c->hdrs, "Etag"); - /* If-None-Match */ - if (etag) { - ap_table_set(r->headers_in, "If-None-Match", etag); + /* 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 ((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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, * 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 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 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; } - 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. + */ + + /* 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; - now = time(NULL); + now = time(NULL); - if (date == BAD_DATE) { /* No, or bad date */ + 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, * 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, */ /* 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, */ /* 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, */ /* 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 @@ static int sub_garbage_coll(request_rec *r, array_header *files, return; } */ - else { + else { /* update content-length of file */ - 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, + 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, "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. */ +} -- 2.47.2