www-modproxy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christian von Roques <roq...@mti.ag>
Subject Re: httpd 1.3.19 + proxy
Date Sun, 04 Mar 2001 16:49:01 GMT
Chuck Murcko <chuck@topsail.org> writes:
> http://dev.apache.org/dist/patches/apply_to_1.3.19/

In the mean time I've made some small whitespace and comment fixes to
my changes to Graham's HTTP/1.1 patch.  Below you'll find my changes
enabling Apaches mod_proxy with Graham's patches applied to make use
of HTTP/1.1 persistent connections with its clients.

The patch changes mod_proxy to write the reply-headers using
ap_send_http_header() instead of directly using ap_bvputs().  This not
only simplifies mod_proxy, in my opinion at least, but enables it to
make use of the features of Apache's normal header and persistent
connection machinery.  The patch is relative to apache 1.3.20dev from
CVS with Graham's HTTP/1.1 patch from
http://dev.apache.org/dist/patches/apply_to_1.3.19/ applied.

I've been swamped with other work and didn't find as much time as I
would have liked to test the patch.

I've found one peculiarity so, IE5.5 makes good use of persistent
connections when directly accessing some pages via HTTPS, but this
doesn't work when IE uses CONNECTs through a Squid to access the HTTPS
proxy.  The connections stay open, but are closed as soon as IE does
the next request.  This even is the case when IE's optiona setting to
use HTTP/1.1 persistent connections through a proxy is enabled.
Because Squid has to be transparent for HTTPS to work through
CONNECTs, it probably is a problem with IE and not the patched
mod_proxy.  Is this a known issue with IE?

        Christian.

diff -X nodiff.pats -wrdC 3 apache+graham_http1.1/src/main/http_protocol.c apache+http1.1_cache/src/main/http_protocol.c
*** apache+graham_http1.1/src/main/http_protocol.c	Sun Feb 18 12:51:07 2001
--- apache+http1.1_cache/src/main/http_protocol.c	Sun Feb 18 12:55:13 2001
***************
*** 1467,1478 ****
      if (!r->status_line)
          r->status_line = status_lines[ap_index_of_response(r->status)];
  
!     /* mod_proxy is only HTTP/1.0, so avoid sending HTTP/1.1 error response;
!      * kluge around broken browsers when indicated by force-response-1.0
       */
!     if (r->proxyreq != NOT_PROXY
!         || (r->proto_num == HTTP_VERSION(1,0)
!             && ap_table_get(r->subprocess_env, "force-response-1.0"))) {
  
          protocol = "HTTP/1.0";
          r->connection->keepalive = -1;
--- 1467,1476 ----
      if (!r->status_line)
          r->status_line = status_lines[ap_index_of_response(r->status)];
  
!     /* kluge around broken browsers when indicated by force-response-1.0
       */
!     if (r->proto_num == HTTP_VERSION(1,0)
! 	&& ap_table_get(r->subprocess_env, "force-response-1.0")) {
  
          protocol = "HTTP/1.0";
          r->connection->keepalive = -1;
diff -X nodiff.pats -wrdC 3 apache+graham_http1.1/src/modules/proxy/mod_proxy.h apache+http1.1_cache/src/modules/proxy/mod_proxy.h
*** apache+graham_http1.1/src/modules/proxy/mod_proxy.h	Sat Mar  3 15:21:58 2001
--- apache+http1.1_cache/src/modules/proxy/mod_proxy.h	Sat Mar  3 16:24:44 2001
***************
*** 273,285 ****
      char *xcache;		/* the X-Cache header value to be sent to client */
  } cache_req;
  
- /* Additional information passed to the function called by ap_table_do() */
- struct tbl_do_args {
-     request_rec *req;
-     cache_req *cache;
-     size_t len;
- };
- 
  struct per_thread_data {
      struct hostent hpbuf;
      u_long ipaddr;
--- 273,278 ----
***************
*** 324,330 ****
  const char *ap_proxy_date_canon(pool *p, const char *x);
  table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f);
  long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite);
! void ap_proxy_send_headers(request_rec *r, cache_req *c, const char *respline, const char
*xcache, table *t);
  int ap_proxy_liststr(const char *list, const char *key, char **val);
  void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength);
  int ap_proxy_hex2sec(const char *x);
--- 317,323 ----
  const char *ap_proxy_date_canon(pool *p, const char *x);
  table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f);
  long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite);
