Dear Squid Folk,

I've implemented a mechamism to arbitrarily add/change/delete headers, using an extension to the existing redirect_program helper application.

Attach please find a unified diff made against the 20040805 Squid-3.0 snapshot--it should patch more recent ones, of course. Also, please find a simple example of a redirect program which uses the mechanism to add a custom header, which shows the basic idea.

Matt

PS. Sent this also to squid-dev, but in case it never makes it through moderation, I figured I'd send it here.

--

Matt Benjamin

The Linux Box
206 South Fifth Ave. Suite 150
Ann Arbor, MI  48104

tel. 734-761-4689
fax. 734-769-8938
cel. 734-216-5309

diff -ru squid-3.0-PRE3-20040805/src/cf.data.pre squid-3.0-PRE3-20040805-redir/src/cf.data.pre
--- squid-3.0-PRE3-20040805/src/cf.data.pre	2004-08-04 12:22:39.000000000 -0400
+++ squid-3.0-PRE3-20040805-redir/src/cf.data.pre	2004-08-27 15:52:04.000000000 -0400
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.353 2004/08/04 16:22:39 wessels Exp $
+# $Id: cf.data.pre,v 1.1 2004/08/27 16:47:25 matt Exp $
 #
 #
 # SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -1633,6 +1633,16 @@
 	is a old-style singlethreaded redirector.
 DOC_END
 
+NAME: redirect_headers
+TYPE: int
+DEFAULT: 0
+LOC: Config.redirectHeaders
+DOC_START
+	Set to a positive value to enable processing of headers by 
+	redirector programs.  Note, if non-zero, redirector programs
+	MUST handle header re-writing.
+DOC_END
+
 NAME: redirect_rewrites_host_header
 TYPE: onoff
 DEFAULT: on
Only in squid-3.0-PRE3-20040805-redir/src: cf_parser.h
diff -ru squid-3.0-PRE3-20040805/src/HttpHeader.cc squid-3.0-PRE3-20040805-redir/src/HttpHeader.cc
--- squid-3.0-PRE3-20040805/src/HttpHeader.cc	2003-09-29 06:24:00.000000000 -0400
+++ squid-3.0-PRE3-20040805-redir/src/HttpHeader.cc	2004-08-27 15:52:04.000000000 -0400
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpHeader.cc,v 1.95 2003/09/29 10:24:00 robertc Exp $
+ * $Id: HttpHeader.cc,v 1.1 2004/08/26 22:06:16 matt Exp $
  *
  * DEBUG: section 55    HTTP Header
  * AUTHOR: Alex Rousskov
@@ -250,7 +250,7 @@
 
 #define assert_eid(id) assert((id) >= 0 && (id) < HDR_ENUM_END)
 
-static HttpHeaderEntry *httpHeaderEntryCreate(http_hdr_type id, const char *name, const char *value);
+HttpHeaderEntry *httpHeaderEntryCreate(http_hdr_type id, const char *name, const char *value);
 static void httpHeaderEntryDestroy(HttpHeaderEntry * e);
 static HttpHeaderEntry *httpHeaderEntryParseCreate(const char *field_start, const char *field_end);
 static void httpHeaderNoteParsedEntry(http_hdr_type id, String value, int error);
@@ -1193,7 +1193,7 @@
  * HttpHeaderEntry
  */
 
