This patch is generated from the shaga branch of HEAD in squid3 Fri Feb 1 01:23:05 2008 GMT See http://devel.squid-cache.org/ Index: squid3/configure.in diff -u squid3/configure.in:1.172 squid3/configure.in:1.172.2.2 --- squid3/configure.in:1.172 Fri Jan 18 02:14:07 2008 +++ squid3/configure.in Thu Jan 31 09:57:23 2008 @@ -853,6 +853,19 @@ fi AM_CONDITIONAL(ENABLE_HTCP, [test x$USE_HTCP = xtrue]) +dnl Shaga support is disabled by default +AM_CONDITIONAL(ENABLE_SHAGA, false) +AC_ARG_ENABLE(shaga, +[ --enable-shaga Enable ShagaEngine support(Mysql logging feature)], +[ if test "$enableval" != "no"; then + echo "ShagaEngine support enabled" + AC_DEFINE(USE_SHAGA, 1, [Define this to include code for ShagaEngine.]) + AM_CONDITIONAL(ENABLE_SHAGA, true) + SHAGALIB="-L/usr/local/lib/mysql -lmysqlclient -lz -lcrypt -lm" +fi +]) +AC_SUBST(SHAGALIB) + dnl SSL is not enabled by default. AM_CONDITIONAL(ENABLE_SSL, false) @@ -2619,7 +2632,6 @@ getaddrinfo \ getnameinfo \ strerror \ - strtok_r \ tempnam \ ) Index: squid3/include/profiling.h diff -u squid3/include/profiling.h:1.23 squid3/include/profiling.h:1.23.2.1 --- squid3/include/profiling.h:1.23 Thu Nov 15 15:51:01 2007 +++ squid3/include/profiling.h Thu Jan 31 09:57:23 2008 @@ -156,8 +156,7 @@ XPROF_HttpHeaderParse, XPROF_HttpHeaderClean, XPROF_StringInitBuf, - XPROF_StringInit, - XPROF_StringLimitInit, + XPROF_StringAllocAndFill, XPROF_StringClean, XPROF_StringReset, XPROF_StringAppend, Index: squid3/include/squid_mswin.h diff -u squid3/include/squid_mswin.h:1.9 squid3/include/squid_mswin.h:1.9.2.1 --- squid3/include/squid_mswin.h:1.9 Sun Jan 20 09:51:23 2008 +++ squid3/include/squid_mswin.h Thu Jan 31 09:57:23 2008 @@ -215,6 +215,10 @@ #include #endif #include +#if (EAI_NODATA == EAI_NONAME) +#undef EAI_NODATA +#define EAI_NODATA WSANO_DATA +#endif #if defined(_MSC_VER) /* Microsoft C Compiler ONLY */ /* Hack to suppress compiler warnings on FD_SET() & FD_CLR() */ #pragma warning (push) Index: squid3/include/strtok_r.h diff -u squid3/include/strtok_r.h:1.2 squid3/include/strtok_r.h:removed --- squid3/include/strtok_r.h:1.2 Sun Jan 20 09:51:23 2008 +++ squid3/include/strtok_r.h Thu Jan 31 17:23:09 2008 @@ -1,50 +0,0 @@ -/* Split string into tokens - Copyright (C) 2004-2005 Free Software Foundation, Inc. - Written by Simon Josefsson. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef STRTOK_R_H -#define STRTOK_R_H - -/* Get strtok_r declaration, if available. */ -#include - -/* Parse S into tokens separated by characters in DELIM. - If S is NULL, the saved pointer in SAVE_PTR is used as - the next starting point. For example: - char s[] = "-abc-=-def"; - char *sp; - x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" - x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL - x = strtok_r(NULL, "=", &sp); // x = NULL - // s = "abc\0-def\0" - - This is a variant of strtok() that is multithread-safe. - - For the POSIX documentation for this function, see: - http://www.opengroup.org/susv3xsh/strtok.html - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - Caveat: It doesn't work with multibyte strings unless all of the delimiter - characters are ASCII characters < 0x30. - - See also strsep(). -*/ -SQUIDCEXTERN char *strtok_r(char *s, const char *sep, char **lasts); - -#endif /* STRTOK_R_H */ Index: squid3/lib/strtok_r.c diff -u squid3/lib/strtok_r.c:1.2 squid3/lib/strtok_r.c:removed --- squid3/lib/strtok_r.c:1.2 Sun Jan 20 09:51:23 2008 +++ squid3/lib/strtok_r.c Thu Jan 31 17:23:09 2008 @@ -1,74 +0,0 @@ -/* Reentrant string tokenizer. Generic version. - Copyright (C) 1991,1996-1999,2001,2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#undef strtok_r -#undef __strtok_r - -#ifndef _LIBC -/* Get specification. */ -# include "strtok_r.h" -# define __strtok_r strtok_r -# define __rawmemchr strchr -#endif - -/* Parse S into tokens separated by characters in DELIM. - If S is NULL, the saved pointer in SAVE_PTR is used as - the next starting point. For example: - char s[] = "-abc-=-def"; - char *sp; - x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" - x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL - x = strtok_r(NULL, "=", &sp); // x = NULL - // s = "abc\0-def\0" -*/ -char * -strtok_r (char *s, const char *delim, char **save_ptr) -{ - char *token; - - if (s == NULL) - s = *save_ptr; - - /* Scan leading delimiters. */ - s += strspn (s, delim); - if (*s == '\0') - { - *save_ptr = s; - return NULL; - } - - /* Find the end of the token. */ - token = s; - s = strpbrk (token, delim); - if (s == NULL) - /* This token finishes the string. */ - *save_ptr = __rawmemchr (token, '\0'); - else - { - /* Terminate the token and make *SAVE_PTR point past it. */ - *s = '\0'; - *save_ptr = s + 1; - } - return token; -} Index: squid3/src/ACLARP.cc diff -u squid3/src/ACLARP.cc:1.22 squid3/src/ACLARP.cc:1.22.2.1 --- squid3/src/ACLARP.cc:1.22 Sun Jan 20 09:51:23 2008 +++ squid3/src/ACLARP.cc Thu Jan 31 09:57:23 2008 @@ -568,7 +568,9 @@ /* Find MAC address from net table */ for (i = 0 ; i < NetTable->dwNumEntries ; i++) { - if ((c == (struct in_addr)NetTable->table[i].dwAddr) && (NetTable->table[i].dwType > 2)) { + in_addr a; + a.s_addr = NetTable->table[i].dwAddr; + if (c == a && (NetTable->table[i].dwType > 2)) { arpReq.arp_ha.sa_family = AF_UNSPEC; memcpy(arpReq.arp_ha.sa_data, NetTable->table[i].bPhysAddr, NetTable->table[i].dwPhysAddrLen); } Index: squid3/src/ACLDestinationDomain.cc diff -u squid3/src/ACLDestinationDomain.cc:1.17 squid3/src/ACLDestinationDomain.cc:1.17.2.1 --- squid3/src/ACLDestinationDomain.cc:1.17 Fri Dec 14 15:50:57 2007 +++ squid3/src/ACLDestinationDomain.cc Thu Jan 31 09:57:23 2008 @@ -76,6 +76,8 @@ int ACLDestinationDomainStrategy::match (ACLData * &data, ACLChecklist *checklist) { + assert(checklist != NULL && checklist->request != NULL); + const ipcache_addrs *ia = NULL; const char *fqdn = NULL; Index: squid3/src/ESIInclude.cc diff -u squid3/src/ESIInclude.cc:1.15 squid3/src/ESIInclude.cc:1.15.2.1 --- squid3/src/ESIInclude.cc:1.15 Sun Jan 20 11:51:07 2008 +++ squid3/src/ESIInclude.cc Thu Jan 31 09:57:23 2008 @@ -320,7 +320,7 @@ ESIInclude::prepareRequestHeaders(HttpHeader &tempheaders, ESIVarState *vars) { tempheaders.update (&vars->header(), NULL); - tempheaders.removeConnectionHeaderEntries(); + tempheaders.removeHopByHopEntries(); } Index: squid3/src/HttpHeader.cc diff -u squid3/src/HttpHeader.cc:1.51 squid3/src/HttpHeader.cc:1.51.2.1 --- squid3/src/HttpHeader.cc:1.51 Mon Nov 26 05:51:15 2007 +++ squid3/src/HttpHeader.cc Thu Jan 31 09:57:23 2008 @@ -236,6 +236,12 @@ HDR_USER_AGENT, HDR_X_FORWARDED_FOR, HDR_SURROGATE_CAPABILITY }; +static http_hdr_type HopByHopHeadersArr[] = + { + HDR_CONNECTION, HDR_KEEP_ALIVE, HDR_PROXY_AUTHENTICATE, HDR_PROXY_AUTHORIZATION, + HDR_TE, HDR_TRAILERS, HDR_TRANSFER_ENCODING, HDR_UPGRADE + }; + /* header accounting */ static HttpHeaderStat HttpHeaderStats[] = { @@ -1763,6 +1769,18 @@ } void +HttpHeader::removeHopByHopEntries() +{ + removeConnectionHeaderEntries(); + + int count = countof(HopByHopHeadersArr); + + for (int i=0; i entries; /* parsed fields in raw format */ HttpHeaderMask mask; /* bit set <=> entry present */ http_hdr_owner_type owner; /* request or reply */ int len; /* length when packed, not counting terminating '\0' */ +protected: + void removeConnectionHeaderEntries(); + private: HttpHeaderEntry *findLastEntry(http_hdr_type id) const; // Make it non-copyable. Our destructor is a bit nasty... Index: squid3/src/Makefile.am diff -u squid3/src/Makefile.am:1.136 squid3/src/Makefile.am:1.136.2.1 --- squid3/src/Makefile.am:1.136 Mon Jan 14 05:51:53 2008 +++ squid3/src/Makefile.am Tue Jan 29 01:02:01 2008 @@ -121,6 +121,12 @@ UNLINKD = endif +if ENABLE_SHAGA +SHAGASOURCE = shaga.cc shaga.h ShagaConfig.h ShagaAccess.h ShagaProtos.h +else +SHAGASOURCE = +endif + if ENABLE_PINGER PINGER = pinger else @@ -197,12 +203,13 @@ AM_CFLAGS = @SQUID_CFLAGS@ AM_CXXFLAGS = @SQUID_CXXFLAGS@ - +MYSQL_INC_DIR = /usr/local/include/mysql +MYSQL_LIB_DIR = /usr/local/lib/mysql EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a ICAP/libicap.a noinst_LIBRARIES = @DISK_LIBS@ @ICAP_LIBS@ noinst_LTLIBRARIES = libsquid.la libauth.la -INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/lib/libTrie/include +INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/lib/libTrie/include -I$(MYSQL_INC_DIR) -I$(MYSQL_LIB_DIR) INCLUDES += @SQUID_CPPUNIT_INC@ EXTRA_PROGRAMS = \ @@ -452,6 +459,7 @@ CompletionDispatcher.cc \ CompletionDispatcher.h \ $(squid_COMMSOURCES) \ + $(SHAGASOURCE) \ CommRead.h \ ConfigOption.cc \ ConfigParser.cc \ @@ -673,6 +681,7 @@ -lmiscutil \ @XTRA_LIBS@ \ @EPOLL_LIBS@ \ + @SHAGALIB@ \ @MINGW_LIBS@ squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @STORE_OBJS@ \ @@ -894,6 +903,7 @@ tools.cc \ typedefs.h \ $(UNLINKDSOURCE) \ + $(SHAGASOURCE) \ URLScheme.cc \ urn.cc \ useragent.cc \ @@ -917,6 +927,7 @@ @SSLLIB@ \ -lmiscutil \ @XTRA_LIBS@ \ + @SHAGALIB@ \ @EPOLL_LIBS@ \ @MINGW_LIBS@ ufsdump_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @@ -1339,6 +1350,7 @@ $(DELAY_POOL_SOURCE) \ disk.cc \ $(DNSSOURCE) \ + $(SHAGASOURCE) \ event.cc \ errorpage.cc \ $(ESI_SOURCE) \ @@ -1521,6 +1533,7 @@ gopher.cc \ helper.cc \ $(HTCPSOURCE) \ + $(SHAGASOURCE) \ http.cc \ HttpBody.cc \ HttpHeader.cc \ @@ -1675,6 +1688,7 @@ gopher.cc \ helper.cc \ $(HTCPSOURCE) \ + $(SHAGASOURCE) \ http.cc \ HttpBody.cc \ HttpHeader.cc \ @@ -1840,6 +1854,7 @@ $(DELAY_POOL_SOURCE) \ disk.cc \ $(DNSSOURCE) \ + $(SHAGASOURCE) \ event.cc \ errorpage.cc \ $(ESI_SOURCE) \ @@ -2000,6 +2015,7 @@ $(DELAY_POOL_SOURCE) \ disk.cc \ $(DNSSOURCE) \ + $(SHAGASOURCE) \ event.cc \ errorpage.cc \ $(ESI_SOURCE) \ @@ -2412,6 +2428,7 @@ Server.cc \ $(SNMP_SOURCE) \ $(SSL_SOURCE) \ + $(SHAGASOURCE) \ stat.cc \ StatHist.cc \ stmem.cc \ Index: squid3/src/Mem.h diff -u squid3/src/Mem.h:1.5 squid3/src/Mem.h:1.5.36.1 --- squid3/src/Mem.h:1.5 Sun May 28 17:50:18 2006 +++ squid3/src/Mem.h Thu Jan 31 09:57:23 2008 @@ -47,6 +47,7 @@ public: static void Init(); + static void Report(); static void RegisterWithCacheManager(CacheManager & manager); static void Stats(StoreEntry *); static void CleanIdlePools(void *unused); Index: squid3/src/ShagaAccess.h diff -u /dev/null squid3/src/ShagaAccess.h:1.1.2.1 --- /dev/null Thu Jan 1 01:00:00 1970 +++ squid3/src/ShagaAccess.h Tue Jan 29 01:02:01 2008 @@ -0,0 +1,41 @@ +/* + * AUTHOR: Arthur Tumanyan + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ +#ifndef SHAGA_ACCESS_H +#define SHAGA_ACCESS_H +int writeToDB(char * __time,char * username,char * ip_address,char * byte); +struct { + char access_timestamp[13]; + char access_user[8]; + char access_ip[15]; + char access_byte[15]; +}ShagaAccess; + +#endif Index: squid3/src/ShagaConfig.h diff -u /dev/null squid3/src/ShagaConfig.h:1.1.2.1 --- /dev/null Thu Jan 1 01:00:00 1970 +++ squid3/src/ShagaConfig.h Tue Jan 29 01:02:01 2008 @@ -0,0 +1,44 @@ +/* + * AUTHOR: Arthur Tumanyan + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ +#ifndef SHAGA_CONFIG_H +#define SHAGA_CONFIG_H + +struct { + int enable_shaga; + int enable_db_config; + char *db_host; + u_short db_port; + char *db_name; + char *db_user; + char *db_pwd; +}Shaga; + +#endif Index: squid3/src/ShagaProtos.h diff -u /dev/null squid3/src/ShagaProtos.h:1.1.2.1 --- /dev/null Thu Jan 1 01:00:00 1970 +++ squid3/src/ShagaProtos.h Tue Jan 29 01:02:02 2008 @@ -0,0 +1,38 @@ +/* + * AUTHOR: Arthur Tumanyan + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ +#ifndef SHAGA_PROTOS_H +#define SHAGA_PROTOS_H +int db_connect(char *dbhost,char *dbuser,char *dbpwd,char *dbname,unsigned int dbport); +void init_shaga_support(); +void shutdown_shaga_support(); +int getExcludeHosts(); +int isExHost(char *host); +#endif Index: squid3/src/SquidString.h diff -u squid3/src/SquidString.h:1.14 squid3/src/SquidString.h:1.14.2.1 --- squid3/src/SquidString.h:1.14 Sun Jan 20 01:50:56 2008 +++ squid3/src/SquidString.h Thu Jan 31 09:57:23 2008 @@ -98,10 +98,7 @@ _SQUID_INLINE_ int size() const; _SQUID_INLINE_ char const * buf() const; - void buf(char *); - void init (char const *); - void initBuf(size_t sz); - void limitInit(const char *str, int len); + void limitInit(const char *str, int len); // TODO: rename to assign() void clean(); void reset(char const *str); void append(char const *buf, int len); @@ -139,7 +136,13 @@ #endif + + private: + void allocAndFill(const char *str, int len); + void allocBuffer(size_t sz); + void setBuffer(char *buf, size_t sz); + /* never reference these directly! */ unsigned short int size_; /* buffer size; 64K limit */ Index: squid3/src/String.cc diff -u squid3/src/String.cc:1.15 squid3/src/String.cc:1.15.18.1 --- squid3/src/String.cc:1.15 Tue May 29 06:51:40 2007 +++ squid3/src/String.cc Thu Jan 31 09:57:23 2008 @@ -36,32 +36,33 @@ #include "squid.h" #include "Store.h" +// low-level buffer allocation, +// does not free old buffer and does not adjust or look at len_ void -String::initBuf(size_t sz) +String::allocBuffer(size_t sz) { PROF_start(StringInitBuf); - buf((char *)memAllocString(sz, &sz)); - assert(sz < 65536); - size_ = sz; + assert (buf_ == NULL); + char *newBuffer = (char*)memAllocString(sz, &sz); + setBuffer(newBuffer, sz); PROF_stop(StringInitBuf); } +// low-level buffer assignment +// does not free old buffer and does not adjust or look at len_ void -String::init(char const *str) +String::setBuffer(char *aBuf, size_t aSize) { - assert(this); - - PROF_start(StringInit); - if (str) - limitInit(str, strlen(str)); - else - clean(); - PROF_stop(StringInit); + assert(!buf_); + assert(aSize < 65536); + buf_ = aBuf; + size_ = aSize; } String::String (char const *aString) : size_(0), len_(0), buf_(NULL) { - init (aString); + if (aString) + allocAndFill(aString, strlen(aString)); #if DEBUGSTRINGS StringRegistry::Instance().add(this); @@ -71,19 +72,16 @@ String & String::operator =(char const *aString) { - clean(); - init (aString); + reset(aString); return *this; } String & String::operator = (String const &old) { - clean (); - - if (old.len_) - limitInit (old.buf(), old.len_); - + clean(); // TODO: optimize to avoid cleaning the buffer we can use + if (old.size() > 0) + allocAndFill(old.buf(), old.size()); return *this; } @@ -105,21 +103,32 @@ return true; } +// public interface, makes sure that we clean the old buffer first void String::limitInit(const char *str, int len) { - PROF_start(StringLimitInit); + clean(); // TODO: optimize to avoid cleaning the buffer we can use + allocAndFill(str, len); +} + +// Allocates the buffer to fit the supplied string and fills it. +// Does not clean. +void +String::allocAndFill(const char *str, int len) +{ + PROF_start(StringAllocAndFill); assert(this && str); - initBuf(len + 1); + allocBuffer(len + 1); len_ = len; xmemcpy(buf_, str, len); buf_[len] = '\0'; - PROF_stop(StringLimitInit); + PROF_stop(StringAllocAndFill); } String::String (String const &old) : size_(0), len_(0), buf_(NULL) { - init (old.buf()); + if (old.size() > 0) + allocAndFill(old.buf(), old.size()); #if DEBUGSTRINGS StringRegistry::Instance().add(this); @@ -156,8 +165,9 @@ String::reset(const char *str) { PROF_start(StringReset); - clean(); - init(str); + clean(); // TODO: optimize to avoid cleaning the buffer if we can reuse it + if (str) + allocAndFill(str, strlen(str)); PROF_stop(StringReset); } @@ -172,11 +182,12 @@ strncat(buf_, str, len); len_ += len; } else { + // Create a temporary string and absorb it later. String snew; snew.len_ = len_ + len; - snew.initBuf(snew.len_ + 1); + snew.allocBuffer(snew.len_ + 1); - if (buf_) + if (len_) xmemcpy(snew.buf_, buf(), len_); if (len) @@ -215,21 +226,13 @@ String::absorb(String &old) { clean(); - size_ = old.size_; - buf (old.buf_); + setBuffer(old.buf_, old.size_); len_ = old.len_; old.size_ = 0; old.buf_ = NULL; old.len_ = 0; } -void -String::buf(char *newBuf) -{ - assert (buf_ == NULL); - buf_ = newBuf; -} - #if DEBUGSTRINGS void String::stat(StoreEntry *entry) const Index: squid3/src/WinSvc.cc diff -u squid3/src/WinSvc.cc:1.4 squid3/src/WinSvc.cc:1.4.24.1 --- squid3/src/WinSvc.cc:1.4 Sat Apr 28 15:51:48 2007 +++ squid3/src/WinSvc.cc Thu Jan 31 09:57:23 2008 @@ -69,6 +69,11 @@ #endif static int Squid_Aborting = 0; +static HANDLE NotifyAddrChange_thread = INVALID_HANDLE_VALUE; + +#undef NotifyAddrChange +typedef DWORD(WINAPI * PFNotifyAddrChange) (OUT PHANDLE, IN LPOVERLAPPED); +#define NOTIFYADDRCHANGE "NotifyAddrChange" #if USE_WIN32_SERVICE static SERVICE_STATUS svcStatus; @@ -386,6 +391,17 @@ } void +WIN32_IpAddrChangeMonitorExit() +{ + DWORD status = ERROR_SUCCESS; + + if (NotifyAddrChange_thread == INVALID_HANDLE_VALUE) { + TerminateThread(NotifyAddrChange_thread, status); + CloseHandle(NotifyAddrChange_thread); + } +} + +void WIN32_Exit() { #ifdef _SQUID_MSWIN_ @@ -406,12 +422,57 @@ DeleteCriticalSection(dbg_mutex); WIN32_ExceptionHandlerCleanup(); + WIN32_IpAddrChangeMonitorExit(); #endif _exit(0); } +#ifdef _SQUID_MSWIN_ +static DWORD WINAPI +WIN32_IpAddrChangeMonitor(LPVOID lpParam) +{ + DWORD Result; + HMODULE IPHLPAPIHandle; + PFNotifyAddrChange NotifyAddrChange; + + if ((IPHLPAPIHandle = GetModuleHandle("IPHLPAPI")) == NULL) + IPHLPAPIHandle = LoadLibrary("IPHLPAPI"); + NotifyAddrChange = (PFNotifyAddrChange) GetProcAddress(IPHLPAPIHandle, NOTIFYADDRCHANGE); + + while (1) { + Result = NotifyAddrChange(NULL, NULL); + if (Result != NO_ERROR) { + debug(1, 1) ("NotifyAddrChange error %ld\n", Result); + return 1; + } + debug(1, 1) ("Notification of IP address change received, requesting Squid reconfiguration ...\n"); + reconfigure(SIGHUP); + } + return 0; +} + +DWORD +WIN32_IpAddrChangeMonitorInit() +{ + DWORD status = ERROR_SUCCESS; + DWORD threadID = 0, ThrdParam = 0; + + if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) { + NotifyAddrChange_thread = CreateThread(NULL, 0, WIN32_IpAddrChangeMonitor, + &ThrdParam, 0, &threadID); + if (NotifyAddrChange_thread == NULL) { + status = GetLastError(); + NotifyAddrChange_thread = INVALID_HANDLE_VALUE; + debug(1, 1) ("Failed to start IP monitor thread.\n"); + } else + debug(1, 2) ("Starting IP monitor thread [%li] ...\n", threadID); + } + return status; +} +#endif + int WIN32_Subsystem_Init(int * argc, char *** argv) { #if defined(_MSC_VER) /* Microsoft C Compiler ONLY */ Index: squid3/src/access_log.cc diff -u squid3/src/access_log.cc:1.51 squid3/src/access_log.cc:1.51.2.1 --- squid3/src/access_log.cc:1.51 Sun Jan 20 01:50:56 2008 +++ squid3/src/access_log.cc Tue Jan 29 01:02:02 2008 @@ -47,7 +47,9 @@ #include "MemBuf.h" #include "SquidTime.h" #include "CacheManager.h" - +#ifdef USE_SHAGA +#include "ShagaAccess.h" +#endif static void accessLogSquid(AccessLogEntry * al, Logfile * logfile); static void accessLogCommon(AccessLogEntry * al, Logfile * logfile); static void accessLogCustom(AccessLogEntry * al, customlog * log); @@ -1339,6 +1341,23 @@ safe_free(ereq); safe_free(erep); } +#if USE_SHAGA +if(Config.Shaga.enable_shaga){ +// +snprintf(ShagaAccess.access_timestamp,13,"%9ld.%03d", + (long int)current_time.tv_sec,( (int)current_time.tv_usec / 1000)); +sscanf((user ? user : dash_str),"%s",ShagaAccess.access_user); +sscanf(client,"%s",ShagaAccess.access_ip); +snprintf(ShagaAccess.access_byte,15,"%ld",(long int)al->cache.size); +// + writeToDB(ShagaAccess.access_timestamp, + ShagaAccess.access_user, + ShagaAccess.access_ip, + ShagaAccess.access_byte); /* write to db TIMESTAMP ,USER ,IP ,BYTE */ +} +#endif + + logfilePrintf(logfile, "\n"); safe_free(user); } Index: squid3/src/cache_cf.cc diff -u squid3/src/cache_cf.cc:1.107 squid3/src/cache_cf.cc:1.107.2.1 --- squid3/src/cache_cf.cc:1.107 Fri Jan 18 23:50:41 2008 +++ squid3/src/cache_cf.cc Thu Jan 31 09:57:23 2008 @@ -210,10 +210,10 @@ { int error_count = 0; char* saveptr = NULL; - char* file = strtok_r(files, w_space, &saveptr); + char* file = strwordtok(files, &saveptr); while (file != NULL) { error_count += parseOneConfigFile(file, depth); - file = strtok_r(NULL, w_space, &saveptr); + file = strwordtok(NULL, &saveptr); } return error_count; } Index: squid3/src/cf.data.pre diff -u squid3/src/cf.data.pre:1.169 squid3/src/cf.data.pre:1.169.2.1 --- squid3/src/cf.data.pre:1.169 Sun Jan 20 03:51:46 2008 +++ squid3/src/cf.data.pre Tue Jan 29 01:02:03 2008 @@ -5521,4 +5521,59 @@ rounded to 1000. DOC_END +NAME: enable_shaga_engine +COMMENT: on|off +IFDEF: USE_SHAGA +TYPE: onoff +LOC: Config.Shaga.enable_shaga +DEFAULT: on +DOC_START + When this set to on,squid will write some entries from access.log file into database +DOC_END + +NAME: shaga_db_host +COMMENT: mysql server ip address +IFDEF: USE_SHAGA +TYPE: string +LOC: Config.Shaga.db_host +DEFAULT: 10.0.0.1 +DOC_START +DOC_END + +NAME: shaga_db_port +COMMENT: listening port of mysql server +IFDEF: USE_SHAGA +TYPE: ushort +LOC: Config.Shaga.db_port +DEFAULT: 3306 +DOC_START +DOC_END + +NAME: shaga_db_name +COMMENT: shaga database name +IFDEF: USE_SHAGA +TYPE: string +LOC: Config.Shaga.db_name +DEFAULT: shaga +DOC_START +DOC_END + +NAME: shaga_db_user +COMMENT: shaga database user +IFDEF: USE_SHAGA +TYPE: string +LOC: Config.Shaga.db_user +DEFAULT: shaga +DOC_START +DOC_END + +NAME: shaga_db_pwd +COMMENT: shaga database password +IFDEF: USE_SHAGA +TYPE: string +LOC: Config.Shaga.db_pwd +DEFAULT: shaga +DOC_START +DOC_END + EOF Index: squid3/src/cf_gen_defines diff -u squid3/src/cf_gen_defines:1.4 squid3/src/cf_gen_defines:1.4.36.1 --- squid3/src/cf_gen_defines:1.4 Sun Jul 2 10:50:45 2006 +++ squid3/src/cf_gen_defines Tue Jan 29 01:02:04 2008 @@ -20,6 +20,7 @@ define["USE_WCCP"]="--enable-wccp" define["USE_WCCPv2"]="--enable-wccpv2" define["ESI"]="--enable-esi" + define["USE_SHAGA"]="--enable-shaga" } /^IFDEF:/ { if (define[$2] != "") Index: squid3/src/client_side_reply.cc diff -u squid3/src/client_side_reply.cc:1.121 squid3/src/client_side_reply.cc:1.121.2.1 --- squid3/src/client_side_reply.cc:1.121 Sun Jan 20 01:50:56 2008 +++ squid3/src/client_side_reply.cc Thu Jan 31 09:57:23 2008 @@ -1234,10 +1234,7 @@ if (is_hit) hdr->delById(HDR_SET_COOKIE); - /* - * Be sure to obey the Connection header - */ - reply->header.removeConnectionHeaderEntries(); + reply->header.removeHopByHopEntries(); // if (request->range) // clientBuildRangeHeader(http, reply); @@ -1334,6 +1331,9 @@ #endif + /* Check whether we should send keep-alive */ + // TODO: disable proxy_keepalive only once + if (reply->bodySize(request->method) < 0) { debugs(88, 3, "clientBuildReplyHeader: can't keep-alive, unknown body size" ); request->flags.proxy_keepalive = 0; @@ -1352,6 +1352,11 @@ if (!Config.onoff.client_pconns && !request->flags.must_keepalive) request->flags.proxy_keepalive = 0; + if (request->flags.proxy_keepalive && shutting_down) { + debugs(88, 3, "clientBuildReplyHeader: Shutting down, don't keep-alive."); + request->flags.proxy_keepalive = 0; + } + /* Append VIA */ if (Config.onoff.via) { LOCAL_ARRAY(char, bbuf, MAX_URL + 32); Index: squid3/src/main.cc diff -u squid3/src/main.cc:1.92 squid3/src/main.cc:1.92.2.2 --- squid3/src/main.cc:1.92 Sat Dec 29 10:50:34 2007 +++ squid3/src/main.cc Thu Jan 31 09:57:24 2008 @@ -73,6 +73,9 @@ #include "forward.h" #include "MemPool.h" #include "ICMPSquid.h" +#ifdef USE_SHAGA +#include "ShagaProtos.h" +#endif #if USE_WIN32_SERVICE @@ -636,6 +639,7 @@ errorClean(); enter_suid(); /* root to read config file */ parseConfigFile(ConfigFile, manager); + Mem::Report(); setEffectiveUser(); _db_init(Config.Log.log, Config.debugOptions); ipcache_restart(); /* clear stuck entries */ @@ -667,6 +671,14 @@ wccp2Init(); #endif +#ifdef USE_SHAGA +if(Config.Shaga.enable_shaga){ + + shutdown_shaga_support(); + init_shaga_support(); + +}else _db_print("ShagaEngine is disabled\n"); +#endif serverConnectionsOpen(); neighbors_init(); @@ -827,6 +839,10 @@ if (WIN32_Socks_initialized) debugs(1, 1, "Windows sockets initialized"); + if (WIN32_OS_version > _WIN_OS_WINNT) { + WIN32_IpAddrChangeMonitorInit(); + } + #endif if (!configured_once) @@ -986,6 +1002,14 @@ #endif +#ifdef USE_SHAGA +if(Config.Shaga.enable_shaga){ + + init_shaga_support(); + +}else _db_print("ShagaEngine is disabled\n"); +#endif + serverConnectionsOpen(); neighbors_init(); @@ -1192,6 +1216,8 @@ parse_err = parseConfigFile(ConfigFile, manager); + Mem::Report(); + if (opt_parse_cfg_only) return parse_err; @@ -1626,6 +1652,12 @@ wccp2ConnectionClose(); #endif +#ifdef USE_SHAGA +if(Config.Shaga.enable_shaga){ + shutdown_shaga_support(); +} +#endif + releaseServerSockets(); commCloseAllSockets(); #if DELAY_POOLS Index: squid3/src/mem.cc diff -u squid3/src/mem.cc:1.39 squid3/src/mem.cc:1.39.2.1 --- squid3/src/mem.cc:1.39 Thu Nov 15 08:51:00 2007 +++ squid3/src/mem.cc Thu Jan 31 09:57:25 2008 @@ -382,8 +382,6 @@ * debug messages here at level 0 or 1 will always be printed * on stderr. */ - debugs(13, 3, "Memory pools are '" << ((Config.onoff.mem_pools ? "on" : "off")) << "'; limit: "<< - std::setprecision(3) << toMB(MemPools::GetInstance().idleLimit()) << " MB"); /* set all pointers to null */ memset(MemPools, '\0', sizeof(MemPools)); @@ -431,6 +429,15 @@ } void +Mem::Report() +{ + debugs(13, 3, "Memory pools are '" << + (Config.onoff.mem_pools ? "on" : "off") << "'; limit: " << + std::setprecision(3) << toMB(MemPools::GetInstance().idleLimit()) << + " MB"); +} + +void Mem::RegisterWithCacheManager(CacheManager & manager) { manager.registerAction("mem", Index: squid3/src/protos.h diff -u squid3/src/protos.h:1.91 squid3/src/protos.h:1.91.2.1 --- squid3/src/protos.h:1.91 Mon Jan 21 17:21:46 2008 +++ squid3/src/protos.h Thu Jan 31 09:57:25 2008 @@ -770,8 +770,8 @@ SQUIDCEXTERN int WIN32_getrusage(int, struct rusage *); SQUIDCEXTERN void WIN32_ExceptionHandlerInit(void); -SQUIDCEXTERN int Win32__WSAFDIsSet(int fd, fd_set* set - ); +SQUIDCEXTERN int Win32__WSAFDIsSet(int fd, fd_set* set); +SQUIDCEXTERN DWORD WIN32_IpAddrChangeMonitorInit(); #endif Index: squid3/src/shaga.cc diff -u /dev/null squid3/src/shaga.cc:1.1.2.1 --- /dev/null Thu Jan 1 01:00:00 1970 +++ squid3/src/shaga.cc Tue Jan 29 01:02:04 2008 @@ -0,0 +1,182 @@ +/* + * AUTHOR: Arthur Tumanyan + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" +#include "shaga.h" +// +int db_connect(char *dbhost,char *dbuser,char *dbpwd,char *dbname,unsigned int dbport){ + + mysql_init(&mysql); + connection = mysql_real_connect(&mysql,dbhost,dbuser,dbpwd,dbname,dbport,NULL,0); + /* check for connection error */ + if(connection == NULL) { + /* log the error message */ + snprintf(MYSQL_ERR,LINE_MAXLEN,"%s\n",(char *)mysql_error(&mysql)); + _db_print(MYSQL_ERR); + /* log this */ + + return 1; + } + + return 0; +} +void init_shaga_support(){ + +if ( db_connect(Config.Shaga.db_host, + Config.Shaga.db_user, + Config.Shaga.db_pwd, + Config.Shaga.db_name, + Config.Shaga.db_port) != 0) + { + snprintf(MYSQL_ERR,LINE_MAXLEN,"Cannot connect to database %s on %s\n", + Config.Shaga.db_name,Config.Shaga.db_host); + /* log this*/if(!already_logged){ + _db_print(MYSQL_ERR); + already_logged = 1; + } + _db_print("ShagaEngine can not start\n"); + _db_print("Fix all errors\n"); + shaga_force = 1; +}else { + exclude = (0 == getExcludeHosts()) ? 1 : 0; + _db_print("ShagaEngine is started\n"); + snprintf(TMP_MSG,LINE_MAXLEN,"Exclude hosts detected %d\n",hc); + _db_print(TMP_MSG); + +} +} + +// +int writeToDB(char * __time,char * username,char * ip_address,char * byte){ + + long int my_stamp = atol(__time); + time_t my_stamp2 = (time_t)my_stamp; + + thistime = localtime(&my_stamp2); + strftime(timestr,25,"%F %T",thistime); + int retval; + + snprintf(TMP_QUERY,LINE_MAXLEN, + "INSERT DELAYED INTO %s(`date`,`user`,`ip_addr`,`bytes`) VALUES(\'%s\',\'%s\',\'%s\',\'%s\')", + TMP_TABLE,(char *) timestr,username,(char *)ip_address,(char *)byte); +if(shaga_force == 0){ +if(exclude == 1 && ( 0 == isExHost(ip_address) ) ){ + state = mysql_real_query(&mysql,TMP_QUERY,strlen(TMP_QUERY)); + +} /* IP address is from exclude hosts pool */ + } /* connection failed */ + + // + if(state) { + snprintf(MYSQL_ERR,LINE_MAXLEN,"%s\n",(char *)mysql_error(&mysql)); + /* log this */ +if(!already_logged){ + _db_print(MYSQL_ERR); + already_logged = 1; + } + return 1; + } + int affected = (int)mysql_affected_rows(&mysql); + if(affected > 0){ + retval = 0; + }else{ + snprintf(MYSQL_ERR,LINE_MAXLEN,"%s\n",(char *)mysql_error(&mysql)); + /* log this */ + if(!already_logged) { + _db_print(MYSQL_ERR); + already_logged = 1; + } + retval = 1; + } + + return retval; +} +// + +void shutdown_shaga_support(){ + if (shaga_force == 0)_db_print("ShagaEngine is shutting down\n"); + if(connection != NULL) mysql_close(&mysql); +} + +int getExcludeHosts(){ + // + snprintf(TMP_QUERY,LINE_MAXLEN,"%s", + "SELECT `hosts` FROM `ecl_hosts`"); + state = mysql_real_query(&mysql,TMP_QUERY,strlen(TMP_QUERY)); + // + if(state) + { + snprintf(MYSQL_ERR,LINE_MAXLEN,"%s\n",(char *)mysql_error(&mysql)); + _db_print(MYSQL_ERR); + /* log about failure */ + return 1; + } + result = mysql_store_result(&mysql); + if (result) // there are rows + { + int c = 0; + while((row = mysql_fetch_row(result))) + { + sscanf(row[0],"%s",excludeHosts[c].host); + + c++; +} + mysql_free_result(result); + hc = c; + // + }else + { + + snprintf(MYSQL_ERR,LINE_MAXLEN,"Error getting records: %s\n",(char *) mysql_error(&mysql)); + _db_print(MYSQL_ERR); + /* log about failure */ + } + return 0; +} + +int isExHost(char *host){ + +int i,ret = 0; + +if(strlen(host) < 7) return 0; + for(i = 0;i < hc;i++) + { + if(strncmp(host,excludeHosts[i].host,15) == 0) + { + ret = 1; + break; + }//strcmp + }//for + return ret; +} +// +// + Index: squid3/src/shaga.h diff -u /dev/null squid3/src/shaga.h:1.1.2.1 --- /dev/null Thu Jan 1 01:00:00 1970 +++ squid3/src/shaga.h Tue Jan 29 01:02:04 2008 @@ -0,0 +1,65 @@ +/* + * AUTHOR: Arthur Tumanyan + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include + +#ifndef SHAGA_LIB_H +#define SHAGA_LIB_H + +#define LINE_MAXLEN 512 +#define TMP_TABLE "tmp_traff" +#define MAX_USER_COUNT 9999 +// +#include "ShagaProtos.h" + +int state; +int hc = 0; +char TMP_QUERY[LINE_MAXLEN]; +char MYSQL_ERR[LINE_MAXLEN]; +char TMP_MSG[LINE_MAXLEN]; +int exclude; +int u_count; /* users count */ +char timestr[25]; +struct tm *thistime; + +struct { + char host[16]; +}excludeHosts[MAX_USER_COUNT]; +// +int shaga_force = 0; +int already_logged = 0; +// +MYSQL_RES *result; +MYSQL_ROW row; +MYSQL *connection, mysql; +// +// +#endif Index: squid3/src/snmp_core.cc diff -u squid3/src/snmp_core.cc:1.24 squid3/src/snmp_core.cc:1.24.2.1 --- squid3/src/snmp_core.cc:1.24 Tue Dec 18 15:51:12 2007 +++ squid3/src/snmp_core.cc Thu Jan 31 09:57:25 2008 @@ -1087,7 +1087,7 @@ for (x = 0; x < Len; x++) { snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]); - strncat(objid, mbuf, sizeof(objid)); + strncat(objid, mbuf, sizeof(objid) - strlen(objid) - 1); } debugs(49, lvl, " oid = " << objid); Index: squid3/src/squid.h diff -u squid3/src/squid.h:1.42 squid3/src/squid.h:1.42.2.1 --- squid3/src/squid.h:1.42 Sun Jan 20 09:51:23 2008 +++ squid3/src/squid.h Thu Jan 31 09:57:25 2008 @@ -388,10 +388,6 @@ #include "strtoll.h" #endif -#if !HAVE_STRTOK_R -#include "strtok_r.h" -#endif - #if !HAVE_INITGROUPS #include "initgroups.h" #endif Index: squid3/src/structs.h diff -u squid3/src/structs.h:1.124 squid3/src/structs.h:1.124.2.1 --- squid3/src/structs.h:1.124 Fri Jan 18 23:50:42 2008 +++ squid3/src/structs.h Tue Jan 29 01:02:04 2008 @@ -192,6 +192,10 @@ struct _SquidConfig { + +#ifdef USE_SHAGA +#include "ShagaConfig.h" +#endif struct { /* These should be for the Store::Root instance. Index: squid3/src/ICAP/ICAPModXact.cc diff -u squid3/src/ICAP/ICAPModXact.cc:1.35 squid3/src/ICAP/ICAPModXact.cc:1.35.2.1 --- squid3/src/ICAP/ICAPModXact.cc:1.35 Sun Jan 20 01:50:58 2008 +++ squid3/src/ICAP/ICAPModXact.cc Thu Jan 31 09:57:25 2008 @@ -1083,6 +1083,16 @@ if (!TheICAPConfig.reuse_connections) buf.Printf("Connection: close\r\n"); + // we must forward "Proxy-Authenticate" and "Proxy-Authorization" + // as ICAP headers. + if (virgin.header->header.has(HDR_PROXY_AUTHENTICATE)) + buf.Printf("Proxy-Authenticate: %s\r\n", + virgin.header->header.getByName("Proxy-Authenticate").buf()); + + if (virgin.header->header.has(HDR_PROXY_AUTHORIZATION)) + buf.Printf("Proxy-Authorization: %s\r\n", + virgin.header->header.getByName("Proxy-Authorization").buf()); + buf.Printf("Encapsulated: "); MemBuf httpBuf; @@ -1170,8 +1180,38 @@ // update ICAP header icapBuf.Printf("%s=%d, ", section, (int) httpBuf.contentSize()); - // pack HTTP head - packHead(httpBuf, head); + // begin cloning + HttpMsg *headClone = NULL; + + if (const HttpRequest* old_request = dynamic_cast(head)) { + HttpRequest* new_request = new HttpRequest; + urlParse(old_request->method, old_request->canonical,new_request); + new_request->http_ver = old_request->http_ver; + inheritVirginProperties(*new_request, *old_request); + headClone = new_request; + } + else if (const HttpReply *old_reply = dynamic_cast(head)) { + HttpReply* new_reply = new HttpReply; + new_reply->sline = old_reply->sline; + headClone = new_reply; + } + + Must(headClone); + + HttpHeaderPos pos = HttpHeaderInitPos; + HttpHeaderEntry* p_head_entry = NULL; + while (NULL != (p_head_entry = head->header.getEntry(&pos)) ) + headClone->header.addEntry(p_head_entry->clone()); + + // end cloning + + // remove all hop-by-hop headers from the clone + headClone->header.removeHopByHopEntries(); + + // pack polished HTTP header + packHead(httpBuf, headClone); + + delete headClone; } void ICAPModXact::packHead(MemBuf &httpBuf, const HttpMsg *head) Index: squid3/src/ICAP/ICAPXaction.cc diff -u squid3/src/ICAP/ICAPXaction.cc:1.24 squid3/src/ICAP/ICAPXaction.cc:1.24.2.1 --- squid3/src/ICAP/ICAPXaction.cc:1.24 Sun Dec 16 14:50:46 2007 +++ squid3/src/ICAP/ICAPXaction.cc Thu Jan 31 09:57:25 2008 @@ -125,7 +125,7 @@ disableRetries(); // we only retry pconn failures - IPAddress outgoing(getOutgoingAddr(NULL)); + IPAddress outgoing; connection = comm_open(SOCK_STREAM, 0, outgoing, COMM_NONBLOCKING, s.uri.buf());