From c21ad0f5b4216a1840a69fc8d59b7f4753b1bbb3 Mon Sep 17 00:00:00 2001 From: robertc <> Date: Wed, 3 May 2006 20:04:44 +0000 Subject: [PATCH] Add a StoreEntryStream class for use with store entries (An alternative to Packer, which uses c++ equivalents to printf. This is part of the work to decouple the squid modules to allow easier tests. --- configure.in | 8 +- src/HttpRequest.cc | 31 ++- src/HttpRequest.h | 6 +- src/Makefile.am | 253 ++++++++++++++++++++--- src/Mem.h | 8 +- src/Packer.h | 11 +- src/SquidString.h | 4 +- src/Store.h | 20 +- src/StoreEntryStream.h | 130 ++++++++++++ src/String.cci | 46 ++++- src/asn.cc | 4 +- src/client_side.cc | 4 +- src/client_side_request.cc | 6 +- src/htcp.cc | 4 +- src/icp_v2.cc | 4 +- src/mem.cc | 177 ++++++++-------- src/mime.cc | 4 +- src/neighbors.cc | 4 +- src/net_db.cc | 4 +- src/peer_digest.cc | 4 +- src/store.cc | 140 ++++++++----- src/store_digest.cc | 4 +- src/store_key_md5.cc | 5 +- src/tests/testHeader_StoreEntryStream.cc | 4 + src/tests/testHttpRequest.cc | 92 +++++++++ src/tests/testHttpRequest.h | 26 +++ src/tests/testStore.cc | 41 ---- src/tests/testStore.h | 47 +++++ src/tests/testStoreEntryStream.cc | 80 +++++++ src/tests/testStoreEntryStream.h | 24 +++ src/tests/testString.cc | 60 ++++++ src/tests/testString.h | 28 +++ src/time.cc | 52 +++++ src/tools.cc | 17 +- src/ufsdump.cc | 18 +- src/url.cc | 9 +- src/urn.cc | 4 +- 37 files changed, 1106 insertions(+), 277 deletions(-) create mode 100644 src/StoreEntryStream.h create mode 100644 src/tests/testHeader_StoreEntryStream.cc create mode 100644 src/tests/testHttpRequest.cc create mode 100644 src/tests/testHttpRequest.h create mode 100644 src/tests/testStoreEntryStream.cc create mode 100644 src/tests/testStoreEntryStream.h create mode 100644 src/tests/testString.cc create mode 100644 src/tests/testString.h create mode 100644 src/time.cc diff --git a/configure.in b/configure.in index be2f1d3a7c..013b2367f8 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl Configuration input file for Squid dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.406 2006/04/26 08:56:27 serassio Exp $ +dnl $Id: configure.in,v 1.407 2006/05/03 14:04:44 robertc Exp $ dnl dnl dnl @@ -13,7 +13,7 @@ AC_CONFIG_SRCDIR([src/main.cc]) AC_CONFIG_AUX_DIR(cfgaux) AM_INIT_AUTOMAKE([tar-ustar]) AM_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.406 $)dnl +AC_REVISION($Revision: 1.407 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AM_MAINTAINER_MODE @@ -745,9 +745,12 @@ AC_CACHE_CHECK(whether to enable the ICAP client,ac_cv_use_icap_client, ac_cv_us if test "$ac_cv_use_icap_client" = "yes" ; then AC_DEFINE(ICAP_CLIENT,1,[Enable ICAP client features in Squid]) AM_CONDITIONAL(USE_ICAP_CLIENT, true) + ICAP_LIBS="ICAP/libicap.a" else AC_DEFINE(ICAP_CLIENT,0,[Enable ICAP client features in Squid]) + ICAP_LIBS="" fi +AC_SUBST(ICAP_LIBS) dnl This is a developer only option. Developers know how to set defines dnl @@ -3007,7 +3010,6 @@ AC_CONFIG_FILES([\ src/fs/Makefile \ src/repl/Makefile \ src/auth/Makefile \ - src/ICAP/Makefile \ contrib/Makefile \ snmplib/Makefile \ icons/Makefile \ diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 3817fd4196..a89b94a5b0 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -1,6 +1,6 @@ /* - * $Id: HttpRequest.cc,v 1.62 2006/04/27 19:27:37 wessels Exp $ + * $Id: HttpRequest.cc,v 1.63 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 73 HTTP Request * AUTHOR: Duane Wessels @@ -143,7 +143,8 @@ HttpRequest::reset() init(); } -bool HttpRequest::sanityCheckStartLine(MemBuf *buf, http_status *error) +bool +HttpRequest::sanityCheckStartLine(MemBuf *buf, http_status *error) { /* * Just see if the request buffer starts with a known @@ -159,7 +160,8 @@ bool HttpRequest::sanityCheckStartLine(MemBuf *buf, http_status *error) return true; } -bool HttpRequest::parseFirstLine(const char *start, const char *end) +bool +HttpRequest::parseFirstLine(const char *start, const char *end) { const char *t = start + strcspn(start, w_space); method = urlParseMethod(start, t); @@ -386,3 +388,26 @@ HttpRequest::expectingBody(method_t unused, ssize_t& theSize) const return expectBody; } + +/* + * Create a Request from a URL and METHOD. + * + * If the METHOD is CONNECT, then a host:port pair is looked for instead of a URL. + * If the request cannot be created cleanly, NULL is returned + */ +HttpRequest * +HttpRequest::CreateFromUrlAndMethod(char * url, method_t method) +{ + return urlParse(method, url, NULL); +} + +/* + * Create a Request from a URL. + * + * If the request cannot be created cleanly, NULL is returned + */ +HttpRequest * +HttpRequest::CreateFromUrl(char * url) +{ + return urlParse(METHOD_GET, url, NULL); +} diff --git a/src/HttpRequest.h b/src/HttpRequest.h index abf3e52e48..1a34c067d6 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -1,6 +1,6 @@ /* - * $Id: HttpRequest.h,v 1.20 2006/04/27 19:27:37 wessels Exp $ + * $Id: HttpRequest.h,v 1.21 2006/05/03 14:04:44 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -144,6 +144,10 @@ public: static void httpRequestPack(void *obj, Packer *p); + static HttpRequest * CreateFromUrlAndMethod(char * url, method_t method); + + static HttpRequest * CreateFromUrl(char * url); + private: const char *packableURI(bool full_uri) const; diff --git a/src/Makefile.am b/src/Makefile.am index 30f496371b..10c6adf1d3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.139 2006/04/27 19:27:37 wessels Exp $ +# $Id: Makefile.am,v 1.140 2006/05/03 14:04:44 robertc Exp $ # # Uncomment and customize the following to suit your needs: # @@ -97,13 +97,6 @@ else ESI_SOURCE = endif -if USE_ICAP_CLIENT - ICAP_LIBS = ICAP/libicap.a - SUBDIRS += ICAP -else - ICAP_LIBS = -endif - if ENABLE_XPROF_STATS XPROF_STATS_SOURCE = ProfStats.cc else @@ -171,8 +164,8 @@ endif AM_CFLAGS = @SQUID_CFLAGS@ AM_CXXFLAGS = @SQUID_CXXFLAGS@ -EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a -noinst_LIBRARIES = @DISK_LIBS@ +EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a ICAP/libicap.a +noinst_LIBRARIES = @DISK_LIBS@ @ICAP_LIBS@ INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/lib/libTrie/include INCLUDES += @SQUID_CPPUNIT_INC@ @@ -541,6 +534,7 @@ squid_SOURCES = \ structs.h \ SwapDir.cc \ SwapDir.h \ + time.cc \ tools.cc \ typedefs.h \ $(UNLINKDSOURCE) \ @@ -562,6 +556,7 @@ noinst_HEADERS = ACLChecklist.cci \ MemBuf.cci \ MemBuf.h \ Store.cci \ + StoreEntryStream.h \ String.cci \ SquidString.h @@ -584,7 +579,7 @@ squid_LDADD = \ @CRYPTLIB@ \ @REGEXLIB@ \ @SNMPLIB@ \ - ${ICAP_LIBS} \ + @ICAP_LIBS@ \ @LIB_MALLOC@ \ @SSLLIB@ \ -lmiscutil \ @@ -597,7 +592,40 @@ squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a @STORE_OBJS@ @STORE_LINKO @REPL_OBJS@ \ @AUTH_LINKOBJS@ \ @AUTH_OBJS@ \ - ${ICAP_LIBS} + @ICAP_LIBS@ + +ICAP_libicap_a_SOURCES = \ + ICAP/ChunkedCodingParser.cc \ + ICAP/ChunkedCodingParser.h \ + ICAP/ICAPClient.cc \ + ICAP/ICAPClient.h \ + ICAP/ICAPClientReqmodPrecache.cc \ + ICAP/ICAPClientReqmodPrecache.h \ + ICAP/ICAPClientRespmodPrecache.cc \ + ICAP/ICAPClientRespmodPrecache.h \ + ICAP/ICAPConfig.cc \ + ICAP/ICAPConfig.h \ + ICAP/ICAPElements.cc \ + ICAP/ICAPElements.h \ + ICAP/ICAPModXact.cc \ + ICAP/ICAPModXact.h \ + ICAP/ICAPOptions.cc \ + ICAP/ICAPOptions.h \ + ICAP/ICAPOptXact.cc \ + ICAP/ICAPOptXact.h \ + ICAP/ICAPServiceRep.cc \ + ICAP/ICAPServiceRep.h \ + ICAP/ICAPXaction.cc \ + ICAP/ICAPXaction.h \ + ICAP/MsgPipe.cc \ + ICAP/MsgPipe.h \ + ICAP/MsgPipeData.h \ + ICAP/MsgPipeEnd.h \ + ICAP/MsgPipeSink.h \ + ICAP/MsgPipeSource.h \ + ICAP/TextException.cc \ + ICAP/TextException.h + unlinkd_SOURCES = unlinkd.cc SquidNew.cc unlinkd_CXXFLAGS = -DUNLINK_DAEMON @@ -623,27 +651,25 @@ recv_announce_SOURCES = recv-announce.cc SquidNew.cc ## client_db wants SNMP_SOURCE ## snmp_core wants ACLStringData ## SwapDir wants ConfigOption - ufsdump_SOURCES = \ - BodyReader.cc \ - ConfigParser.cc \ debug.cc \ int.cc \ - ufsdump.cc \ - store.cc \ - StoreFileSystem.cc \ + mem.cc \ + store_key_md5.cc \ StoreMeta.cc \ - StoreMeta.h \ StoreMetaMD5.cc \ - StoreMetaMD5.h \ StoreMetaSTD.cc \ - StoreMetaSTD.h \ StoreMetaUnpacker.cc \ - StoreMetaUnpacker.h \ StoreMetaURL.cc \ - StoreMetaURL.h \ StoreMetaVary.cc \ - StoreMetaVary.h \ + String.cc \ + time.cc \ + ufsdump.cc \ + url.cc \ + BodyReader.cc \ + ConfigParser.cc \ + store.cc \ + StoreFileSystem.cc \ StoreSwapLogData.cc \ StoreSwapLogData.h \ access_log.cc \ @@ -660,8 +686,8 @@ ufsdump_SOURCES = \ AuthScheme.cc \ AuthConfig.cc \ cache_cf.cc \ - CacheDigest.cc \ cache_manager.cc \ + CacheDigest.cc \ carp.cc \ cbdata.cc \ client_db.cc \ @@ -727,7 +753,6 @@ ufsdump_SOURCES = \ $(LEAKFINDERSOURCE) \ list.cc \ logfile.cc \ - mem.cc \ mem_node.cc \ mem_node.h \ Mem.h \ @@ -757,7 +782,6 @@ ufsdump_SOURCES = \ SquidNew.cc \ stat.cc \ StatHist.cc \ - String.cc \ stmem.cc \ store_io.cc \ StoreIOBuffer.h \ @@ -766,7 +790,6 @@ ufsdump_SOURCES = \ StoreClient.h \ store_digest.cc \ store_dir.cc \ - store_key_md5.cc \ store_log.cc \ store_rebuild.cc \ store_swapin.cc \ @@ -777,7 +800,6 @@ ufsdump_SOURCES = \ tools.cc \ typedefs.h \ $(UNLINKDSOURCE) \ - url.cc \ urn.cc \ useragent.cc \ wais.cc \ @@ -794,7 +816,7 @@ ufsdump_LDADD = \ @CRYPTLIB@ \ @REGEXLIB@ \ @SNMPLIB@ \ - ${ICAP_LIBS} \ + @ICAP_LIBS@ \ @LIB_MALLOC@ \ @SSLLIB@ \ -lmiscutil \ @@ -1016,7 +1038,9 @@ check_PROGRAMS+= \ tests/testACLMaxUserIP \ tests/testBoilerplate \ tests/testHeaders \ + tests/testHttpRequest \ tests/testStore \ + tests/testString \ @STORE_TESTS@ tests_testAuth_SOURCES= tests/testAuth.cc tests/testMain.cc tests/testAuth.h $(TESTSOURCES) \ @@ -1147,6 +1171,7 @@ HEADERS_TO_TEST = \ tests/testHeader_HttpHeader.cc \ tests/testHeader_HttpHeaderRange.cc \ tests/testHeader_HttpReply.cc \ + tests/testHeader_StoreEntryStream.cc \ tests/testHeader_wordlist.cc tests_testHeaders_SOURCES= tests/testMain.cc $(HEADERS_TO_TEST) tests_testHeaders_LDADD= \ @@ -1157,6 +1182,153 @@ tests_testHeaders_DEPENDENCIES = \ @SQUID_CPPUNIT_LA@ +## Tests of the HttpRequest module. +tests_testHttpRequest_SOURCES = \ + access_log.cc \ + acl.cc \ + acl_noncore.cc \ + ACLChecklist.cc \ + ACLProxyAuth.cc \ + ACLStringData.cc \ + ACLRegexData.cc \ + ACLUserData.cc \ + AuthConfig.cc \ + authenticate.cc \ + AuthUser.cc \ + AuthUserRequest.cc \ + AuthScheme.cc \ + BodyReader.cc \ + cache_manager.cc \ + cache_cf.cc \ + CacheDigest.cc \ + carp.cc \ + cbdata.cc \ + client_db.cc \ + client_side.cc \ + client_side_reply.cc \ + client_side_request.cc \ + clientStream.cc \ + comm.cc \ + comm_select.cc \ + comm_poll.cc \ + comm_epoll.cc \ + comm_kqueue.cc \ + ConfigOption.cc \ + ConfigParser.cc \ + $(DELAY_POOL_SOURCE) \ + debug.cc \ + disk.cc \ + $(DNSSOURCE) \ + event.cc \ + errorpage.cc \ + $(ESI_SOURCE) \ + ETag.cc \ + external_acl.cc \ + ExternalACLEntry.cc \ + fd.cc \ + fde.cc \ + forward.cc \ + fqdncache.cc \ + ftp.cc \ + globals.cc \ + gopher.cc \ + helper.cc \ + htcp.cc \ + http.cc \ + HttpBody.cc \ + HttpHeader.cc \ + HttpHeaderTools.cc \ + HttpHdrCc.cc \ + HttpHdrContRange.cc \ + HttpHdrRange.cc \ + HttpHdrSc.cc \ + HttpHdrScTarget.cc \ + HttpMsg.cc \ + HttpRequest.cc \ + HttpReply.cc \ + HttpStatusLine.cc \ + icmp.cc \ + icp_v2.cc \ + icp_v3.cc \ + $(IDENT_SOURCE) \ + ipc.cc \ + ipcache.cc \ + IPInterception.cc \ + int.cc \ + internal.cc \ + list.cc \ + logfile.cc \ + multicast.cc \ + mem.cc \ + mem_node.cc \ + MemBuf.cc \ + MemObject.cc \ + mime.cc \ + neighbors.cc \ + net_db.cc \ + Packer.cc \ + Parsing.cc \ + pconn.cc \ + peer_digest.cc \ + peer_select.cc \ + redirect.cc \ + refresh.cc \ + Server.cc \ + $(SNMP_SOURCE) \ + $(SSL_SOURCE) \ + stat.cc \ + StatHist.cc \ + stmem.cc \ + store.cc \ + store_client.cc \ + store_digest.cc \ + store_dir.cc \ + store_io.cc \ + store_key_md5.cc \ + store_log.cc \ + store_rebuild.cc \ + store_swapin.cc \ + store_swapmeta.cc \ + store_swapout.cc \ + StoreFileSystem.cc \ + StoreIOState.cc \ + StoreMeta.cc \ + StoreMetaMD5.cc \ + StoreMetaSTD.cc \ + StoreMetaUnpacker.cc \ + StoreMetaURL.cc \ + StoreMetaVary.cc \ + StoreSwapLogData.cc \ + String.cc \ + time.cc \ + tools.cc \ + tunnel.cc \ + SwapDir.cc \ + url.cc \ + urn.cc \ + tests/testHttpRequest.cc \ + tests/testMain.cc \ + wais.cc \ + whois.cc \ + wordlist.cc +nodist_tests_testHttpRequest_SOURCES = \ + repl_modules.cc \ + string_arrays.c +tests_testHttpRequest_LDADD = \ + @REPL_OBJS@ \ + @ICAP_LIBS@ \ + @SSLLIB@ \ + -L../lib -lmiscutil \ + @XTRA_LIBS@ \ + @SQUID_CPPUNIT_LA@ \ + @SNMPLIB@ +tests_testHttpRequest_LDFLAGS = $(LIBADD_DL) +tests_testHttpRequest_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ + @REPL_OBJS@ \ + @SQUID_CPPUNIT_LA@ \ + @ICAP_LIBS@ + + # TODO:mime.cc drags in HttpReply.cc # delay pools need client_side_request.cc STORE_TEST_SOURCES=\ @@ -1200,6 +1372,8 @@ tests_testStore_SOURCES= \ tests/stub_MemObject.cc \ tests/testStore.cc \ tests/testStore.h \ + tests/testStoreEntryStream.cc \ + tests/testStoreEntryStream.h \ tests/testStoreController.cc \ tests/testStoreController.h \ tests/testStoreHashIndex.cc \ @@ -1219,6 +1393,25 @@ tests_testStore_LDFLAGS = $(LIBADD_DL) tests_testStore_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @SQUID_CPPUNIT_LA@ +# string needs mem.cc. mem.cc wants cache_manage +tests_testString_SOURCES= \ + mem.cc \ + String.cc \ + tests/stub_cache_manager.cc \ + tests/testMain.cc \ + tests/testString.cc \ + tests/testString.h \ + $(TESTSOURCES) + +tests_testString_LDADD= \ + -L../lib -lmiscutil \ + @REGEXLIB@ \ + @SQUID_CPPUNIT_LA@ \ + @SSLLIB@ +tests_testString_LDFLAGS = $(LIBADD_DL) +tests_testString_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ + @SQUID_CPPUNIT_LA@ + SWAP_TEST_SOURCES = \ tests/stub_store_rebuild.cc \ tests/stub_internal.cc \ diff --git a/src/Mem.h b/src/Mem.h index ebdc116180..ab234f0446 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -1,6 +1,6 @@ /* - * $Id: Mem.h,v 1.2 2003/02/21 22:50:05 robertc Exp $ + * $Id: Mem.h,v 1.3 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 13 High Level Memory Pool Management * AUTHOR: Harvest Derived @@ -36,6 +36,8 @@ #ifndef SQUID_MEM #define SQUID_MEM +#include + class Mem { @@ -43,8 +45,8 @@ public: static void Init(); static void Stats(StoreEntry *); static void CleanIdlePools(void *unused); - static void Report(StoreEntry *); - static void PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, StoreEntry * e); + static void Report(std::ostream &); + static void PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, std::ostream &); }; #endif /* SQUID_MEM */ diff --git a/src/Packer.h b/src/Packer.h index 023325963a..2d8287d70f 100644 --- a/src/Packer.h +++ b/src/Packer.h @@ -1,6 +1,6 @@ /* - * $Id: Packer.h,v 1.1 2006/04/22 13:08:39 robertc Exp $ + * $Id: Packer.h,v 1.2 2006/05/03 14:04:44 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -36,9 +36,9 @@ #include "config.h" -/* see Packer.c for description */ +/* see Packer.cc for description */ -typedef struct _Packer Packer; +class Packer; /* a common objPackInto interface; used by debugObj */ typedef void (*ObjPackMethod) (void *obj, Packer * p); @@ -52,9 +52,10 @@ typedef void (*vprintf_f) (); #endif - -struct _Packer +class Packer { + +public: /* protected, use interface functions instead */ append_f append; vprintf_f packer_vprintf; diff --git a/src/SquidString.h b/src/SquidString.h index a99f652e21..dd50269c82 100644 --- a/src/SquidString.h +++ b/src/SquidString.h @@ -1,6 +1,6 @@ /* - * $Id: SquidString.h,v 1.6 2005/09/27 20:37:42 wessels Exp $ + * $Id: SquidString.h,v 1.7 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 67 String * AUTHOR: Duane Wessels @@ -131,6 +131,8 @@ private: char *buf_; }; +_SQUID_INLINE_ std::ostream & operator<<(std::ostream& os, String const &aString); + #ifdef _USE_INLINE_ #include "String.cci" #endif diff --git a/src/Store.h b/src/Store.h index 40ccf8dc41..8fbf1f015a 100644 --- a/src/Store.h +++ b/src/Store.h @@ -1,6 +1,6 @@ /* - * $Id: Store.h,v 1.19 2006/04/22 05:29:19 robertc Exp $ + * $Id: Store.h,v 1.20 2006/05/03 14:04:44 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -34,6 +34,10 @@ #ifndef SQUID_STORE_H #define SQUID_STORE_H +#include "squid.h" + +#include + #include "StoreIOBuffer.h" #include "Range.h" #include "RefCount.h" @@ -136,6 +140,19 @@ public: ESIElement::Pointer cachedESITree; #endif + /* append bytes to the buffer */ + virtual void append(char const *, int len); + /* disable sending content to the clients */ + virtual void buffer(); + /* flush any buffered content */ + virtual void flush(); + /* reduce the memory lock count on the entry */ + virtual int unlock(); + /* increate the memory lock count on the entry */ + + virtual void lock() + + ; private: static MemImplementingAllocator *pool; @@ -178,6 +195,7 @@ private: typedef void (*STOREGETCLIENT) (StoreEntry *, void *cbdata); + /* Abstract base class that will replace the whole store and swapdir interface. */ class Store : public RefCountable diff --git a/src/StoreEntryStream.h b/src/StoreEntryStream.h new file mode 100644 index 0000000000..4ee1937a58 --- /dev/null +++ b/src/StoreEntryStream.h @@ -0,0 +1,130 @@ + +/* + * $Id: StoreEntryStream.h,v 1.1 2006/05/03 14:04:44 robertc Exp $ + * + * + * 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 SQUID_STORE_ENTRY_STREAM_H +#define SQUID_STORE_ENTRY_STREAM_H + +#include "Store.h" + +#include + +/* + * This class provides a streambuf interface for writing + * to StoreEntries. Typical use is via a StoreEntryStream + * rather than direct manipulation + */ + +class StoreEntryStreamBuf : public std::streambuf +{ + +public: + StoreEntryStreamBuf(StoreEntry *anEntry) : anEntry(anEntry) + { + + anEntry->lock() + + ; + anEntry->buffer(); + } + + ~StoreEntryStreamBuf() + { + anEntry->unlock(); + } + +protected: + /* flush the current buffer and the character that is overflowing + * to the store entry. + */ + virtual char overflow(char aChar = traits_type::eof()) + { + std::streamsize pending(pptr() - pbase()); + + if (pending && sync ()) + return traits_type::eof(); + + if (aChar != traits_type::eof()) { + char chars[1] = {aChar}; + + if (aChar != traits_type::eof()) + anEntry->append(chars, 1); + } + + pbump (-pending); // Reset pptr(). + return aChar; + } + + /* push the buffer to the store */ + virtual int sync() + { + std::streamsize pending(pptr() - pbase()); + + if (pending) + anEntry->append(pbase(), pending); + + anEntry->flush(); + + return 0; + } + + /* write multiple characters to the store entry + * - this is an optimisation method. + */ + virtual std::streamsize xsputn(const char * chars, std::streamsize number) + { + if (number) + anEntry->append(chars, number); + + return number; + } + +private: + StoreEntry *anEntry; + +}; + +class StoreEntryStream : public std::ostream +{ + +public: + /* create a stream for writing text etc into anEntry */ + StoreEntryStream(StoreEntry *anEntry) : _buffer(anEntry) { this->init(&_buffer);} + +private: + StoreEntryStreamBuf _buffer; + +public: + StoreEntryStreamBuf * rdbuf() const { return const_cast(&_buffer); } +}; + +#endif /* SQUID_STORE_ENTRY_STREAM_H */ diff --git a/src/String.cci b/src/String.cci index 4e6e1d77bc..eda0341537 100644 --- a/src/String.cci +++ b/src/String.cci @@ -1,6 +1,6 @@ /* - * $Id: String.cci,v 1.4 2005/09/27 20:37:42 wessels Exp $ + * $Id: String.cci,v 1.5 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 67 String * AUTHOR: Duane Wessels @@ -73,18 +73,54 @@ String::rpos(char const ch) const int String::cmp (char const *aString) const { + /* strcmp fails on NULLS */ + + if (size() == 0 && (aString == NULL || aString[0] == '\0')) + return 0; + + if (size() == 0) + return -1; + + if (aString == NULL || aString[0] == '\0') + return 1; + return strcmp(buf(), aString); } int String::cmp (char const *aString, size_t count) const { + /* always the same at length 0 */ + + if (count == 0) + return 0; + + if (size() == 0 && (aString == NULL || aString[0] == '\0')) + return 0; + + if (size() == 0) + return -1; + + if (aString == NULL || aString[0] == '\0') + return 1; + return strncmp(buf(), aString, count); } int String::cmp (String const &aString) const { + /* strcmp fails on NULLS */ + + if (size() == 0 && aString.size() == 0) + return 0; + + if (size() == 0) + return -1; + + if (aString.size() == 0) + return 1; + return strcmp(buf(), aString.buf()); } @@ -122,3 +158,11 @@ String::cutPointer (char const *loc) buf_[len_] = '\0'; } +std::ostream & +operator<<(std::ostream& os, String const &aString) +{ + os << aString.buf(); + return os; +} + + diff --git a/src/asn.cc b/src/asn.cc index fc5c338c9e..a781969990 100644 --- a/src/asn.cc +++ b/src/asn.cc @@ -1,6 +1,6 @@ /* - * $Id: asn.cc,v 1.104 2006/04/23 11:10:31 robertc Exp $ + * $Id: asn.cc,v 1.105 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 53 AS Number handling * AUTHOR: Duane Wessels, Kostas Anagnostakis @@ -235,7 +235,7 @@ asnCacheStart(int as) debug(53, 3) ("asnCacheStart: AS %d\n", as); snprintf(asres, 4096, "whois://%s/!gAS%d", Config.as_whois_server, as); asState->as_number = as; - req = urlParse(METHOD_GET, asres); + req = HttpRequest::CreateFromUrl(asres); assert(NULL != req); asState->request = HTTPMSGLOCK(req); diff --git a/src/client_side.cc b/src/client_side.cc index 41b7c1f952..d6bad92349 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.719 2006/04/27 19:27:37 wessels Exp $ + * $Id: client_side.cc,v 1.720 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -2210,7 +2210,7 @@ clientProcessRequest(ConnStateData::Pointer &conn, ClientSocketContext *context, return; } - if ((request = urlParse(method, http->uri)) == NULL) { + if ((request = HttpRequest::CreateFromUrlAndMethod(http->uri, method)) == NULL) { clientStreamNode *node = context->getClientReplyContext(); debug(33, 5) ("Invalid URL: %s\n", http->uri); clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 09e094183a..bb61bf4e21 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side_request.cc,v 1.62 2006/04/27 19:27:37 wessels Exp $ + * $Id: client_side_request.cc,v 1.63 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 85 Client-side Request Routines * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c) @@ -306,7 +306,7 @@ clientBeginRequest(method_t method, char const *url, CSCB * streamcallback, http->uri = (char *)xcalloc(url_sz, 1); strcpy(http->uri, url); - if ((request = urlParse(method, http->uri)) == NULL) { + if ((request = HttpRequest::CreateFromUrlAndMethod(http->uri, method)) == NULL) { debug(85, 5) ("Invalid URL: %s\n", http->uri); return -1; } @@ -847,7 +847,7 @@ ClientRequestContext::clientRedirectDone(char *result) debug(85, 1) ("clientRedirectDone: bad input: %s\n", result); } } else if (strcmp(result, http->uri)) - new_request = urlParse(old_request->method, result); + new_request = HttpRequest::CreateFromUrlAndMethod(result, old_request->method); } if (new_request) { diff --git a/src/htcp.cc b/src/htcp.cc index a56a045d08..c05231782e 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -1,6 +1,6 @@ /* - * $Id: htcp.cc,v 1.62 2006/01/19 18:40:28 wessels Exp $ + * $Id: htcp.cc,v 1.63 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 31 Hypertext Caching Protocol * AUTHOR: Duane Wesssels @@ -806,7 +806,7 @@ htcpSpecifier::checkHit() { method_t m = urlParseMethod(method); char *blk_end; - checkHitRequest = urlParse(m, uri); + checkHitRequest = HttpRequest::CreateFromUrlAndMethod(uri, m); if (NULL == checkHitRequest) { debug(31, 3) ("htcpCheckHit: NO; failed to parse URL\n"); diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 134f0fbfa2..79dbbb21b9 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -1,6 +1,6 @@ /* - * $Id: icp_v2.cc,v 1.91 2006/04/23 11:10:31 robertc Exp $ + * $Id: icp_v2.cc,v 1.92 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 12 Internet Cache Protocol * AUTHOR: Duane Wessels @@ -427,7 +427,7 @@ icpGetRequest(char *url, int reqnum, int fd, struct sockaddr_in * from) HttpRequest *result; - if ((result = urlParse(METHOD_GET, url)) == NULL) + if ((result = HttpRequest::CreateFromUrl(url)) == NULL) icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from); return result; diff --git a/src/mem.cc b/src/mem.cc index 3ce8be4cc0..0669a337b4 100644 --- a/src/mem.cc +++ b/src/mem.cc @@ -1,6 +1,6 @@ /* - * $Id: mem.cc,v 1.92 2006/04/23 11:10:31 robertc Exp $ + * $Id: mem.cc,v 1.93 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 13 High Level Memory Pool Management * AUTHOR: Harvest Derived @@ -34,15 +34,20 @@ */ #include "squid.h" + +#include +#include + #include "Mem.h" #include "memMeter.h" #include "Store.h" +#include "StoreEntryStream.h" #include "MemBuf.h" /* module globals */ /* local prototypes */ -static void memStringStats(StoreEntry * sentry); +static void memStringStats(std::ostream &); /* module locals */ static MemImplementingAllocator *MemPools[MEM_MAX]; @@ -86,54 +91,51 @@ static MemMeter HugeBufVolumeMeter; /* local routines */ static void -memStringStats(StoreEntry * sentry) +memStringStats(std::ostream &stream) { - const char *pfmt = "%-20s\t %d\t %d\n"; int i; int pooled_count = 0; size_t pooled_volume = 0; /* heading */ - storeAppendPrintf(sentry, - "String Pool\t Impact\t\t\n" - " \t (%%strings)\t (%%volume)\n"); + stream << "String Pool\t Impact\t\t\n \t (%%strings)\t (%%volume)\n"; /* table body */ for (i = 0; i < mem_str_pool_count; i++) { const MemAllocator *pool = StrPools[i].pool; const int plevel = pool->getMeter().inuse.level; - storeAppendPrintf(sentry, pfmt, - pool->objectType(), - xpercentInt(plevel, StrCountMeter.level), - xpercentInt(plevel * pool->objectSize(), StrVolumeMeter.level)); + stream << std::setw(20) << std::left << pool->objectType(); + stream << std::right << "\t " << xpercentInt(plevel, StrCountMeter.level); + stream << "\t " << xpercentInt(plevel * pool->objectSize(), StrVolumeMeter.level) << "\n"; pooled_count += plevel; pooled_volume += plevel * pool->objectSize(); } /* malloc strings */ - storeAppendPrintf(sentry, pfmt, - "Other Strings", - xpercentInt(StrCountMeter.level - pooled_count, StrCountMeter.level), - xpercentInt(StrVolumeMeter.level - pooled_volume, StrVolumeMeter.level)); + stream << std::setw(20) << std::left << "Other Strings"; + + stream << std::right << "\t "; - storeAppendPrintf(sentry, "\n"); + stream << xpercentInt(StrCountMeter.level - pooled_count, StrCountMeter.level) << "\t "; + + stream << xpercentInt(StrVolumeMeter.level - pooled_volume, StrVolumeMeter.level) << "\n\n"; } static void -memBufStats(StoreEntry * sentry) +memBufStats(std::ostream & stream) { - storeAppendPrintf(sentry, "Large buffers: %ld (%ld KB)\n", - (long int) HugeBufCountMeter.level, - (long int) HugeBufVolumeMeter.level / 1024); + stream << "Large buffers: " << + HugeBufCountMeter.level << " (" << + HugeBufVolumeMeter.level / 1024 << " KB)\n"; } void Mem::Stats(StoreEntry * sentry) { - storeBuffer(sentry); - Report(sentry); - memStringStats(sentry); - memBufStats(sentry); - storeBufferFlush(sentry); + StoreEntryStream stream(sentry); + Report(stream); + memStringStats(stream); + memBufStats(stream); + stream.flush(); } /* @@ -537,18 +539,21 @@ memFreeBufFunc(size_t size) /* MemPoolMeter */ void -Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, StoreEntry * e) +Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, std::ostream &stream) { int excess = 0; int needed = 0; MemPoolMeter *pm = mp_st->meter; - storeAppendPrintf(e, "%-20s\t %4d\t ", - mp_st->label, mp_st->obj_size); + stream << std::setw(20) << std::left << mp_st->label; + stream << "\t " << std::setw(4) << std::right; + stream << mp_st->obj_size; /* Chunks */ - storeAppendPrintf(e, "%4d\t %4d\t ", - toKB(mp_st->obj_size * mp_st->chunk_capacity), mp_st->chunk_capacity); + stream << "\t " << std::setw(4); + stream << toKB(mp_st->obj_size * mp_st->chunk_capacity); + stream << "\t " << std::setw(4) << mp_st->chunk_capacity; + stream << "\t "; if (mp_st->chunk_capacity) { needed = mp_st->items_inuse / mp_st->chunk_capacity; @@ -559,9 +564,11 @@ Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, Store excess = mp_st->chunks_inuse - needed; } - storeAppendPrintf(e, "%4d\t %4d\t %4d\t %4d\t %.1f\t ", - mp_st->chunks_alloc, mp_st->chunks_inuse, mp_st->chunks_free, mp_st->chunks_partial, - xpercent(excess, needed)); + stream << std::setw(4) << mp_st->chunks_alloc << "\t "; + stream << std::setw(4) << mp_st->chunks_inuse << "\t "; + stream << std::setw(4) << mp_st->chunks_free << "\t "; + stream << std::setw(4) << mp_st->chunks_partial << "\t "; + stream << std::setprecision(1) << xpercent(excess, needed) << "\t "; /* * Fragmentation calculation: * needed = inuse.level / chunk_capacity @@ -570,33 +577,26 @@ Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, Store * * Fragm = (alloced - (inuse / obj_ch) ) / alloced */ - - storeAppendPrintf(e, - "%d\t %ld\t %ld\t %.2f\t %.1f\t" /* alloc */ - "%d\t %ld\t %ld\t %.2f\t %.1f\t" /* in use */ - "%d\t %ld\t %ld\t" /* idle */ - "%.0f\t %.1f\t %.1f\t %.1f\n", /* saved */ - /* alloc */ - mp_st->items_alloc, - (long) toKB(mp_st->obj_size * pm->alloc.level), - (long) toKB(mp_st->obj_size * pm->alloc.hwater_level), - (double) ((squid_curtime - pm->alloc.hwater_stamp) / 3600.), - xpercent(mp_st->obj_size * pm->alloc.level, AllMeter->alloc.level), - /* in use */ - mp_st->items_inuse, - (long) toKB(mp_st->obj_size * pm->inuse.level), - (long) toKB(mp_st->obj_size * pm->inuse.hwater_level), - (double) ((squid_curtime - pm->inuse.hwater_stamp) / 3600.), - xpercent(pm->inuse.level, pm->alloc.level), - /* idle */ - mp_st->items_idle, - (long) toKB(mp_st->obj_size * pm->idle.level), - (long) toKB(mp_st->obj_size * pm->idle.hwater_level), - /* saved */ - pm->gb_saved.count, - xpercent(pm->gb_saved.count, AllMeter->gb_saved.count), - xpercent(pm->gb_saved.bytes, AllMeter->gb_saved.bytes), - xdiv(pm->gb_saved.count - pm->gb_osaved.count, xm_deltat)); + /* allocated */ + stream << mp_st->items_alloc << "\t "; + stream << toKB(mp_st->obj_size * pm->alloc.level) << "\t "; + stream << toKB(mp_st->obj_size * pm->alloc.hwater_level) << "\t "; + stream << std::setprecision(2) << ((squid_curtime - pm->alloc.hwater_stamp) / 3600.); + stream << "\t " << std::setprecision(1) << xpercent(mp_st->obj_size * pm->alloc.level, AllMeter->alloc.level); + /* in use */ + stream << "\t" << mp_st->items_inuse << "\t "; + stream << toKB(mp_st->obj_size * pm->inuse.level) << "\t "; + stream << toKB(mp_st->obj_size * pm->inuse.hwater_level) << "\t "; + stream << std::setprecision(2) << ((squid_curtime - pm->inuse.hwater_stamp) / 3600.); + stream << "\t " << std::setprecision(1) << xpercent(pm->inuse.level, pm->alloc.level); + /* idle */ + stream << "\t" << mp_st->items_idle << "\t " << toKB(mp_st->obj_size * pm->idle.level); + stream << "\t " << toKB(mp_st->obj_size * pm->idle.hwater_level) << "\t"; + /* saved */ + stream << std::setprecision(0) << pm->gb_saved.count << "\t "; + stream << std::setprecision(1) << xpercent(pm->gb_saved.count, AllMeter->gb_saved.count); + stream << "\t " << xpercent(pm->gb_saved.bytes, AllMeter->gb_saved.bytes) << "\t "; + stream << xdiv(pm->gb_saved.count - pm->gb_osaved.count, xm_deltat) << "\n"; pm->gb_osaved.count = pm->gb_saved.count; } @@ -632,7 +632,7 @@ MemPoolReportSorter(const void *a, const void *b) } void -Mem::Report(StoreEntry * e) +Mem::Report(std::ostream &stream) { static char buf[64]; static MemPoolStats mp_stats; @@ -642,26 +642,25 @@ Mem::Report(StoreEntry * e) MemAllocator *pool; /* caption */ - storeAppendPrintf(e, "Current memory usage:\n"); + stream << "Current memory usage:\n"; /* heading */ - storeAppendPrintf(e, - "Pool\t Obj Size\t" - "Chunks\t\t\t\t\t\t\t" - "Allocated\t\t\t\t\t" - "In Use\t\t\t\t\t" - "Idle\t\t\t" - "Allocations Saved\t\t\t" - "Hit Rate\t" - "\n" - " \t (bytes)\t" - "KB/ch\t obj/ch\t" - "(#)\t used\t free\t part\t %%Frag\t " - "(#)\t (KB)\t high (KB)\t high (hrs)\t %%Tot\t" - "(#)\t (KB)\t high (KB)\t high (hrs)\t %%alloc\t" - "(#)\t (KB)\t high (KB)\t" - "(#)\t %%cnt\t %%vol\t" - "(#) / sec\t" - "\n"); + stream << "Pool\t Obj Size\t" + "Chunks\t\t\t\t\t\t\t" + "Allocated\t\t\t\t\t" + "In Use\t\t\t\t\t" + "Idle\t\t\t" + "Allocations Saved\t\t\t" + "Hit Rate\t" + "\n" + " \t (bytes)\t" + "KB/ch\t obj/ch\t" + "(#)\t used\t free\t part\t %%Frag\t " + "(#)\t (KB)\t high (KB)\t high (hrs)\t %%Tot\t" + "(#)\t (KB)\t high (KB)\t high (hrs)\t %%alloc\t" + "(#)\t (KB)\t high (KB)\t" + "(#)\t %%cnt\t %%vol\t" + "(#) / sec\t" + "\n"; xm_deltat = current_dtime - xm_time; xm_time = current_dtime; @@ -691,7 +690,7 @@ Mem::Report(StoreEntry * e) qsort(sortme, npools, sizeof(*sortme), MemPoolReportSorter); for (int i = 0; i< npools; i++) { - PoolReport(&sortme[i], mp_total.TheMeter, e); + PoolReport(&sortme[i], mp_total.TheMeter, stream); } xfree(sortme); @@ -711,17 +710,17 @@ Mem::Report(StoreEntry * e) mp_stats.items_idle = mp_total.tot_items_idle; mp_stats.overhead = mp_total.tot_overhead; - PoolReport(&mp_stats, mp_total.TheMeter, e); + PoolReport(&mp_stats, mp_total.TheMeter, stream); /* Cumulative */ - storeAppendPrintf(e, "Cumulative allocated volume: %s\n", double_to_str(buf, 64, mp_total.TheMeter->gb_saved.bytes)); + stream << "Cumulative allocated volume: "<< double_to_str(buf, 64, mp_total.TheMeter->gb_saved.bytes) << "\n"; /* overhead */ - storeAppendPrintf(e, "Current overhead: %d bytes (%.3f%%)\n", - mp_total.tot_overhead, xpercent(mp_total.tot_overhead, mp_total.TheMeter->inuse.level)); + stream << "Current overhead: " << mp_total.tot_overhead << " bytes (" << + std::setprecision(3) << xpercent(mp_total.tot_overhead, mp_total.TheMeter->inuse.level) << "%%)\n"; /* limits */ - storeAppendPrintf(e, "Idle pool limit: %.2f MB\n", toMB(mp_total.mem_idle_limit)); + stream << "Idle pool limit: " << std::setprecision(2) << toMB(mp_total.mem_idle_limit) << " MB\n"; /* limits */ - storeAppendPrintf(e, "Total Pools created: %d\n", mp_total.tot_pools_alloc); - storeAppendPrintf(e, "Pools ever used: %d (shown above)\n", mp_total.tot_pools_alloc - not_used); - storeAppendPrintf(e, "Currently in use: %d\n", mp_total.tot_pools_inuse); + stream << "Total Pools created: " << mp_total.tot_pools_alloc << "\n"; + stream << "Pools ever used: " << mp_total.tot_pools_alloc - not_used << " (shown above)\n"; + stream << "Currently in use: " << mp_total.tot_pools_inuse << "\n"; } diff --git a/src/mime.cc b/src/mime.cc index b9aee8ffa4..105ad3469d 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -1,6 +1,6 @@ /* - * $Id: mime.cc,v 1.124 2006/04/22 06:03:42 robertc Exp $ + * $Id: mime.cc,v 1.125 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 25 MIME Parsing * AUTHOR: Harvest Derived @@ -571,7 +571,7 @@ MimeIcon::created (StoreEntry *newEntry) EBIT_SET(e->flags, ENTRY_SPECIAL); storeSetPublicKey(e); storeBuffer(e); - HttpRequest *r = urlParse(METHOD_GET, url); + HttpRequest *r = HttpRequest::CreateFromUrl(url); if (NULL == r) fatal("mimeLoadIcon: cannot parse internal URL"); diff --git a/src/neighbors.cc b/src/neighbors.cc index 50e5f51140..12aab5eb5d 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,6 +1,6 @@ /* - * $Id: neighbors.cc,v 1.333 2006/02/17 18:10:59 wessels Exp $ + * $Id: neighbors.cc,v 1.334 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 15 Neighbor Routines * AUTHOR: Harvest Derived @@ -1479,7 +1479,7 @@ peerCountMcastPeersStart(void *data) p->mcast.flags.count_event_pending = 0; snprintf(url, MAX_URL, "http://%s/", inet_ntoa(p->in_addr.sin_addr)); fake = storeCreateEntry(url, url, request_flags(), METHOD_GET); - HttpRequest *req = urlParse(METHOD_GET, url); + HttpRequest *req = HttpRequest::CreateFromUrl(url); psstate = new ps_state; psstate->request = HTTPMSGLOCK(req); psstate->entry = fake; diff --git a/src/net_db.cc b/src/net_db.cc index fd4177c292..89386f8138 100644 --- a/src/net_db.cc +++ b/src/net_db.cc @@ -1,6 +1,6 @@ /* - * $Id: net_db.cc,v 1.185 2006/04/23 11:10:31 robertc Exp $ + * $Id: net_db.cc,v 1.186 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 38 Network Measurement Database * AUTHOR: Duane Wessels @@ -1297,7 +1297,7 @@ netdbExchangeStart(void *data) uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", "netdb"); debug(38, 3) ("netdbExchangeStart: Requesting '%s'\n", uri); assert(NULL != uri); - ex->r = urlParse(METHOD_GET, uri); + ex->r = HttpRequest::CreateFromUrl(uri); if (NULL == ex->r) { debug(38, 1) ("netdbExchangeStart: Bad URI %s\n", uri); diff --git a/src/peer_digest.cc b/src/peer_digest.cc index 56186f391d..f9bf188d83 100644 --- a/src/peer_digest.cc +++ b/src/peer_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: peer_digest.cc,v 1.110 2006/04/18 12:28:40 robertc Exp $ + * $Id: peer_digest.cc,v 1.111 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 72 Peer Digest Routines * AUTHOR: Alex Rousskov @@ -314,7 +314,7 @@ peerDigestRequest(PeerDigest * pd) url = internalRemoteUri(p->host, p->http_port, "/squid-internal-periodic/", StoreDigestFileName); - req = urlParse(METHOD_GET, url); + req = HttpRequest::CreateFromUrl(url); assert(req); diff --git a/src/store.cc b/src/store.cc index 77236210d8..5ddad5692e 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $Id: store.cc,v 1.586 2006/04/22 05:29:20 robertc Exp $ + * $Id: store.cc,v 1.587 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 20 Storage Manager * AUTHOR: Harvest Derived @@ -52,7 +52,7 @@ static STMCB storeWriteComplete; #define REBUILD_TIMESTAMP_DELTA_MAX 2 -#define STORE_IN_MEM_BUCKETS (229) +#define STORE_IN_MEM_BUCKETS (229) const char *memStatusStr[] = { @@ -454,6 +454,16 @@ storePurgeMem(StoreEntry * e) storeRelease(e); } +/* DEPRECATED: please use e->lock(); */ +void +storeLockObject(StoreEntry * e) +{ + + e->lock() + + ; +} + /* RBC 20050104 this is wrong- memory ref counting * is not at all equivalent to the store 'usage' concept * which the replacement policies should be acting upon. @@ -462,13 +472,14 @@ storePurgeMem(StoreEntry * e) * but this should not influence store replacement. */ void -storeLockObject(StoreEntry * e) + +StoreEntry::lock() { - e->lock_count++; - debug(20, 3) ("storeLockObject: key '%s' count=%d\n", - e->getMD5Text(), (int) e->lock_count); - e->lastref = squid_curtime; - Store::Root().reference(*e); + lock_count++; + debugs(20, 3, "storeLockObject: key '" << getMD5Text() <<"' count=" << + lock_count << "\n"); + lastref = squid_curtime; + Store::Root().reference(*this); } void @@ -500,37 +511,44 @@ storeReleaseRequest(StoreEntry * e) storeSetPrivateKey(e); } +/* DEPRECATED: please use e->unlock() */ +int +storeUnlockObject(StoreEntry * e) +{ + return e->unlock(); +} + /* unlock object, return -1 if object get released after unlock * otherwise lock_count */ int -storeUnlockObject(StoreEntry * e) +StoreEntry::unlock() { - e->lock_count--; + lock_count--; debug(20, 3) ("storeUnlockObject: key '%s' count=%d\n", - e->getMD5Text(), e->lock_count); + getMD5Text(), lock_count); - if (e->lock_count) - return (int) e->lock_count; + if (lock_count) + return (int) lock_count; - if (e->store_status == STORE_PENDING) - e->setReleaseFlag(); + if (store_status == STORE_PENDING) + setReleaseFlag(); - assert(storePendingNClients(e) == 0); + assert(storePendingNClients(this) == 0); - if (EBIT_TEST(e->flags, RELEASE_REQUEST)) - storeRelease(e); - else if (storeKeepInMemory(e)) { - Store::Root().dereference(*e); - storeSetMemStatus(e, IN_MEMORY); - e->mem_obj->unlinkRequest(); + if (EBIT_TEST(flags, RELEASE_REQUEST)) + storeRelease(this); + else if (storeKeepInMemory(this)) { + Store::Root().dereference(*this); + storeSetMemStatus(this, IN_MEMORY); + mem_obj->unlinkRequest(); } else { - Store::Root().dereference(*e); + Store::Root().dereference(*this); - if (EBIT_TEST(e->flags, KEY_PRIVATE)) + if (EBIT_TEST(flags, KEY_PRIVATE)) debug(20, 1) ("WARNING: %s:%d: found KEY_PRIVATE\n", __FILE__, __LINE__); /* storePurgeMem may free e */ - storePurgeMem(e); + storePurgeMem(this); } return 0; @@ -623,7 +641,7 @@ storeSetPrivateKey(StoreEntry * e) MemObject *mem = e->mem_obj; if (e->key && EBIT_TEST(e->flags, KEY_PRIVATE)) - return; /* is already private */ + return; /* is already private */ if (e->key) { if (e->swap_filen > -1) @@ -652,7 +670,7 @@ storeSetPublicKey(StoreEntry * e) MemObject *mem = e->mem_obj; if (e->key && !EBIT_TEST(e->flags, KEY_PRIVATE)) - return; /* is already public */ + return; /* is already public */ assert(mem); @@ -688,7 +706,7 @@ storeSetPublicKey(StoreEntry * e) /* Oops.. the variance has changed. Kill the base object * to record the new variance key */ - safe_free(request->vary_headers); /* free old "bad" variance key */ + safe_free(request->vary_headers); /* free old "bad" variance key */ pe = storeGetPublic(mem->url, mem->method); if (pe) @@ -710,7 +728,7 @@ storeSetPublicKey(StoreEntry * e) pe = storeCreateEntry(mem->url, mem->log_url, request->flags, request->method); HttpVersion version(1, 0); /* We are allowed to do this typecast */ - HttpReply *rep = (HttpReply *) pe->getReply(); // bypass const + HttpReply *rep = (HttpReply *) pe->getReply(); // bypass const rep->setHeaders(version, HTTP_OK, "Internal marker object", "x-squid-internal/vary", -1, -1, squid_curtime + 100000); vary = httpHeaderGetList(&mem->getReply()->header, HDR_VARY); @@ -782,7 +800,7 @@ storeCreateEntry(const char *url, const char *log_url, request_flags flags, meth debug(20, 3) ("storeCreateEntry: '%s'\n", url); e = new StoreEntry(url, log_url); - e->lock_count = 1; /* Note lock here w/o calling storeLock() */ + e->lock_count = 1; /* Note lock here w/o calling storeLock() */ mem = e->mem_obj; mem->method = method; @@ -806,7 +824,7 @@ storeCreateEntry(const char *url, const char *log_url, request_flags flags, meth e->swap_dirn = -1; e->refcount = 0; e->lastref = squid_curtime; - e->timestamp = -1; /* set in storeTimestampsSet() */ + e->timestamp = -1; /* set in storeTimestampsSet() */ e->ping_status = PING_NONE; EBIT_SET(e->flags, ENTRY_VALIDATED); return e; @@ -858,14 +876,20 @@ StoreEntry::write (StoreIOBuffer writeBuffer) PROF_stop(StoreEntry_write); } -/* Append incoming data from a primary server to an entry. */ +/* Legacy call for appending data to a store entry */ void storeAppend(StoreEntry * e, const char *buf, int len) { - MemObject *mem = e->mem_obj; - assert(mem != NULL); + e->append(buf, len); +} + +/* Append incoming data from a primary server to an entry. */ +void +StoreEntry::append(char const *buf, int len) +{ + assert(mem_obj != NULL); assert(len >= 0); - assert(e->store_status == STORE_PENDING); + assert(store_status == STORE_PENDING); StoreIOBuffer tempBuffer; tempBuffer.data = (char *)buf; @@ -874,10 +898,11 @@ storeAppend(StoreEntry * e, const char *buf, int len) * XXX sigh, offset might be < 0 here, but it gets "corrected" * later. This offset crap is such a mess. */ - tempBuffer.offset = mem->endOffset() - (e->getReply() ? e->getReply()->hdr_sz : 0); - e->write(tempBuffer); + tempBuffer.offset = mem_obj->endOffset() - (getReply() ? getReply()->hdr_sz : 0); + write(tempBuffer); } + void #if STDC_HEADERS storeAppendPrintf(StoreEntry * e, const char *fmt,...) @@ -993,7 +1018,7 @@ storeCheckCachable(StoreEntry * e) } else if (EBIT_TEST(e->flags, ENTRY_NEGCACHED)) { debug(20, 3) ("storeCheckCachable: NO: negative cached\n"); store_check_cachable_hist.no.negative_cached++; - return 0; /* avoid release call below */ + return 0; /* avoid release call below */ } else if ((e->getReply()->content_length > 0 && static_cast(e->getReply()->content_length) > Config.Store.maxObjectSize) || @@ -1124,7 +1149,7 @@ storeAbort(StoreEntry * e) assert(e->store_status == STORE_PENDING); assert(mem != NULL); debug(20, 6) ("storeAbort: %s\n", e->getMD5Text()); - storeLockObject(e); /* lock while aborting */ + storeLockObject(e); /* lock while aborting */ storeNegativeCache(e); storeReleaseRequest(e); EBIT_SET(e->flags, ENTRY_ABORTED); @@ -1160,7 +1185,7 @@ storeAbort(StoreEntry * e) /* Close any swapout file */ storeSwapOutFileClose(e); - storeUnlockObject(e); /* unlock */ + storeUnlockObject(e); /* unlock */ } /* Clear Memory storage to accommodate the given object len */ @@ -1226,8 +1251,8 @@ Store::Maintain(void *notused) } /* The maximum objects to scan for maintain storage space */ -#define MAINTAIN_MAX_SCAN 1024 -#define MAINTAIN_MAX_REMOVE 64 +#define MAINTAIN_MAX_SCAN 1024 +#define MAINTAIN_MAX_REMOVE 64 /* * This routine is to be called by main loop in main.c. @@ -1507,7 +1532,7 @@ storeFreeMemory(void) int expiresMoreThan(time_t expires, time_t when) { - if (expires < 0) /* No Expires given */ + if (expires < 0) /* No Expires given */ return 1; return (expires > (squid_curtime + when)); @@ -1667,20 +1692,33 @@ storeCreateMemObject(StoreEntry * e, const char *url, const char *log_url) e->mem_obj = new MemObject(url, log_url); } -/* this just sets DELAY_SENDING */ +/* DEPRECATED: please use entry->buffer() */ void storeBuffer(StoreEntry * e) { - EBIT_SET(e->flags, DELAY_SENDING); + e->buffer(); +} + +/* this just sets DELAY_SENDING */ +void +StoreEntry::buffer() +{ + EBIT_SET(flags, DELAY_SENDING); +} + +/* DEPRECATED - please use e->flush(); */ +void storeBufferFlush(StoreEntry * e) +{ + e->flush(); } /* this just clears DELAY_SENDING and Invokes the handlers */ void -storeBufferFlush(StoreEntry * e) +StoreEntry::flush() { - if (EBIT_TEST(e->flags, DELAY_SENDING)) { - EBIT_CLR(e->flags, DELAY_SENDING); - InvokeHandlers(e); + if (EBIT_TEST(flags, DELAY_SENDING)) { + EBIT_CLR(flags, DELAY_SENDING); + InvokeHandlers(this); } } @@ -1716,7 +1754,7 @@ storeEntryReset(StoreEntry * e) assert (mem); debug(20, 3) ("storeEntryReset: %s\n", storeUrl(e)); mem->reset(); - HttpReply *rep = (HttpReply *) e->getReply(); // bypass const + HttpReply *rep = (HttpReply *) e->getReply(); // bypass const rep->reset(); e->expires = e->lastmod = e->timestamp = -1; } @@ -1774,7 +1812,7 @@ createRemovalPolicy(RemovalPolicySettings * settings) debug(20, 1) ("ERROR: Be sure to have set cache_replacement_policy\n"); debug(20, 1) ("ERROR: and memory_replacement_policy in squid.conf!\n"); fatalf("ERROR: Unknown policy %s\n", settings->type); - return NULL; /* NOTREACHED */ + return NULL; /* NOTREACHED */ } #if 0 diff --git a/src/store_digest.cc b/src/store_digest.cc index f340fc28e9..a30f6d59cb 100644 --- a/src/store_digest.cc +++ b/src/store_digest.cc @@ -1,6 +1,6 @@ /* - * $Id: store_digest.cc,v 1.63 2006/02/17 20:15:35 wessels Exp $ + * $Id: store_digest.cc,v 1.64 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 71 Store Digest Manager * AUTHOR: Alex Rousskov @@ -398,7 +398,7 @@ storeDigestRewriteStart(void *datanotused) sd_state.rewrite_lock = cbdataAlloc(generic_cbdata); sd_state.rewrite_lock->data = e; debug(71, 3) ("storeDigestRewrite: url: %s key: %s\n", url, e->getMD5Text()); - HttpRequest *req = urlParse(METHOD_GET, url); + HttpRequest *req = HttpRequest::CreateFromUrl(url); e->mem_obj->request = HTTPMSGLOCK(req); /* wait for rebuild (if any) to finish */ diff --git a/src/store_key_md5.cc b/src/store_key_md5.cc index c409d3302f..49773ae1a9 100644 --- a/src/store_key_md5.cc +++ b/src/store_key_md5.cc @@ -1,6 +1,6 @@ /* - * $Id: store_key_md5.cc,v 1.31 2003/08/10 11:00:44 robertc Exp $ + * $Id: store_key_md5.cc,v 1.32 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 20 Storage Manager MD5 Cache Keys * AUTHOR: Duane Wessels @@ -104,8 +104,7 @@ storeKeyPrivate(const char *url, method_t method, int id) static cache_key digest[MD5_DIGEST_CHARS]; MD5_CTX M; assert(id > 0); - debug(20, 3) ("storeKeyPrivate: %s %s\n", - RequestMethodStr[method], url); + debugs(20, 3, "storeKeyPrivate: " << RequestMethodStr[method] << url); MD5Init(&M); MD5Update(&M, (unsigned char *) &id, sizeof(id)); MD5Update(&M, (unsigned char *) &method, sizeof(method)); diff --git a/src/tests/testHeader_StoreEntryStream.cc b/src/tests/testHeader_StoreEntryStream.cc new file mode 100644 index 0000000000..5ca8f5174e --- /dev/null +++ b/src/tests/testHeader_StoreEntryStream.cc @@ -0,0 +1,4 @@ +/* This test tests that the header below can be processed on its own with + * no other #includes. Dont add any! + */ +#include "StoreEntryStream.h" diff --git a/src/tests/testHttpRequest.cc b/src/tests/testHttpRequest.cc new file mode 100644 index 0000000000..d32dbc95a5 --- /dev/null +++ b/src/tests/testHttpRequest.cc @@ -0,0 +1,92 @@ +#include "squid.h" +#include + +#include "Mem.h" +#include "testHttpRequest.h" +#include "HttpRequest.h" + + +CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest ); + +/* stub functions to link successfully */ +void +shut_down(int) +{} + +/* end stubs */ + +/* init memory pools */ + +struct Initer +{ + Initer() {Mem::Init();} +}; + +static Initer ensure_mempools; + +/* + * Test creating an HttpRequest object from a Url and method + */ +void +testHttpRequest::testCreateFromUrlAndMethod() +{ + /* vanilla url */ + ushort expected_port; + char * url = xstrdup("http://foo:90/bar"); + HttpRequest *aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET); + expected_port = 90; + HttpRequest *nullRequest = NULL; + CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port); + CPPUNIT_ASSERT_EQUAL(METHOD_GET, aRequest->method); + CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->host)); + CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath); + CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol); + CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url)); + xfree(url); + /* vanilla url, different method */ + url = xstrdup("http://foo/bar"); + aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_PUT); + expected_port = 80; + CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port); + CPPUNIT_ASSERT_EQUAL(METHOD_PUT, aRequest->method); + CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->host)); + CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath); + CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol); + CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url)); + /* a connect url with non-CONNECT data */ + url = xstrdup(":foo/bar"); + aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT); + xfree(url); + CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest); + /* a CONNECT url with CONNECT data */ + url = xstrdup("foo:45"); + aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT); + expected_port = 45; + CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port); + CPPUNIT_ASSERT_EQUAL(METHOD_CONNECT, aRequest->method); + CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->host)); + CPPUNIT_ASSERT_EQUAL(String(""), aRequest->urlpath); + CPPUNIT_ASSERT_EQUAL(PROTO_NONE, aRequest->protocol); + CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url)); + xfree(url); +} + +/* + * Test creating an HttpRequest object from a Url alone. + */ +void +testHttpRequest::testCreateFromUrl() +{ + /* vanilla url */ + ushort expected_port; + char * url = xstrdup("http://foo:90/bar"); + HttpRequest *aRequest = HttpRequest::CreateFromUrl(url); + expected_port = 90; + CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port); + CPPUNIT_ASSERT_EQUAL(METHOD_GET, aRequest->method); + CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->host)); + CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath); + CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol); + CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url)); + xfree(url); +} diff --git a/src/tests/testHttpRequest.h b/src/tests/testHttpRequest.h new file mode 100644 index 0000000000..a173a4c1f8 --- /dev/null +++ b/src/tests/testHttpRequest.h @@ -0,0 +1,26 @@ + +#ifndef SQUID_SRC_TEST_HTTP_REQUEST_H +#define SQUID_SRC_TEST_HTTP_REQUEST_H + +#include + +/* + * test HttpRequest + */ + +class testHttpRequest : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testHttpRequest ); + CPPUNIT_TEST( testCreateFromUrlAndMethod ); + CPPUNIT_TEST( testCreateFromUrl ); + CPPUNIT_TEST_SUITE_END(); + +public: + +protected: + void testCreateFromUrlAndMethod(); + void testCreateFromUrl(); +}; + +#endif + diff --git a/src/tests/testStore.cc b/src/tests/testStore.cc index 59c8de730f..71d6781ccd 100644 --- a/src/tests/testStore.cc +++ b/src/tests/testStore.cc @@ -4,47 +4,6 @@ CPPUNIT_TEST_SUITE_REGISTRATION( testStore ); -/* subclass of Store to allow testing of methods without having all the - * other components live - */ - -class TestStore : public Store -{ - -public: - TestStore() : statsCalled (false) {} - - bool statsCalled; - - virtual int callback(); - - virtual StoreEntry* get - (const cache_key*); - - virtual void get - (String, void (*)(StoreEntry*, void*), void*); - - virtual void init(); - -virtual void maintain() {}; - - virtual size_t maxSize() const; - - virtual size_t minSize() const; - - virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */ - - virtual void reference(StoreEntry &){} /* Reference this object */ - - virtual void dereference(StoreEntry &){} /* Unreference this object */ - - virtual void updateSize(size_t size, int sign) {} - - virtual StoreSearch *search(String const url, HttpRequest *); -}; - -typedef RefCount TestStorePointer; - int TestStore::callback() { diff --git a/src/tests/testStore.h b/src/tests/testStore.h index dcf4a38d60..b148f60b3f 100644 --- a/src/tests/testStore.h +++ b/src/tests/testStore.h @@ -2,8 +2,12 @@ #ifndef SQUID_SRC_TEST_STORE_H #define SQUID_SRC_TEST_STORE_H +#include "squid.h" +#include "Store.h" + #include + /* * test the store framework */ @@ -26,5 +30,48 @@ protected: void testMaxSize(); }; + +/* subclass of Store to allow testing of methods without having all the + * other components live + */ + +class TestStore : public Store +{ + +public: + TestStore() : statsCalled (false) {} + + bool statsCalled; + + virtual int callback(); + + virtual StoreEntry* get + (const cache_key*); + + virtual void get + (String, void (*)(StoreEntry*, void*), void*); + + virtual void init(); + +virtual void maintain() {}; + + virtual size_t maxSize() const; + + virtual size_t minSize() const; + + virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */ + + virtual void reference(StoreEntry &){} /* Reference this object */ + + virtual void dereference(StoreEntry &){} /* Unreference this object */ + + virtual void updateSize(size_t size, int sign) {} + + virtual StoreSearch *search(String const url, HttpRequest *); +}; + +typedef RefCount TestStorePointer; + + #endif diff --git a/src/tests/testStoreEntryStream.cc b/src/tests/testStoreEntryStream.cc new file mode 100644 index 0000000000..b8f458b39e --- /dev/null +++ b/src/tests/testStoreEntryStream.cc @@ -0,0 +1,80 @@ +#include "squid.h" +#include "Mem.h" +#include "testStore.h" +#include "testStoreEntryStream.h" +#include "Store.h" +#include "StoreEntryStream.h" + +#include + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION( testStoreEntryStream ); + +/* class that captures various call data for test analysis */ + +class CapturingStoreEntry : public StoreEntry +{ + +public: + MEMPROXY_CLASS(CapturingStoreEntry); + + CapturingStoreEntry() : _buffer_calls(0), _flush_calls(0) {} + + String _appended_text; + int _buffer_calls; + int _flush_calls; + + virtual void buffer() + { + _buffer_calls += 1; + } + + virtual void flush() + { + _flush_calls += 1; + } + + virtual void append(char const * buf, int len) + { + _appended_text.append(buf, len); + } +}; + +MEMPROXY_CLASS_INLINE(CapturingStoreEntry); + + +/* init memory pools */ + +struct Initer +{ + Initer() {Mem::Init();} +}; + +static Initer ensure_mempools; + +void +testStoreEntryStream::testGetStream() +{ + /* Setup a store root so we can create a StoreEntry */ + StorePointer aStore (new TestStore); + Store::Root(aStore); + + CapturingStoreEntry * anEntry = new CapturingStoreEntry(); + { + StoreEntryStream stream(anEntry); + CPPUNIT_ASSERT_EQUAL(1, anEntry->_buffer_calls); + CPPUNIT_ASSERT_EQUAL(0, anEntry->_flush_calls); + stream << "some text" << std::setw(4) << "!"; + CPPUNIT_ASSERT_EQUAL(1, anEntry->_buffer_calls); + CPPUNIT_ASSERT_EQUAL(0, anEntry->_flush_calls); + stream.flush(); + CPPUNIT_ASSERT_EQUAL(1, anEntry->_buffer_calls); + CPPUNIT_ASSERT_EQUAL(1, anEntry->_flush_calls); + CPPUNIT_ASSERT_EQUAL(String("some text !"), anEntry->_appended_text); + } + + delete anEntry; + + Store::Root(NULL); +} diff --git a/src/tests/testStoreEntryStream.h b/src/tests/testStoreEntryStream.h new file mode 100644 index 0000000000..0985d99b5a --- /dev/null +++ b/src/tests/testStoreEntryStream.h @@ -0,0 +1,24 @@ + +#ifndef SQUID_SRC_TEST_STORE_ENTRY_STREAM_H +#define SQUID_SRC_TEST_STORE_ENTRY_STREAM_H + +#include + +/* + * test StoreEntryStream + */ + +class testStoreEntryStream : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testStoreEntryStream ); + CPPUNIT_TEST( testGetStream ); + CPPUNIT_TEST_SUITE_END(); + +public: + +protected: + void testGetStream(); +}; + +#endif + diff --git a/src/tests/testString.cc b/src/tests/testString.cc new file mode 100644 index 0000000000..0f63e26cac --- /dev/null +++ b/src/tests/testString.cc @@ -0,0 +1,60 @@ +#include "squid.h" +#include "Mem.h" +#include "SquidString.h" +#include "testString.h" + +CPPUNIT_TEST_SUITE_REGISTRATION( testString ); + +/* let this test link sanely */ +void +eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata) +{} + +/* init memory pools */ + +struct Initer +{ + Initer() {Mem::Init();} +}; + +static Initer ensure_mempools; + +void +testString::testCmpDefault() +{ + String left, right; + /* two default strings are equal */ + CPPUNIT_ASSERT(!left.cmp(right)); + CPPUNIT_ASSERT(!left.cmp(NULL)); + CPPUNIT_ASSERT(!left.cmp(NULL, 1)); +} + +void +testString::testCmpEmptyString() +{ + String left(""); + String right; + /* an empty string ("") is equal to a default string */ + CPPUNIT_ASSERT(!left.cmp(right)); + CPPUNIT_ASSERT(!left.cmp(NULL)); + CPPUNIT_ASSERT(!left.cmp(NULL, 1)); + /* reverse the order to catch corners */ + CPPUNIT_ASSERT(!right.cmp(left)); + CPPUNIT_ASSERT(!right.cmp("")); + CPPUNIT_ASSERT(!right.cmp("", 1)); +} + +void +testString::testCmpNotEmptyDefault() +{ + String left("foo"); + String right; + /* empty string sorts before everything */ + CPPUNIT_ASSERT(left.cmp(right) > 0); + CPPUNIT_ASSERT(left.cmp(NULL) > 0); + CPPUNIT_ASSERT(left.cmp(NULL, 1) > 0); + /* reverse for symmetry tests */ + CPPUNIT_ASSERT(right.cmp(left) < 0); + CPPUNIT_ASSERT(right.cmp("foo") < 0); + CPPUNIT_ASSERT(right.cmp("foo", 1) < 0); +} diff --git a/src/tests/testString.h b/src/tests/testString.h new file mode 100644 index 0000000000..e5d545d6ca --- /dev/null +++ b/src/tests/testString.h @@ -0,0 +1,28 @@ + +#ifndef SQUID_SRC_TEST_STRING_H +#define SQUID_SRC_TEST_STRING_H + +#include + +/* + * test the store framework + */ + +class testString : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testString ); + CPPUNIT_TEST( testCmpDefault ); + CPPUNIT_TEST( testCmpEmptyString ); + CPPUNIT_TEST( testCmpNotEmptyDefault ); + CPPUNIT_TEST_SUITE_END(); + +public: + +protected: + void testCmpDefault(); + void testCmpEmptyString(); + void testCmpNotEmptyDefault(); +}; + +#endif + diff --git a/src/time.cc b/src/time.cc new file mode 100644 index 0000000000..13661c2d3d --- /dev/null +++ b/src/time.cc @@ -0,0 +1,52 @@ + +/* + * $Id: time.cc,v 1.1 2006/05/03 14:04:44 robertc Exp $ + * + * DEBUG: section 21 Time Functions + * AUTHOR: Harvest Derived + * + * 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" + + +time_t +getCurrentTime(void) +{ +#if GETTIMEOFDAY_NO_TZP + gettimeofday(¤t_time); +#else + + gettimeofday(¤t_time, NULL); +#endif + + current_dtime = (double) current_time.tv_sec + + (double) current_time.tv_usec / 1000000.0; + return squid_curtime = current_time.tv_sec; +} diff --git a/src/tools.cc b/src/tools.cc index c6e333b4d9..377660ff43 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.266 2006/04/23 11:10:32 robertc Exp $ + * $Id: tools.cc,v 1.267 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -924,21 +924,6 @@ setMaxFD(void) #endif /* RLIMIT_VMEM */ } -time_t -getCurrentTime(void) -{ -#if GETTIMEOFDAY_NO_TZP - gettimeofday(¤t_time); -#else - - gettimeofday(¤t_time, NULL); -#endif - - current_dtime = (double) current_time.tv_sec + - (double) current_time.tv_usec / 1000000.0; - return squid_curtime = current_time.tv_sec; -} - int percent(int a, int b) { diff --git a/src/ufsdump.cc b/src/ufsdump.cc index daed49b922..526bea76c1 100644 --- a/src/ufsdump.cc +++ b/src/ufsdump.cc @@ -1,6 +1,6 @@ /* - * $Id: ufsdump.cc,v 1.5 2006/04/29 13:57:39 serassio Exp $ + * $Id: ufsdump.cc,v 1.6 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 0 UFS Store Dump * AUTHOR: Robert Collins @@ -44,9 +44,21 @@ #include #include +/* stub functions for parts of squid not factored to be dynamic yet */ void shut_down(int) {} +#if WHENITMINIMAL +void +eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata) +{} + +void +cachemgrRegister(const char *action, const char *desc, OBJH * handler, int pw_req_flag, int atomic) +{} + +#endif +/* end stub functions */ struct DumpStoreMeta : public unary_function { @@ -116,14 +128,10 @@ main(int argc, char *argv[]) metadata = aBuilder.createStoreMeta (); - StoreEntry anEntry; - cache_key key[MD5_DIGEST_CHARS]; memset(key, '\0', MD5_DIGEST_CHARS); - memset(&anEntry, '\0', sizeof(StoreEntry)); - DumpStoreMeta dumper; for_each(*metadata, dumper); diff --git a/src/url.cc b/src/url.cc index 499d304789..dd5b03b309 100644 --- a/src/url.cc +++ b/src/url.cc @@ -1,6 +1,6 @@ /* - * $Id: url.cc,v 1.152 2006/04/23 11:10:32 robertc Exp $ + * $Id: url.cc,v 1.153 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 23 URL Parsing * AUTHOR: Duane Wessels @@ -317,6 +317,13 @@ urlDefaultPort(protocol_t p) * * If the 'request' arg is non-NULL, put parsed values there instead * of allocating a new HttpRequest. + * + * This abuses HttpRequest as a way of representing the parsed url + * and its components. + * method is used to switch parsers and to init the HttpRequest. + * If method is METHOD_CONNECT, then rather than a URL a hostname:port is + * looked for. + * The url is non const so that if its too long we can NULL-terminate it in place. */ HttpRequest * urlParse(method_t method, char *url, HttpRequest *request) diff --git a/src/urn.cc b/src/urn.cc index ac3388a6f3..e45b2a5014 100644 --- a/src/urn.cc +++ b/src/urn.cc @@ -1,6 +1,6 @@ /* - * $Id: urn.cc,v 1.96 2006/02/17 20:15:35 wessels Exp $ + * $Id: urn.cc,v 1.97 2006/05/03 14:04:44 robertc Exp $ * * DEBUG: section 52 URN Parsing * AUTHOR: Kostas Anagnostakis @@ -211,7 +211,7 @@ UrnState::createUriResRequest (String &uri) safe_free (host); safe_free (urlres); urlres = xstrdup (local_urlres); - urlres_r = urlParse(METHOD_GET, urlres); + urlres_r = HttpRequest::CreateFromUrl(urlres); } void -- 2.47.2