return len;
+}
+
+/* do a HTTP/1.1 age calculation */
+time_t ap_proxy_current_age(cache_req *c, const time_t age_value)
+{
+ time_t apparent_age, corrected_received_age, response_delay, corrected_initial_age, resident_time, current_age;
+
+ /* Perform an HTTP/1.1 age calculation. (RFC2616 13.2.3) */
+
+ apparent_age = MAX(0, c->resp_time - c->date);
+ corrected_received_age = MAX(apparent_age, age_value);
+ response_delay = c->resp_time - c->req_time;
+ corrected_initial_age = corrected_received_age + response_delay;
+ resident_time = time(NULL) - c->resp_time;
+ current_age = corrected_initial_age + resident_time;
+
+ return (current_age);
+}
+
+/* open a cache file and return a pointer to a BUFF */
+BUFF *ap_proxy_open_cachefile(request_rec *r, char *filename)
+{
+ BUFF *cachefp = NULL;
+ int cfd;
+
+ if (filename != NULL) {
+ cfd = open(filename, O_RDWR | O_BINARY);
+ if (cfd != -1) {
+ ap_note_cleanups_for_fd(r->pool, cfd);
+ cachefp = ap_bcreate(r->pool, B_RD | B_WR);
+ ap_bpushfd(cachefp, cfd, cfd);
+ }
+ else if (errno != ENOENT)
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "proxy: error opening cache file %s",
+ filename);
+#ifdef EXPLAIN
+ else
+ Explain1("File %s not found", filename);
+#endif
+
+ }
+ return cachefp;
+}
+
+/* create a cache file and return a pointer to a BUFF */
+BUFF *ap_proxy_create_cachefile(request_rec *r, char *filename)
+{
+ BUFF *cachefp = NULL;
+ int cfd;
+
+ if (filename != NULL) {
+ cfd = open(filename, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0622);
+ if (cfd != -1) {
+ ap_note_cleanups_for_fd(r->pool, cfd);
+ cachefp = ap_bcreate(r->pool, B_WR);
+ ap_bpushfd(cachefp, -1, cfd);
+ }
+ else if (errno != ENOENT)
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "proxy: error creating cache file %s",
+ filename);
+ }
+ return cachefp;
+}
+
+/* Clear all connection-based headers from headers table */
+void ap_proxy_clear_connection(pool *p, table *headers)
+{
+ const char *name;
+ char *next = ap_pstrdup(p, ap_table_get(headers, "Connection"));
+
+ ap_table_unset(headers, "Proxy-Connection");
+ if (!next)
+ return;
+
+ while (*next) {
+ name = next;
+ while (*next && !ap_isspace(*next) && (*next != ','))
+ ++next;
+ while (*next && (ap_isspace(*next) || (*next == ','))) {
+ *next = '\0';
+ ++next;
+ }
+ ap_table_unset(headers, name);
+ }
+ ap_table_unset(headers, "Connection");
}
#if defined WIN32