-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
In need of some cleanup, but, in service.
Adrian Chadd wrote:
| On Thu, May 08, 2008, Matt Benjamin wrote:
|> -----BEGIN PGP SIGNED MESSAGE-----
|> Hash: SHA256
|>
|> It was...
|
| .. where?
|
|
|
|
| Adrian
|
- --
Matt Benjamin
The Linux Box
206 South Fifth Ave. Suite 150
Ann Arbor, MI 48104
http://linuxbox.com
tel. 734-761-4689
fax. 734-769-8938
cel. 734-216-5309
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFII8K1JiSUUSaRdSURCB7FAJ4xwU1df+y8FwHcBdbq4W4BR6WjNQCfR1AN
Qj6YUhcFZQ7nglMVr1S9wqw=
=9Aq0
-----END PGP SIGNATURE-----
diff --git a/src/cf.data.pre b/src/cf.data.pre
index e9c0709..96efeec 100644
--- a/src/cf.data.pre
+++ b/src/cf.data.pre
@@ -2463,6 +2463,16 @@ DOC_START
be allowed to request.
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
+
COMMENT_START
OPTIONS FOR TUNING THE CACHE
-----------------------------------------------------------------------------
diff --git a/src/http.cc b/src/http.cc
index 4191377..82bc99e 100644
--- a/src/http.cc
+++ b/src/http.cc
@@ -1418,6 +1418,14 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request,
}
}
+ /* linuxbox magic variation on login=*:password */
+ if (hdr_out->has(HDR_AUTHORIZATION)) {
+ debug(11,3) ("Linuxbox: proxying auth to proxy-auth\n");
+ const char *auth = hdr_in->getStr(HDR_AUTHORIZATION);
+ if (auth && strncasecmp(auth, "basic ", 6) == 0) {
+ hdr_out->putStr(HDR_PROXY_AUTHORIZATION, auth);
+ }
+ } else
/* append WWW-Authorization if configured for peer */
if (flags.originpeer && orig_request->peer_login &&
!hdr_out->has(HDR_AUTHORIZATION)) {
diff --git a/src/redirect.cc b/src/redirect.cc
index f9142a3..128789a 100644
--- a/src/redirect.cc
+++ b/src/redirect.cc
@@ -44,6 +44,40 @@
#include "client_side.h"
#include "helper.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;
+
+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("RDRSEP", lpos)) != std::string::npos) {
+ std::string k, v;
+ k = s.substr(lpos, rpos);
+ v = s.substr(rpos+6, s.length()-6);
+ 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;
@@ -52,6 +86,7 @@ typedef struct
struct IN_ADDR client_addr;
const char *client_ident;
const char *method_s;
+ HttpRequest* client_request; // linuxbox
RH *handler;
}
@@ -72,7 +107,50 @@ redirectHandleReply(void *data, char *reply)
void *cbdata;
debugs(61, 5, "redirectHandleRead: {" << (reply && *reply != '\0' ? 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;
+ int headers_deleted;
+ while ((e = hdr->getEntry(&pos))) {
+ hdr->delAt(pos, headers_deleted);
+ }
+
+ // 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) {
+ 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 = new HttpHeaderEntry(hdr_id,
+ hname.c_str(),
+ hvalue.c_str());
+ hdr->addEntry(hhe);
+ }
+ }
+ }
+
if ((t = strchr(reply, ' ')))
*t = '\0';
@@ -116,7 +194,9 @@ 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 = "";
char claddr[20];
char myaddr[20];
assert(http);
@@ -162,10 +242,38 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL)
fqdn = dash_str;
+ 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 = hdr->getEntry(&pos))) {
+ hdr_temp.append(e->name);
+ hdr_temp.append("RDRSEP");
+ hdr_temp.append(e->value);
+ hdr_temp.append("\n");
+ }
+ hdr_block = base64_encode(hdr_temp.buf());
+ buf_sz += hdr_block.size() + 1;
+
+ }
xstrncpy(claddr, inet_ntoa(r->client_addr), 20);
xstrncpy(myaddr, inet_ntoa(http->request->my_addr), 20);
- snprintf(buf, 8192, "%s %s/%s %s %s myip=%s myport=%d\n",
+
+ buf = (char*) xmalloc (buf_sz * sizeof(char));
+ memset(buf, 0, buf_sz);
+
+ if(Config.redirectHeaders) {
+
+#if 0 /* new format */
+ snprintf(buf, buf_sz, "%s %s/%s %s %s myip=%s myport=%d\n",
r->orig_url,
claddr,
fqdn,
@@ -173,8 +281,26 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
r->method_s,
myaddr,
http->request->my_port);
+#else
+ 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());
+#endif
+ } 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 --git a/src/structs.h b/src/structs.h
index 67749d9..a5e308b 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -393,6 +393,7 @@ struct _SquidConfig
int redirectChildren;
int redirectConcurrency;
+ int redirectHeaders;
time_t authenticateGCInterval;
time_t authenticateTTL;
time_t authenticateIpTTL;