! void ap_proxy_write_headers(cache_req *c, const char *respline, table *t);
  int ap_proxy_liststr(const char *list, const char *key, char **val);
  void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength);
  int ap_proxy_hex2sec(const char *x);
***************
*** 339,345 ****
  int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
  int ap_proxy_garbage_init(server_rec *, pool *);
  /* This function is called by ap_table_do() for all header lines */
- int ap_proxy_count_hdr_line(void *p, const char *key, const char *value);
  int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
  unsigned ap_proxy_bputs2(const char *data, BUFF *client, cache_req *cache);
  time_t ap_proxy_current_age(cache_req *c, const time_t age_value);
--- 332,337 ----
diff -X nodiff.pats -wrdC 3 apache+graham_http1.1/src/modules/proxy/proxy_cache.c apache+http1.1_cache/src/modules/proxy/proxy_cache.c
*** apache+graham_http1.1/src/modules/proxy/proxy_cache.c	Sat Mar  3 15:21:58 2001
--- apache+http1.1_cache/src/modules/proxy/proxy_cache.c	Sat Mar  3 16:40:27 2001
***************
*** 62,67 ****
--- 62,68 ----
  #include "http_conf_globals.h"
  #include "http_log.h"
  #include "http_main.h"
+ #include "http_core.h"
  #include "util_date.h"
  #ifdef WIN32
  #include <sys/utime.h>