-static HttpHeaderEntry *
+HttpHeaderEntry *
 httpHeaderEntryCreate(http_hdr_type id, const char *name, const char *value)
 {
     HttpHeaderEntry *e;
diff -ru squid-3.0-PRE3-20040805/src/redirect.cc squid-3.0-PRE3-20040805-redir/src/redirect.cc
--- squid-3.0-PRE3-20040805/src/redirect.cc	2004-04-07 04:51:31.000000000 -0400
+++ squid-3.0-PRE3-20040805-redir/src/redirect.cc	2004-08-27 15:52:04.000000000 -0400
@@ -1,6 +1,6 @@
 
 /*
- * $Id: redirect.cc,v 1.105 2004/04/07 08:51:31 hno Exp $
+ * $Id: redirect.cc,v 1.1 2004/08/27 16:47:25 matt Exp $
  *
  * DEBUG: section 61    Redirector
  * AUTHOR: Duane Wessels
@@ -41,6 +41,43 @@
 #include "HttpRequest.h"
 #include "client_side.h"
 
+// STL
+#include <memory>
+#include <list>
+#include <string>
+typedef std::list<std::string> StringList;
+typedef std::pair<std::string,std::string> StringPair;
+typedef std::list<StringPair> StringPairList;
+
+// From HttpHeader.cc
+HttpHeaderEntry *httpHeaderEntryCreate(http_hdr_type id, const char *name, const char *value);
+
+StringPair parse_header_line(const std::string& s) {
+    StringPair sp("NO_SUCH_STRING_PAIR","");
+    std::string::size_type rpos, lpos = 0;
+    if((rpos = s.find(':', lpos)) != std::string::npos) {
+      std::string k, v;
+      k = s.substr(lpos, rpos);
+      v = s.substr(rpos+1, s.length()-1);
+      sp.first = k;
+      sp.second = v;
+    }
+    return sp;
+}
+
+StringPairList parse_header_block(const String& s) {
+    StringPairList spl;
+    std::string hdrs = s.buf();
+    std::string::size_type rpos, lpos = 0;
+
+    while((rpos = hdrs.find('\n', lpos)) != std::string::npos) {
+        std::string line = hdrs.substr(lpos, rpos-lpos);
+	spl.push_back(parse_header_line(line));
+	lpos = rpos + 1;
+    }
+    return spl;
+}
+
 typedef struct
 {
     void *data;
@@ -49,6 +86,7 @@
     struct in_addr client_addr;
     const char *client_ident;
     const char *method_s;
+    HttpRequest* client_request; // linuxbox
     RH *handler;
 }
 
@@ -69,7 +107,50 @@
     void *cbdata;
     debug(61, 5) ("redirectHandleRead: {%s}\n", reply ? reply : "<NULL>");
 
+    // todo: maybe allow a coded string that indicates "use headers as given"
+    // to save a few cycles
+
     if (reply) {
+
+	if(Config.redirectHeaders) {
+
+	    // clear all headers
+	    HttpHeaderEntry *e;
+	    HttpHeader* hdr = &r->client_request->header;
+	    HttpHeaderPos pos = HttpHeaderInitPos;
+	    while ((e = httpHeaderGetEntry(hdr, &pos))) {
+		httpHeaderDelAt(hdr, pos);
+	    }
+
+	    // decode redirected headers, and add each one
+	    String hdr_block;
+	    String hdr_temp;
+	    if ((t = strrchr(reply, ' '))) {
+		t++; // *t is now the start of the encoded headers
+		hdr_block = t;
+		hdr_temp = base64_decode(hdr_block.buf());
+		StringPairList hdr_lst = parse_header_block(hdr_temp);
+		StringPairList::iterator spl_iter;
+		for(spl_iter = hdr_lst.begin(); spl_iter != hdr_lst.end();
+		    ++spl_iter) {
+		    //todo:  check if we understand this
+		    std::string& hname = spl_iter->first;
+		    std::string& hvalue = spl_iter->second;
+		    http_hdr_type hdr_id;
+		    hdr_id =  httpHeaderIdByNameDef((char*) hname.c_str(), 
+						    hname.length());
+		    if(hdr_id == -1) {
+			hdr_id = HDR_OTHER;
+		    }
+		    debug(61, 5) ("redirectHeaders: adding header %s\n", hname.c_str());
+		    HttpHeaderEntry* hhe = httpHeaderEntryCreate(hdr_id, 
+								 hname.c_str(),
+								 hvalue.c_str());
+		    httpHeaderAddEntry(hdr, hhe);
+		}
+	    }
+	}
+
         if ((t = strchr(reply, ' ')))
             *t = '\0';
 
@@ -106,10 +187,13 @@
 void
 redirectStart(clientHttpRequest * http, RH * handler, void *data)
 {
+
     ConnStateData::Pointer conn = http->getConn();
     redirectStateData *r = NULL;
     const char *fqdn;
-    char buf[8192];
+    char *buf;
+    int buf_sz;
+    String hdr_block = "";
     assert(http);
     assert(handler);
     debug(61, 5) ("redirectStart: '%s'\n", http->uri);
@@ -167,14 +251,51 @@
     if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL)
         fqdn = dash_str;
 
-    snprintf(buf, 8192, "%s %s/%s %s %s\n",
-             r->orig_url,
-             inet_ntoa(r->client_addr),
-             fqdn,
-             r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
-             r->method_s);
+    buf_sz = 8192;
+    if(Config.redirectHeaders) {
+
+	// stash pointer to request in state struct
+	r->client_request = http->request;
+
+	// format copy of headers as base64 encoded block
+	String hdr_temp = "";
+	HttpHeaderEntry *e;
+	HttpHeader* hdr = &r->client_request->header;
+	HttpHeaderPos pos = HttpHeaderInitPos;
+	while ((e = httpHeaderGetEntry(hdr, &pos))) {
+	    hdr_temp.append(e->name);
+	    hdr_temp.append(":");
+	    hdr_temp.append(e->value);
+	    hdr_temp.append("\n");
+	}
+	hdr_block = base64_encode(hdr_temp.buf());
+	buf_sz += hdr_block.size() + 1;
+	
+    }
+
+    buf = (char*) xmalloc (buf_sz * sizeof(char));
+    memset(buf, 0, buf_sz);
+
+    if(Config.redirectHeaders) {
+	snprintf(buf, buf_sz, "%s %s/%s %s %s %s\n",
+		 r->orig_url,
+		 inet_ntoa(r->client_addr),
+		 fqdn,
+		 r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
+		 r->method_s,
+		 hdr_block.buf());
+
+    } else {
+	snprintf(buf, buf_sz, "%s %s/%s %s %s\n",
+		 r->orig_url,
+		 inet_ntoa(r->client_addr),
+		 fqdn,
+		 r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
+		 r->method_s);
+    }
 
     helperSubmit(redirectors, buf, redirectHandleReply, r);
+    xfree(buf);
 }
 
 void
diff -ru squid-3.0-PRE3-20040805/src/structs.h squid-3.0-PRE3-20040805-redir/src/structs.h
--- squid-3.0-PRE3-20040805/src/structs.h	2004-04-04 19:17:48.000000000 -0400
+++ squid-3.0-PRE3-20040805-redir/src/structs.h	2004-08-27 15:52:04.000000000 -0400
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.487 2004/04/04 23:17:48 hno Exp $
+ * $Id: structs.h,v 1.1 2004/08/27 16:47:25 matt Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -404,6 +404,7 @@
 
     int redirectChildren;
     int redirectConcurrency;
+    int redirectHeaders;
     time_t authenticateGCInterval;
     time_t authenticateTTL;
     time_t authenticateIpTTL;

Attachment: header-redirector.php
Description: application/httpd-php



Reply via email to