/* print option name */
packerPrintf(p, (pcount ? ", %.*s" : "%.*s"),
- CcFieldsInfo[flag].name.size(),
+ CcFieldsInfo[flag].name.psize(),
CcFieldsInfo[flag].name.rawBuf());
/* handle options with values */
}
}
- if (cc->other.size())
+ if (cc->other.size() != 0)
packerPrintf(p, (pcount ? ", %.*s" : "%.*s"),
- cc->other.size(), cc->other.rawBuf());
+ cc->other.psize(), cc->other.rawBuf());
}
/* negative max_age will clean old max_Age setting */
/* print option name */
packerPrintf(p, (pcount ? ", %.*s" : "%.*s"),
- ScFieldsInfo[flag].name.size(),
+ ScFieldsInfo[flag].name.psize(),
ScFieldsInfo[flag].name.rawBuf());
/* handle options with values */
packerPrintf(p, "=%d", (int) sc->max_age);
if (flag == SC_CONTENT)
- packerPrintf(p, "=\"%.*s\"", sc->content.size(), sc->content.rawBuf());
+ packerPrintf(p, "=\"%.*s\"", sc->content.psize(), sc->content.rawBuf());
pcount++;
}
}
if (sc->target.size())
- packerPrintf (p, ";%.*s", sc->target.size(), sc->target.rawBuf());
+ packerPrintf (p, ";%.*s", sc->target.psize(), sc->target.rawBuf());
}
void
}
http_hdr_type
-httpHeaderIdByName(const char *name, int name_len, const HttpHeaderFieldInfo * info, int end)
+httpHeaderIdByName(const char *name, size_t name_len, const HttpHeaderFieldInfo * info, int end)
{
int i;
bool HttpReply::sanityCheckStartLine(MemBuf *buf, http_status *error)
{
- if (buf->contentSize() >= protoPrefix.size() && protoPrefix.cmp(buf->content(), protoPrefix.size()) != 0) {
+ if (buf->contentSize() >= protoPrefix.psize() && protoPrefix.cmp(buf->content(), protoPrefix.size()) != 0) { //hack
debugs(58, 3, "HttpReply::sanityCheckStartLine: missing protocol prefix (" << protoPrefix << ") in '" << buf->content() << "'");
*error = HTTP_INVALID_HEADER;
return false;
assert(p);
/* pack request-line */
packerPrintf(p, "%s %.*s HTTP/1.0\r\n",
- RequestMethodStr(method), urlpath.size(), urlpath.rawBuf());
+ RequestMethodStr(method), urlpath.psize(), urlpath.rawBuf());
/* headers */
header.packInto(p);
/* trailer */
#define SQUID_STRING_H
#include "config.h"
+#include "TextException.h"
+
/** todo checks to wrap this include properly */
#include <ostream>
*/
_SQUID_INLINE_ char operator [](unsigned int pos) const;
- _SQUID_INLINE_ int size() const;
+ _SQUID_INLINE_ size_t size() const;
+ /// variant of size() suited to be used for printf-alikes.
+ /// throws when size() > MAXINT
+ _SQUID_INLINE_ int psize() const;
_SQUID_INLINE_ char const * unsafeBuf() const;
/**
/// returns std::string::npos if ch is not found
_SQUID_INLINE_ size_t find(char const ch) const;
_SQUID_INLINE_ const char * rpos(char const ch) const;
+ _SQUID_INLINE_ size_t rfind(char const ch) const;
_SQUID_INLINE_ int cmp (char const *) const;
_SQUID_INLINE_ int cmp (char const *, size_t count) const;
_SQUID_INLINE_ int cmp (String const &) const;
_SQUID_INLINE_ int caseCmp (char const *, size_t count) const;
_SQUID_INLINE_ int caseCmp (String const &) const;
+ String substr(size_t from, size_t to) const;
+
/** \deprecated Use assignment to [] position instead.
* ie str[newLength] = '\0';
*/
_SQUID_INLINE_ void cut(size_t newLength);
- /** \deprecated Use assignment to [] position instead.
- * ie str[newLength] = '\0';
- */
- _SQUID_INLINE_ void cutPointer(char const *loc);
#if DEBUGSTRINGS
void setBuffer(char *buf, size_t sz);
/* never reference these directly! */
- unsigned short int size_; /* buffer size; 64K limit */
+ size_t size_; /* buffer size; 64K limit */
- unsigned short int len_; /* current length */
+ size_t len_; /* current length */
char *buf_;
+
+ _SQUID_INLINE_ void set(char const *loc, char const ch);
+ _SQUID_INLINE_ void cutPointer(char const *loc);
+
};
_SQUID_INLINE_ std::ostream & operator<<(std::ostream& os, String const &aString);
old.len_ = 0;
}
+String
+String::substr(size_t from, size_t to) const
+{
+ Must(from >= 0 && from < size());
+ Must(to > 0 && to <= size());
+ Must(to > from);
+
+ String rv;
+ rv.limitInit(rawBuf()+from,to-from);
+ return rv;
+}
+
+
#if DEBUGSTRINGS
void
String::stat(StoreEntry *entry) const
return p ? p : "(NULL)";
}
+
#ifndef _USE_INLINE_
#include "String.cci"
#endif
#include "assert.h"
#include <cstring>
+#include "squid.h"
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h> //for INT_MAX
+#else /* HAVE_STDINT_H */
+#ifndef INT_MAX
+#define INT_MAX 1<<31 //hack but a safe bet
+#endif /* INT_MAX */
+#endif /* HAVE_STDINT_H */
+
String::String() : size_(0), len_(0), buf_ (NULL)
{
#endif
}
-int
+size_t
String::size() const
{
return len_;
}
+int
+String::psize() const
+{
+ Must(size() < INT_MAX);
+ return size();
+}
+
char const *
String::unsafeBuf() const
{
return strrchr(termedBuf(), (ch));
}
+size_t
+String::rfind(char const ch) const
+{
+ const char *c;
+ c=rpos(ch);
+ if (c==NULL)
+ return std::string::npos;
+ return c-rawBuf();
+}
+
+
int
String::cmp (char const *aString) const
{
return caseCmp(str.rawBuf(),str.size());
}
+
+void
+String::set(char const *loc, char const ch)
+{
+ if (loc < buf_ || loc > (buf_ + size_) ) return;
+
+ buf_[loc-buf_] = ch;
+}
+
void
String::cut(size_t newLength)
{
static void
clientPackTermBound(String boundary, MemBuf * mb)
{
- mb->Printf("\r\n--%.*s--\r\n", boundary.size(), boundary.rawBuf());
+ mb->Printf("\r\n--%.*s--\r\n", boundary.psize(), boundary.rawBuf());
debugs(33, 6, "clientPackTermBound: buf offset: " << mb->size);
}
/* put boundary */
debugs(33, 5, "clientPackRangeHdr: appending boundary: " << boundary);
/* rfc2046 requires to _prepend_ boundary with <crlf>! */
- mb->Printf("\r\n--%.*s\r\n", boundary.size(), boundary.rawBuf());
+ mb->Printf("\r\n--%.*s\r\n", boundary.psize(), boundary.rawBuf());
/* stuff the header with required entries and pack it */
if (!Config.errorDirectory && request && request->header.getList(HDR_ACCEPT_LANGUAGE, &hdr) ) {
const char *unsafeBuf = hdr.unsafeBuf(); // raw header string for parsing
- int pos = 0; // current parsing position in header string
+ size_t pos = 0; // current parsing position in header string
char *reset = NULL; // where to reset the p pointer for each new tag file
char *dt = NULL;
return 0; /* different username */
}
+static const String str_type_eq("type=");
void
FtpStateData::checkUrlpath()
{
int l;
- const char *t;
+ size_t t;
- if ((t = request->urlpath.rpos(';')) != NULL) {
- if (strncasecmp(t + 1, "type=", 5) == 0) {
- typecode = (char) xtoupper(*(t + 6));
- request->urlpath.cutPointer(t);
+ if ((t = request->urlpath.rfind(';')) != std::string::npos) {
+ if (request->urlpath.substr(t+1,t+1+str_type_eq.size())==str_type_eq) {
+ typecode = (char)xtoupper(request->urlpath[t+str_type_eq.size()+1]);
+ request->urlpath.cut(t);
}
}
if (orig_request->extacl_user.size() && orig_request->extacl_passwd.size()) {
char loginbuf[256];
snprintf(loginbuf, sizeof(loginbuf), "%.*s:%.*s",
- orig_request->extacl_user.size(),
+ orig_request->extacl_user.psize(),
orig_request->extacl_user.rawBuf(),
- orig_request->extacl_passwd.size(),
+ orig_request->extacl_passwd.psize(),
orig_request->extacl_passwd.rawBuf());
httpHeaderPutStrf(hdr_out, HDR_PROXY_AUTHORIZATION, "Basic %s",
base64_encode(loginbuf));
} else if (orig_request->extacl_user.size() && orig_request->extacl_passwd.size()) {
char loginbuf[256];
snprintf(loginbuf, sizeof(loginbuf), "%.*s:%.*s",
- orig_request->extacl_user.size(),
+ orig_request->extacl_user.psize(),
orig_request->extacl_user.rawBuf(),
- orig_request->extacl_passwd.size(),
+ orig_request->extacl_passwd.psize(),
orig_request->extacl_passwd.rawBuf());
httpHeaderPutStrf(hdr_out, HDR_AUTHORIZATION, "Basic %s",
base64_encode(loginbuf));
class HttpHeaderFieldInfo;
SQUIDCEXTERN HttpHeaderFieldInfo *httpHeaderBuildFieldsInfo(const HttpHeaderFieldAttrs * attrs, int count);
SQUIDCEXTERN void httpHeaderDestroyFieldsInfo(HttpHeaderFieldInfo * info, int count);
-SQUIDCEXTERN http_hdr_type httpHeaderIdByName(const char *name, int name_len, const HttpHeaderFieldInfo * attrs, int end);
+SQUIDCEXTERN http_hdr_type httpHeaderIdByName(const char *name, size_t name_len, const HttpHeaderFieldInfo * attrs, int end);
SQUIDCEXTERN http_hdr_type httpHeaderIdByNameDef(const char *name, int name_len);
SQUIDCEXTERN const char *httpHeaderNameById(int id);
SQUIDCEXTERN int httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive);
static Logfile *storelog = NULL;
+static const String str_unknown="unknown";
+
void
storeLog(int tag, const StoreEntry * e)
{
* Because if we print it before the swap file number, it'll break
* the existing log format.
*/
- logfilePrintf(storelog, "%9d.%03d %-7s %02d %08X %s %4d %9d %9d %9d %s %"PRId64"/%"PRId64" %s %s\n",
+
+ String ctype=(reply->content_type.size() ? reply->content_type.termedBuf() : str_unknown);
+
+ logfilePrintf(storelog, "%9d.%03d %-7s %02d %08X %s %4d %9d %9d %9d %.*s %"PRId64"/%"PRId64" %s %s\n",
(int) current_time.tv_sec,
(int) current_time.tv_usec / 1000,
storeLogTags[tag],
(int) reply->date,
(int) reply->last_modified,
(int) reply->expires,
- reply->content_type.size() ? reply->content_type.unsafeBuf() : "unknown",
+ ctype.psize(), ctype.rawBuf(),
reply->content_length,
e->contentLen(),
RequestMethodStr(mem->method),
CPPUNIT_ASSERT(right.cmp("foo") < 0);
CPPUNIT_ASSERT(right.cmp("foo", 1) < 0);
}
+
+void testString::testSubstr()
+{
+ String s("0123456789");
+ String check=s.substr(3,5);
+ String ref("34");
+ CPPUNIT_ASSERT(s1 == ref);
+}
CPPUNIT_TEST( testCmpDefault );
CPPUNIT_TEST( testCmpEmptyString );
CPPUNIT_TEST( testCmpNotEmptyDefault );
+ CPPUNIT_TEST( testSubstr );
+
CPPUNIT_TEST_SUITE_END();
public:
void testCmpDefault();
void testCmpEmptyString();
void testCmpNotEmptyDefault();
+ void testSubstr();
};
#endif
if (request->protocol == PROTO_URN) {
snprintf(urlbuf, MAX_URL, "urn:%.*s",
- request->urlpath.size(),
+ request->urlpath.psize(),
request->urlpath.rawBuf());
} else {
/// \todo AYJ: this could use "if..else and method == METHOD_CONNECT" easier.
*request->login ? "@" : null_string,
request->GetHost(),
portbuf,
- request->urlpath.size(),
+ request->urlpath.psize(),
request->urlpath.rawBuf());
break;
if (request->protocol == PROTO_URN) {
snprintf(buf, MAX_URL, "urn:%.*s",
- request->urlpath.size(), request->urlpath.rawBuf());
+ request->urlpath.psize(), request->urlpath.rawBuf());
} else {
/// \todo AYJ: this could use "if..else and method == METHOD_CONNECT" easier.
switch (request->method.id()) {
loginbuf,
request->GetHost(),
portbuf,
- request->urlpath.size(),
+ request->urlpath.psize(),
request->urlpath.rawBuf());
/*
* strip arguments AFTER a question-mark
if (req->protocol == PROTO_URN) {
snprintf(urlbuf, MAX_URL, "urn:%.*s",
- req->urlpath.size(),
+ req->urlpath.psize(),
req->urlpath.rawBuf());
return (urlbuf);
}
{
LOCAL_ARRAY(char, local_urlres, 4096);
char *host = getHost (uri);
- snprintf(local_urlres, 4096, "http://%s/uri-res/N2L?urn:%.*s", host, uri.size(), uri.rawBuf());
+ snprintf(local_urlres, 4096, "http://%s/uri-res/N2L?urn:%.*s", host, uri.psize(), uri.rawBuf());
safe_free (host);
safe_free (urlres);
urlres = xstrdup (local_urlres);
buf = (char *)xmalloc(l);
- snprintf(buf, l, "%.*s\r\n", p->request->urlpath.size()-1, p->request->urlpath.rawBuf() + 1);
+ snprintf(buf, l, "%.*s\r\n", p->request->urlpath.psize()-1, p->request->urlpath.rawBuf() + 1);
comm_write(fd, buf, strlen(buf), whoisWriteComplete, p, NULL);
comm_read(fd, p->buf, BUFSIZ, whoisReadReply, p);