***************
*** 726,742 ****
   */
  int ap_proxy_cache_conditional(request_rec *r, cache_req *c, BUFF *cachefp)
  {
-     const long int zero = 0L;
      const char *etag, *wetag;
  
      /* 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 If-Match and If-Unmodified-Since exist
--- 727,740 ----
   */
  int ap_proxy_cache_conditional(request_rec *r, cache_req *c, BUFF *cachefp)
  {
      const char *etag, *wetag;
  
      /* 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 If-Match and If-Unmodified-Since exist
***************
*** 791,797 ****
  
  	/* if cache file is being updated */
  	if (c->origfp) {
! 	    ap_proxy_send_headers(NULL, c, c->resp_line, c->xcache, c->hdrs);
  	    ap_proxy_send_fb(c->origfp, r, c, c->len, 1);
  	    ap_pclosef(r->pool, ap_bfileno(c->origfp, B_WR));
  	    ap_proxy_cache_tidy(c);
--- 789,795 ----
  
          /* 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);
              ap_pclosef(r->pool, ap_bfileno(c->origfp, B_WR));
              ap_proxy_cache_tidy(c);
***************
*** 804,812 ****
      }
  
  
!     /* check for If-None-Match, If-Modified-Since
!      *
!      */
      while (1) {
  
  	/* check for existance of If-None-Match and If-Modified-Since
--- 802,808 ----
      }
  
  
!     /* check for If-None-Match, If-Modified-Since */
      while (1) {
  
          /* check for existance of If-None-Match and If-Modified-Since
***************
*** 864,870 ****
  
  	/* are we updating the cache file? */
  	if (c->origfp) {
! 	    ap_proxy_send_headers(NULL, c, c->resp_line, c->xcache, c->hdrs);
  	    ap_proxy_send_fb(c->origfp, r, c, c->len, 1);
  	    ap_pclosef(r->pool, ap_bfileno(c->origfp, B_WR));
  	    ap_proxy_cache_tidy(c);
--- 860,866 ----
  
          /* 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);
              ap_pclosef(r->pool, ap_bfileno(c->origfp, B_WR));
              ap_proxy_cache_tidy(c);
***************
*** 881,897 ****
      Explain0("Local copy modified, send it");
      r->status_line = strchr(c->resp_line, ' ') + 1;
      r->status = c->status;
!     if (!r->assbackwards) {
! 	ap_soft_timeout("proxy send headers", r);
! 	ap_proxy_send_headers(r, NULL, c->resp_line, c->xcache, c->hdrs);
! 	ap_kill_timeout(r);
!     }
!     ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
!     r->sent_bodyct = 1;
  
      /* are we rewriting the cache file? */
      if (c->origfp) {
! 	ap_proxy_send_headers(NULL, c, c->resp_line, NULL, c->hdrs);
  	ap_proxy_send_fb(c->origfp, r, c, c->len, r->header_only);
  	ap_pclosef(r->pool, ap_bfileno(c->origfp, B_WR));
  	ap_proxy_cache_tidy(c);
--- 877,892 ----
      Explain0("Local copy modified, send it");
      r->status_line = strchr(c->resp_line, ' ') + 1;
      r->status = c->status;
! 
!     /* Prepare and send headers to client */
!     ap_overlap_tables(r->headers_out, c->hdrs, AP_OVERLAP_TABLES_SET);
!     ap_table_setn(r->headers_out, "X-Cache", c->xcache);
!     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);
          ap_pclosef(r->pool, ap_bfileno(c->origfp, B_WR));
          ap_proxy_cache_tidy(c);
***************
*** 924,938 ****
  int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
  		      cache_req **cr)
  {
!     char hashfile[66];
!     const char *datestr, *pragma_req = NULL, *pragma_cresp = NULL;
!     const char *etag = NULL, *wetag = NULL, *cc_req = NULL, *cc_cresp = NULL;
!     const char *vary = NULL, *ifmatch = NULL, *ifnonematch = NULL;
!     const char *imstr, *pragma, *auth;
      cache_req *c;
      time_t now;
      BUFF *cachefp;
!     int cfd, i;
      void *sconf = r->server->module_config;
      proxy_server_conf *pconf =
      (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
--- 919,929 ----
  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);
***************
*** 954,966 ****
      c->req_hdrs = NULL;   
      c->hdrs = NULL;
      c->xcache = NULL;
      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);
- /* get the If-Modified-Since date of the request */
-       c->ims = ap_parseHTTPdate(imstr);
        if (c->ims == BAD_DATE)	/* bad or out of range date; remove it */
           ap_table_unset(r->headers_in, "If-Modified-Since");
      }
--- 945,958 ----
      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");
      }
***************
*** 983,990 ****
      c->inm = ap_table_get(r->headers_in, "If-None-Match");
  
  /* find the filename for this cache entry */
-     ap_proxy_hash(url, hashfile, pconf->cache.dirlevels, pconf->cache.dirlength);
      if (conf->root != NULL) {
        c->filename = ap_pstrcat(r->pool, conf->root, "/", hashfile, NULL);
      }
      else {
--- 975,983 ----
      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 {
***************
*** 1024,1037 ****
  
  /* if the cache file exists, open it */
      cachefp = NULL;
  /* find out about whether the request can access the cache */
-     Explain5("Request for %s, pragma_req=%s, auth=%s, ims=%ld, imstr=%s", url,
-            pragma_req, auth, c->ims, imstr); 
      if (c->filename != NULL && r->method_number == M_GET &&
          strlen(url) < 1024 ) {
        cachefp = ap_proxy_open_cachefile(r, c->filename); 
      }
  
      if (cachefp != NULL) {
  	i = rdcache(r, cachefp, c);
  	if (i == -1)
--- 1017,1032 ----
  
      /* if the cache file exists, open it */
      cachefp = NULL;
+     Explain3("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 a cache file exists, try reading body and headers from cache file */
      if (cachefp != NULL) {
  	i = rdcache(r, cachefp, c);
  	if (i == -1)
***************
*** 1049,1055 ****
  	    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);
  	    }
  	}
--- 1044,1050 ----
  	    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);
  	    }
      }
***************
*** 1064,1071 ****
  */
      /* 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
--- 1059,1064 ----
***************
*** 1080,1087 ****
       */
      if (c->hdrs && c->req_hdrs) {
  	char *vary = ap_pstrdup(r->pool, ap_table_get(c->hdrs, "Vary"));
- 	char *p;
- 	int i;
  
  	while (vary && *vary) {
  	    char *name = vary;
--- 1073,1078 ----
***************
*** 1111,1117 ****
  		c->fp = cachefp;
  		Explain0("Vary header mismatch - object must be fetched from scratch. Declining.");
  		return DECLINED;
- 
  	    }
  	}
      }
--- 1102,1107 ----
***************
*** 1305,1322 ****
  #endif 
      request_rec *r = c->req;
      char *p;
-     int i;
      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 long int zero = 0L;
      const char *cc_resp;
-     off_t orig_clen;
-     /* buffer to store response headers */
-     char *hdr_buff[HUGE_STRING_LEN];
      table *req_hdrs;
  
      cc_resp = ap_table_get(resp_hdrs, "Cache-Control");
--- 1295,1307 ----
***************
*** 1411,1419 ****
      }
  
  
- 
- 
- 
      /* It's safe to cache the response.
       *
       * We now want to update the cache file header information with
--- 1396,1401 ----
***************
*** 1495,1502 ****
      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] = ' ';
--- 1477,1483 ----
      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] = ' ';
***************
*** 1565,1572 ****
      }
  
      while (1) {
-       struct tbl_do_args tdo;
- 
  /* create temporary filename */
  #ifndef TPF
  #define TMPFILESTR    "/tmpXXXXXX"
--- 1546,1551 ----
***************
*** 1622,1633 ****
        ap_proxy_clear_connection(r->pool, req_hdrs);
  
  /* save original request headers */
-       tdo.req = NULL;
-       tdo.cache = c;
        if (c->req_hdrs)
!           ap_table_do(ap_proxy_send_hdr_line, &tdo, c->req_hdrs, NULL);
        else
!           ap_table_do(ap_proxy_send_hdr_line, &tdo, 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);
--- 1601,1610 ----
  	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);
diff -X nodiff.pats -wrdC 3 apache+graham_http1.1/src/modules/proxy/proxy_ftp.c apache+http1.1_cache/src/modules/proxy/proxy_ftp.c
*** apache+graham_http1.1/src/modules/proxy/proxy_ftp.c	Sat Mar  3 15:21:58 2001
--- apache+http1.1_cache/src/modules/proxy/proxy_ftp.c	Mon Feb 12 17:20:50 2001
***************
*** 461,469 ****
      BUFF *data = NULL;
      pool *p = r->pool;
      int one = 1;
-     const long int zero = 0L;
      NET_SIZE_T clen;
-     struct tbl_do_args tdo;
  
      void *sconf = r->server->module_config;
      proxy_server_conf *conf =
--- 461,467 ----
***************
*** 1208,1244 ****
  	ap_bpushfd(data, dsock, dsock);
      }
  
-     ap_hard_timeout("proxy receive", r);
- 
      /* send response */
!     /* write status line */
!     if (!r->assbackwards)
! 	ap_rvputs(r, "HTTP/1.1 ", r->status_line, CRLF, NULL);
!     if (c != NULL && c->fp != NULL
! 	&& ap_bvputs(c->fp, "HTTP/1.1 ", r->status_line, CRLF, NULL) == -1) {
! 	    ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
! 		"proxy: error writing CRLF to %s", c->tempfile);
! 	    c = ap_proxy_cache_error(c);
!     }
! 
!     /* we don't yet support keepalives */
!     ap_rputs("Connection: close" CRLF, r);
  
!     /* send headers */
!     tdo.req = r;
!     tdo.cache = c;
!     ap_table_do(ap_proxy_send_hdr_line, &tdo, resp_hdrs, NULL);
  
!     if (!r->assbackwards)
! 	ap_rputs(CRLF, r);
!     if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1)
{
! 	ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
! 	    "proxy: error writing CRLF to %s", c->tempfile);
! 	c = ap_proxy_cache_error(c);
!     }
  
-     ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
-     r->sent_bodyct = 1;
  /* send body */
      if (!r->header_only) {
  	if (parms[0] != 'd') {
--- 1206,1228 ----
  	ap_bpushfd(data, dsock, dsock);
      }
  
  /* send response */
!     /* write status line and headers to the cache file */
!     ap_proxy_write_headers(c, ap_pstrcat(p, "HTTP/1.1 ", r->status_line, NULL), resp_hdrs);
  
!     /* Setup the headers for our client from upstreams response-headers */
!     ap_overlap_tables(r->headers_out, resp_hdrs, AP_OVERLAP_TABLES_SET);
!     /* Add X-Cache header */
!     ap_table_setn(r->headers_out, "X-Cache",
!                   ap_pstrcat(r->pool, "MISS from ",
!                              ap_get_server_name(r), NULL));
!     /* The Content-Type of this response is the upstream one. */
!     r->content_type = ap_table_get (r->headers_out, "Content-Type");
!     /* finally output the headers to the client */
!     ap_send_http_header(r);
  
!     ap_hard_timeout("proxy receive", r);
  
  /* send body */
      if (!r->header_only) {
  	if (parms[0] != 'd') {
diff -X nodiff.pats -wrdC 3 apache+graham_http1.1/src/modules/proxy/proxy_http.c apache+http1.1_cache/src/modules/proxy/proxy_http.c
*** apache+graham_http1.1/src/modules/proxy/proxy_http.c	Sat Mar  3 15:21:58 2001
--- apache+http1.1_cache/src/modules/proxy/proxy_http.c	Sun Mar  4 10:52:59 2001
***************
*** 152,160 ****
      char *strp2;
      const char *err, *desthost;
      int i, j, sock, len, backasswards;
      array_header *reqhdrs_arr;
!     table *resp_hdrs;
!     table_entry *reqhdrs;
      struct sockaddr_in server;
      struct in_addr destaddr;
      struct hostent server_hp;
--- 152,160 ----
      char *strp2;
      const char *err, *desthost;
      int i, j, sock, len, backasswards;
+     table *req_hdrs, *resp_hdrs;
      array_header *reqhdrs_arr;
!     table_entry *reqhdrs_elts;
      struct sockaddr_in server;
      struct in_addr destaddr;
      struct hostent server_hp;
***************
*** 162,173 ****
      char buffer[HUGE_STRING_LEN];
      char portstr[32];
      pool *p = r->pool;
-     const long int zero = 0L;
      int destport = 0;
      char *destportstr = NULL;
      const char *urlptr = NULL;
      const char *datestr, *urlstr;
-     struct tbl_do_args tdo;
  
      void *sconf = r->server->module_config;
      proxy_server_conf *conf =
--- 162,171 ----
***************
*** 175,181 ****
      struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
      struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts;
      int nocache = 0;
!     char *xcache = NULL;
  
      memset(&server, '\0', sizeof(server));
      server.sin_family = AF_INET;
--- 173,180 ----
      struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
      struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts;
      int nocache = 0;
! 
!     if (conf->cache.root == NULL) nocache = 1;
  
      memset(&server, '\0', sizeof(server));
      server.sin_family = AF_INET;
***************
*** 288,296 ****
      /* record request_time for HTTP/1.1 age calculation */
      c->req_time = time(NULL);
  
!     /* strip hop-by-hop headers from the request */
!     ap_proxy_clear_connection(r->pool, r->headers_in);
! 
  
      /* At this point, we start sending the HTTP/1.1 request to the
       * remote server (proxy or otherwise).
--- 287,299 ----
      /* record request_time for HTTP/1.1 age calculation */
      c->req_time = time(NULL);
  
!     /* build upstream-request headers by stripping r->headers_in from
!      * connection specific headers.
!      * We must not remove the Connection: header from r->headers_in,
!      * we still have to react to Connection: close
!      */
!     req_hdrs = ap_copy_table(r->pool, r->headers_in);
!     ap_proxy_clear_connection(r->pool, req_hdrs);
  
      /* At this point, we start sending the HTTP/1.1 request to the
       * remote server (proxy or otherwise).
***************
*** 301,306 ****
--- 304,310 ----
      ap_hard_timeout("proxy send", r);
      ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF,
  	   NULL);
+     /* Send Host: now, adding it to req_hdrs wouldn't be much better */
      if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
  	ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
      else
***************
*** 308,314 ****
  
      if (conf->viaopt == via_block) {
  	/* Block all outgoing Via: headers */
! 	ap_table_unset(r->headers_in, "Via");
      } else if (conf->viaopt != via_off) {
  	/* Create a "Via:" request header entry and merge it */
  	i = ap_get_server_port(r);
--- 312,318 ----
  
      if (conf->viaopt == via_block) {
  	/* Block all outgoing Via: headers */
!         ap_table_unset(req_hdrs, "Via");
      } else if (conf->viaopt != via_off) {
  	/* Create a "Via:" request header entry and merge it */
  	i = ap_get_server_port(r);
***************
*** 318,324 ****
  	    ap_snprintf(portstr, sizeof portstr, ":%d", i);
  	}
  	/* Generate outgoing Via: header with/without server comment: */
! 	ap_table_mergen(r->headers_in, "Via",
  		    (conf->viaopt == via_full)
  			? ap_psprintf(p, "%d.%d %s%s (%s)",
  				HTTP_VERSION_MAJOR(r->proto_num),
--- 322,328 ----
  	    ap_snprintf(portstr, sizeof portstr, ":%d", i);
  	}
  	/* Generate outgoing Via: header with/without server comment: */
! 	ap_table_mergen(req_hdrs, "Via",
  		    (conf->viaopt == via_full)
  			? ap_psprintf(p, "%d.%d %s%s (%s)",
  				HTTP_VERSION_MAJOR(r->proto_num),
***************
*** 332,354 ****
  			);
      }
  
      /* we don't yet support keepalives - but we will soon, I promise! */
!     ap_bvputs(f, "Connection: close", CRLF, NULL);
  
!     reqhdrs_arr = ap_table_elts(r->headers_in);
!     reqhdrs = (table_entry *) reqhdrs_arr->elts;
      for (i = 0; i < reqhdrs_arr->nelts; i++) {
! 	if (reqhdrs[i].key == NULL || reqhdrs[i].val == NULL
  
  	/* Clear out hop-by-hop request headers not to send:
  	 * RFC2616 13.5.1 says we should strip these headers:
  	 */
! 	    || !strcasecmp(reqhdrs[i].key, "Host")	/* Already sent */
! 	    || !strcasecmp(reqhdrs[i].key, "Keep-Alive")
! 	    || !strcasecmp(reqhdrs[i].key, "TE")
! 	    || !strcasecmp(reqhdrs[i].key, "Trailer")
! 	    || !strcasecmp(reqhdrs[i].key, "Transfer-Encoding")
! 	    || !strcasecmp(reqhdrs[i].key, "Upgrade")
  
  	    /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be 
  	     * suppressed if THIS server requested the authentication,
--- 336,362 ----
  			);
      }
  
+     /* Add X-Forwarded-For: so that the upstream has a chance to
+        determine, where the original request came from. */
+     ap_table_mergen(req_hdrs, "X-Forwarded-For", r->connection->remote_ip);
+     
      /* we don't yet support keepalives - but we will soon, I promise! */
!     ap_table_set(req_hdrs, "Connection", "close");
  
!     reqhdrs_arr = ap_table_elts(req_hdrs);
!     reqhdrs_elts = (table_entry *) reqhdrs_arr->elts;
      for (i = 0; i < reqhdrs_arr->nelts; i++) {
!         if (reqhdrs_elts[i].key == NULL || reqhdrs_elts[i].val == NULL
  
          /* Clear out hop-by-hop request headers not to send:
           * RFC2616 13.5.1 says we should strip these headers:
           */
!             || !strcasecmp(reqhdrs_elts[i].key, "Host") /* Already sent */
!             || !strcasecmp(reqhdrs_elts[i].key, "Keep-Alive")
!             || !strcasecmp(reqhdrs_elts[i].key, "TE")
!             || !strcasecmp(reqhdrs_elts[i].key, "Trailer")
!             || !strcasecmp(reqhdrs_elts[i].key, "Transfer-Encoding")
!             || !strcasecmp(reqhdrs_elts[i].key, "Upgrade")
  
  	    /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be 
  	     * suppressed if THIS server requested the authentication,
***************
*** 359,367 ****
  	     * code itself, not here. This saves us having to signal
  	     * somehow whether this request was authenticated or not.
  	     */
! 	    || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization"))
  	    continue;
! 	ap_bvputs(f, reqhdrs[i].key, ": ", reqhdrs[i].val, CRLF, NULL);
      }
  
      /* the obligatory empty line to mark the end of the headers */
--- 367,375 ----
  	     * code itself, not here. This saves us having to signal
  	     * somehow whether this request was authenticated or not.
  	     */
! 	    || !strcasecmp(reqhdrs_elts[i].key, "Proxy-Authorization"))
  	    continue;
! 	ap_bvputs(f, reqhdrs_elts[i].key, ": ", reqhdrs_elts[i].val, CRLF, NULL);
      }
  
      /* the obligatory empty line to mark the end of the headers */
***************
*** 377,383 ****
  
  
      /* Right - now it's time to listen for a response.
-      *
       */
      ap_hard_timeout("proxy receive", r);
  
--- 385,390 ----
***************
*** 502,539 ****
  	       break;
  	    }
  	}
-     }
  
      /* update the cache file, possibly even fulfilling the request if
       * it turns out a conditional allowed us to serve the object from the
       * cache...
       */
- 
      i = ap_proxy_cache_update(c, resp_hdrs, !backasswards, nocache);
      if (i != DECLINED) {
  	ap_bclose(f);
  	return i;
      }
  
!     ap_hard_timeout("proxy receive", r);
  
!     /* write status line and headers */
!     xcache = ap_pstrcat(r->pool, "MISS from ", ap_get_server_name(r), NULL);
!     ap_proxy_send_headers(r, c, ap_pstrcat(p, "HTTP/1.1 ", r->status_line, NULL), xcache,
resp_hdrs);
  
!     ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
!     r->sent_bodyct = 1;
!     /* Is it an HTTP/0.9 respose? If so, send the extra data */
      if (backasswards) {
  	ap_bwrite(r->connection->client, buffer, len);
  	if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) !=
len) {
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
  		"proxy: error writing extra data to %s", c->tempfile);
  	    c = ap_proxy_cache_error(c);
  	}
      }
  
-     ap_kill_timeout(r);
  
  #ifdef CHARSET_EBCDIC
      /* What we read/write after the header should not be modified
--- 509,555 ----
  	       break;
  	    }
  	}
  
  	/* update the cache file, possibly even fulfilling the request if
  	 * it turns out a conditional allowed us to serve the object from the
  	 * cache...
  	 */
  	i = ap_proxy_cache_update(c, resp_hdrs, !backasswards, nocache);
  	if (i != DECLINED) {
  	  ap_bclose(f);
  	  return i;
  	}
  	
! 	/* write status line and headers to the cache file */
! 	ap_proxy_write_headers(c, ap_pstrcat(p, "HTTP/1.1 ", r->status_line, NULL), resp_hdrs);
!     }
  
!     /* Setup the headers for our client from upstreams response-headers */
!     ap_overlap_tables(r->headers_out, resp_hdrs, AP_OVERLAP_TABLES_SET);
!     /* Add X-Cache header */
!     ap_table_setn(r->headers_out, "X-Cache",
!                   ap_pstrcat(r->pool, "MISS from ",
!                              ap_get_server_name(r), NULL));
!     /* The Content-Type of this response is the upstream one. */
!     r->content_type = ap_table_get (r->headers_out, "Content-Type");
!     Explain1("Content-Type: %s", r->content_type);
!     /* finally output the headers to the client */
!     ap_send_http_header(r);
  
!     /* Is it an HTTP/0.9 respose? If so, send the extra data we read
!        from upstream as the start of the reponse to client */
      if (backasswards) {
+         ap_hard_timeout("proxy send assbackward", r);
+ 
  	ap_bwrite(r->connection->client, buffer, len);
  	if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) !=
len) {
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
  		"proxy: error writing extra data to %s", c->tempfile);
  	    c = ap_proxy_cache_error(c);
  	}
+         ap_kill_timeout(r);
      }
  
  
  #ifdef CHARSET_EBCDIC
      /* What we read/write after the header should not be modified
diff -X nodiff.pats -wrdC 3 apache+graham_http1.1/src/modules/proxy/proxy_util.c apache+http1.1_cache/src/modules/proxy/proxy_util.c
*** apache+graham_http1.1/src/modules/proxy/proxy_util.c	Sat Mar  3 15:21:58 2001
--- apache+http1.1_cache/src/modules/proxy/proxy_util.c	Sun Feb 18 13:30:37 2001
***************
*** 571,580 ****
  	    }
  	    break;
  	}
- 	total_bytes_rcvd += n;
  	if (n == 0)
  	    break;		/* EOF */
  	o = 0;
  
  	/* Write to cache first. */
  	/*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */
--- 571,580 ----
  	    }
  	    break;
  	}
  	if (n == 0)
  	    break;		/* EOF */
  	o = 0;
+ 	total_bytes_rcvd += n;
  
  	/* Write to cache first. */
  	/*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */
***************
*** 638,687 ****
  }
  
  /*
!  * Sends response line and headers.  Uses the client fd and the 
!  * headers_out array from the passed request_rec to talk to the client
!  * and to properly set the headers it sends for things such as logging.
!  * 
!  * If respline is NULL, no response line will be sent.
!  * If c is NULL, headers won't be written to cache.
!  * If r is NULL, headers won't be written to client.
   *
!  * A timeout should be set before calling this routine.
   */
! void ap_proxy_send_headers(request_rec *r, cache_req *c, const char *respline, const char
*xcache, table *t)
  {
-     struct tbl_do_args tdo;
- 
      /* write status line */
!     if (respline) {
! 	if (r && !r->assbackwards)
! 	    ap_rvputs(r, respline, CRLF, NULL);
! 	if (c && c->fp && ap_bvputs(c->fp, respline, CRLF, NULL) == -1) {
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
  			  "proxy: error writing status line to %s", c->tempfile);
  	    c = ap_proxy_cache_error(c);
  	}
-     }
- 
-     /* send response headers to client */
-     tdo.req = r;
-     tdo.cache = c;
-     ap_table_do(ap_proxy_send_hdr_line, &tdo, t, NULL);
  
!     /* send X-Cache to client */
!     if (r && xcache) {
! 	ap_rvputs(r, "X-Cache: ", xcache, CRLF, NULL);
!     }
  
!     /* send terminating CRLF */
!     if (r && !r->assbackwards)
! 	ap_rputs(CRLF, r);
!     if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1)
{
  	ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
  		      "proxy: error writing CRLF to %s", c->tempfile);
  	c = ap_proxy_cache_error(c);
      }
- 
  }
  
  
--- 638,667 ----
  }
  
  /*
!  * Writes response line and headers to the cache file.
   * 
!  * If respline is NULL, no response line will be written.
   */
! void ap_proxy_write_headers(cache_req *c, const char *respline, table *t)
  {
      /* write status line */
!     if (respline && c->fp != NULL &&
!         ap_bvputs(c->fp, respline, CRLF, NULL) == -1) {
              ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
                            "proxy: error writing status line to %s", c->tempfile);
              c = ap_proxy_cache_error(c);
+         return;
      }
  
!     /* write response headers to the cache file */
!     ap_table_do(ap_proxy_send_hdr_line, c, t, NULL);
  
!     /* write terminating CRLF */
!     if (c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
                        "proxy: error writing CRLF to %s", c->tempfile);
          c = ap_proxy_cache_error(c);
      }
  }
  
  
***************
*** 1326,1349 ****
  
  /* This function is called by ap_table_do() for all header lines
   * (from proxy_http.c and proxy_ftp.c)
!  * It is passed a table_do_args struct pointer and a MIME field and value pair
!  * This function does not cache certain headers defined by RFC2616 */
  int ap_proxy_send_hdr_line(void *p, const char *key, const char *value)
  {
!     struct tbl_do_args *parm = (struct tbl_do_args *)p;
  
      if (key == NULL || value == NULL || value[0] == '\0')
  	return 1;
!     if (parm->req && !parm->req->assbackwards) {
! 	ap_rvputs(parm->req, key, ": ", value, CRLF, NULL);
! /* CHECKME: Do we need to create the headers_out table first? */
! 	ap_table_addn(parm->req->headers_out, key, value);
!     }
!     if (parm->cache != NULL && parm->cache->fp != NULL &&
! 	ap_bvputs(parm->cache->fp, key, ": ", value, CRLF, NULL) == -1) {
! 	    ap_log_rerror(APLOG_MARK, APLOG_ERR, parm->cache->req,
! 		    "proxy: error writing header to %s", parm->cache->tempfile);
! 	    parm->cache = ap_proxy_cache_error(parm->cache);
      }
      return 1; /* tell ap_table_do() to continue calling us for more headers */
  }
--- 1306,1325 ----
  
  /* This function is called by ap_table_do() for all header lines
   * (from proxy_http.c and proxy_ftp.c)
!  * It is passed a cache_req struct pointer and a MIME field and value pair
!  */
  int ap_proxy_send_hdr_line(void *p, const char *key, const char *value)
  {
!     cache_req *c = (cache_req *)p;
  
      if (key == NULL || value == NULL || value[0] == '\0')
  	return 1;
!     if (c->fp != NULL &&
!         ap_bvputs(c->fp, key, ": ", value, CRLF, NULL) == -1) {
!             ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
!                     "proxy: error writing header to %s", c->tempfile);
!             c = ap_proxy_cache_error(c);
!             return 0; /* no need to continue, it failed already */
      }
      return 1; /* tell ap_table_do() to continue calling us for more headers */
  }
***************
*** 1421,1427 ****
      return cachefp;
  }
  
! /* Clear all connection-based headers from the incoming headers table */
  void ap_proxy_clear_connection(pool *p, table *headers)
  {
      const char *name;
--- 1397,1403 ----
      return cachefp;
  }
  
! /* Clear all connection-based headers from headers table */
  void ap_proxy_clear_connection(pool *p, table *headers)
  {
      const char *name;

Mime
View raw message