From: rousskov <>
Date: Thu, 28 May 1998 04:51:37 +0000 (+0000)
Subject: - removed ascii headers from reply and request structures
X-Git-Tag: SQUID_3_0_PRE1~3236
X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2246b73298f50a6d4ecdf84e5759a1da2fa9c98b;p=thirdparty%2Fsquid.git
- removed ascii headers from reply and request structures
- added more http headers
- fixed content of entity-headers array
- do not update headers with 304 that are not allowed by HTTP/1.1
- moved routines common for request and replies to HttpMsg.c
- rewrote clientBuildReply* and other client_side functions
using new header interface
- code cleanup
- do not cut off "; parameter" from "digitized" Content-Type
http fields
- Added X-Request-URI for persistent connection debugging
---
diff --git a/ChangeLog b/ChangeLog
index 5fe353cdf6..890561aad6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+ - do not cut off "; parameter" from "digitized" Content-Type
+ http fields
+ - Added X-Request-URI for persistent connection debugging
+ (Henrik Nordstrom)
- Added Polish error pages from Maciej Kozinski.
- Fixed hash_first/hash_next bugs with **Current pointer.
Replaced with *next pointer.
@@ -38,22 +42,25 @@ Changes to squid-1.2.beta21 (May 22, 1998):
- Changed URN menu output to be sorted.
- Added fast select(2) timeouts when using ASYNC_IO.
- Added ARP ACL support for Linux (David Luyer).
- - Added binary http headers to requests (still under construction)
+ - Added binary http headers to requests
- request_t objects are now created and destroyed in a consistent way
- Fixed cache control printf bug
- Added a lot of new http header ids
- Improved Connection: header handling; now both Connection and
- Proxy-Connection headers are checked
+ Proxy-Connection headers are checked for connection directives
- Connection request header is now handled correctly regardless
of its position and the number of entries
- - Better handling of persistent connection "clues" in HTTP headers
+ - Only replies with valid Content-Length can be sent with keep-alive
+ connection directive (Henrik Nordstrom)
+ - Better handling of persistent connection "clues" in HTTP headers;
+ the decision now depends on HTTP version (and User-Agent exceptions)
- Removed handling of "length=" directive in IMS headers;
the directive is not in the HTTP/1.1 standard;
standing by for objections
- allowed/denied headers are now checked using bit masks instead of
strcmp loops
- removed Uri: from allowed headers; Uri is deprecated in RFC 2068
- - removed processing of Request-Range header (no in specs?)
+ - removed processing of Request-Range header (not in specs?)
- Fixed byte-order bugs in cacheDigestHashKey.
- Changed hash_remove_link() to return void.
- Changed ipcache_gethostbyname() to return NULL if
diff --git a/TODO b/TODO
index 5476fa3209..4c0fd7a41d 100644
--- a/TODO
+++ b/TODO
@@ -36,23 +36,6 @@ Our Todo List
(3) 'no_cache' access list for specifing objects which should not
be cached.
(3) What to do about ACL's and URL escaping?
-(3) Alex's HTTP Header todo list
- - http_request will be replaced with HttpRequest with changes
- similar to (http_reply -> HttpReply) transition.
- - Http replies and request will be parsed once on
- receiver(reader) end and will remain in compiled form after
- that. No "raw" header buffer will be preserved.
- - Request and reply headers (with start-lines) are likely to be
- written in compiled form as metadata to swap files.
- - Dynamic memory allocation will be revised once again. Most of
- xstrdup calls and local buffers will be replaced with better
- alternatives with static pre-allocation of resources. This work
- has been started already.
- - Statistics collected on Http* objects and memory management
- routines will be enhanced.
- - A lot of current oddities with freshly added code should go away as
- we debug and polish things. Comments discussing current code
- problems will be deleted; hopefully, along with the problems.
(3) Full request headers for CONNECT requests.
(4) ** Everywhere that we use 'pattern' or such, use ACL elements instead.
@@ -60,6 +43,7 @@ Our Todo List
(4) ** Double check that MemBuf.size is used correctly everywhere (AR)
(4) Refresh based on content types. This means we'll need an enum of
known content types added to StoreEntry. Unknown types will lose.
+(4) Write binary headers as metadata?
(5) X-Proxy-hops header?
(5) internalize redirectors?
@@ -119,3 +103,4 @@ DONE:
- Replace bcopy with xmemcpy
(4) ** FTP PUT (KA)
(1) SSL doesn't work with Proxy Authentication
+(3) HTTP Header todo list (AR)
diff --git a/src/HttpBody.cc b/src/HttpBody.cc
index d006a70e69..340817192a 100644
--- a/src/HttpBody.cc
+++ b/src/HttpBody.cc
@@ -2,7 +2,7 @@
/*
- * $Id: HttpBody.cc,v 1.10 1998/05/22 23:43:49 wessels Exp $
+ * $Id: HttpBody.cc,v 1.11 1998/05/27 22:51:39 rousskov Exp $
*
* DEBUG: section 56 HTTP Message Body
* AUTHOR: Alex Rousskov
@@ -84,7 +84,7 @@ void
httpBodyPackInto(const HttpBody * body, Packer * p)
{
assert(body && p);
- /* assume it was a 0-terminating buffer */
+ /* assume it was a 0-terminated buffer */
if (body->size)
packerAppend(p, body->buf, body->size - 1);
}
diff --git a/src/HttpHdrExtField.cc b/src/HttpHdrExtField.cc
index 10ae40ee01..c1b7fa0f9e 100644
--- a/src/HttpHdrExtField.cc
+++ b/src/HttpHdrExtField.cc
@@ -1,6 +1,6 @@
/*
- * $Id: HttpHdrExtField.cc,v 1.3 1998/04/06 22:32:06 wessels Exp $
+ * $Id: HttpHdrExtField.cc,v 1.4 1998/05/27 22:51:40 rousskov Exp $
*
* DEBUG: section 69 HTTP Header: Extension Field
* AUTHOR: Alex Rousskov
@@ -72,12 +72,6 @@ httpHdrExtFieldParseCreate(const char *field_start, const char *field_end)
while (value_start < field_end && isspace(*value_start))
value_start++;
- /* cut off "; parameter" from Content-Type @?@ why? */
- if (!strncasecmp(field_start, "Content-Type:", 13)) {
- const int l = strcspn(value_start, ";\t ");
- if (l > 0 && value_start + l < field_end)
- field_end = value_start + l;
- }
return httpHdrExtFieldDoCreate(
field_start, name_end - field_start,
value_start, field_end - value_start);
diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
index e4ab1d3884..baea9e7664 100644
--- a/src/HttpHeader.cc
+++ b/src/HttpHeader.cc
@@ -1,6 +1,6 @@
/*
- * $Id: HttpHeader.cc,v 1.36 1998/05/22 23:43:52 wessels Exp $
+ * $Id: HttpHeader.cc,v 1.37 1998/05/27 22:51:41 rousskov Exp $
*
* DEBUG: section 55 HTTP Header
* AUTHOR: Alex Rousskov
@@ -51,9 +51,6 @@
*/
-/* To-Do: fix parseCount stats @?@ @?@ */
-
-
/*
* local types
*/
@@ -87,10 +84,12 @@ static const HttpHeaderFieldAttrs HeadersAttrs[] =
{"Age", HDR_ALLOW, ftStr},
{"Authorization", HDR_AUTHORIZATION, ftStr}, /* for now */
{"Cache-Control", HDR_CACHE_CONTROL, ftPCc},
- {"Connection", HDR_CONNECTION, ftStr}, /* for now */
+ {"Connection", HDR_CONNECTION, ftStr},
+ {"Content-Base", HDR_CONTENT_BASE, ftStr},
{"Content-Encoding", HDR_CONTENT_ENCODING, ftStr},
{"Content-Language", HDR_CONTENT_LANGUAGE, ftStr},
{"Content-Length", HDR_CONTENT_LENGTH, ftInt},
+ {"Content-Location", HDR_CONTENT_LOCATION, ftStr},
{"Content-MD5", HDR_CONTENT_MD5, ftStr}, /* for now */
{"Content-Range", HDR_CONTENT_RANGE, ftPContRange},
{"Content-Type", HDR_CONTENT_TYPE, ftStr},
@@ -125,6 +124,7 @@ static const HttpHeaderFieldAttrs HeadersAttrs[] =
{"X-Cache", HDR_X_CACHE, ftStr},
{"X-Cache-Lookup", HDR_X_CACHE_LOOKUP, ftStr},
{"X-Forwarded-For", HDR_X_FORWARDED_FOR, ftStr},
+ {"X-Request-URI", HDR_X_REQUEST_URI, ftStr},
{"X-Squid-Error", HDR_X_SQUID_ERROR, ftStr},
{"Other:", HDR_OTHER, ftStr} /* ':' will not allow matches */
};
@@ -169,8 +169,10 @@ static http_hdr_type GeneralHeadersArr[] =
/* entity-headers */
static http_hdr_type EntityHeadersArr[] =
{
- HDR_ALLOW, HDR_CONTENT_ENCODING, HDR_CONTENT_LANGUAGE, HDR_CONTENT_LENGTH,
- HDR_CONTENT_RANGE, HDR_ETAG, HDR_EXPIRES, HDR_LAST_MODIFIED, HDR_LINK, HDR_OTHER
+ HDR_ALLOW, HDR_CONTENT_BASE, HDR_CONTENT_ENCODING, HDR_CONTENT_LANGUAGE,
+ HDR_CONTENT_LENGTH, HDR_CONTENT_LOCATION, HDR_CONTENT_MD5,
+ HDR_CONTENT_RANGE, HDR_CONTENT_TYPE, HDR_ETAG, HDR_EXPIRES, HDR_LAST_MODIFIED, HDR_LINK,
+ HDR_OTHER
};
static HttpHeaderMask ReplyHeadersMask; /* set run-time using ReplyHeaders */
@@ -178,12 +180,12 @@ static http_hdr_type ReplyHeadersArr[] =
{
HDR_ACCEPT, HDR_ACCEPT_CHARSET, HDR_ACCEPT_ENCODING, HDR_ACCEPT_LANGUAGE,
HDR_ACCEPT_RANGES, HDR_AGE,
- HDR_CONTENT_MD5, HDR_CONTENT_TYPE,
HDR_LOCATION, HDR_MAX_FORWARDS,
HDR_MIME_VERSION, HDR_PUBLIC, HDR_RETRY_AFTER, HDR_SERVER, HDR_SET_COOKIE,
HDR_VARY,
HDR_WARNING, HDR_PROXY_CONNECTION, HDR_X_CACHE,
- HDR_X_CACHE_LOOKUP,
+ HDR_X_CACHE_LOOKUP,
+ HDR_X_REQUEST_URI,
HDR_X_SQUID_ERROR
};
@@ -198,11 +200,11 @@ static http_hdr_type RequestHeadersArr[] =
/* header accounting */
static HttpHeaderStat HttpHeaderStats[] =
{
- {"reply"},
+ {"all"},
{"request"},
- {"all"}
+ {"reply"}
};
-static int HttpHeaderStatCount = sizeof(HttpHeaderStats) / sizeof(*HttpHeaderStats);
+static int HttpHeaderStatCount = countof(HttpHeaderStats);
/* global counters */
static int HeaderParsedCount = 0;
@@ -216,9 +218,6 @@ static int HeaderEntryParsedCount = 0;
#define assert_eid(id) assert((id) >= 0 && (id) < HDR_ENUM_END)
-static int httpHeaderDelById(HttpHeader * hdr, http_hdr_type id);
-static void httpHeaderDelAt(HttpHeader * hdr, HttpHeaderPos pos);
-
static HttpHeaderEntry *httpHeaderEntryCreate(http_hdr_type id, const char *name, const char *value);
static void httpHeaderEntryDestroy(HttpHeaderEntry * e);
static HttpHeaderEntry *httpHeaderEntryParseCreate(const char *field_start, const char *field_end);
@@ -237,6 +236,8 @@ httpHeaderInitModule()
int i;
/* check that we have enough space for masks */
assert(8 * sizeof(HttpHeaderMask) >= HDR_ENUM_END);
+ /* all headers must be described */
+ assert(countof(HeadersAttrs) == HDR_ENUM_END);
Headers = httpHeaderBuildFieldsInfo(HeadersAttrs, HDR_ENUM_END);
/* create masks */
httpHeaderMaskInit(&ListHeadersMask);
@@ -281,11 +282,12 @@ httpHeaderStatInit(HttpHeaderStat * hs, const char *label)
*/
void
-httpHeaderInit(HttpHeader * hdr)
+httpHeaderInit(HttpHeader * hdr, http_hdr_owner_type owner)
{
- assert(hdr);
- debug(55, 7) ("init-ing hdr: %p\n", hdr);
+ assert(hdr && (owner == hoRequest || owner == hoReply));
+ debug(55, 7) ("init-ing hdr: %p owner: %d\n", hdr, owner);
memset(hdr, 0, sizeof(*hdr));
+ hdr->owner = owner;
arrayInit(&hdr->entries);
}
@@ -295,15 +297,16 @@ httpHeaderClean(HttpHeader * hdr)
HttpHeaderPos pos = HttpHeaderInitPos;
HttpHeaderEntry *e;
- debug(55, 7) ("cleaning hdr: %p\n", hdr);
- assert(hdr);
+ assert(hdr && (hdr->owner == hoRequest || hdr->owner == hoReply));
+ debug(55, 7) ("cleaning hdr: %p owner: %d\n", hdr, hdr->owner);
statHistCount(&HttpHeaderStats[0].hdrUCountDistr, hdr->entries.count);
+ statHistCount(&HttpHeaderStats[hdr->owner].hdrUCountDistr, hdr->entries.count);
HeaderDestroyedCount++;
NonEmptyHeaderDestroyedCount += hdr->entries.count > 0;
while ((e = httpHeaderGetEntry(hdr, &pos))) {
- /* fix this for req headers @?@ */
statHistCount(&HttpHeaderStats[0].fieldTypeDistr, e->id);
+ statHistCount(&HttpHeaderStats[hdr->owner].fieldTypeDistr, e->id);
/* tmp hack to avoid coredumps */
if (e->id < 0 || e->id >= HDR_ENUM_END)
debug(55, 0) ("httpHeaderClean BUG: entry[%d] is invalid (%d). Ignored.\n",
@@ -316,21 +319,37 @@ httpHeaderClean(HttpHeader * hdr)
arrayClean(&hdr->entries);
}
+/* append entries (also see httpHeaderUpdate) */
+void
+httpHeaderAppend(HttpHeader * dest, const HttpHeader * src)
+{
+ const HttpHeaderEntry *e;
+ HttpHeaderPos pos = HttpHeaderInitPos;
+ assert(src && dest);
+ assert(src != dest);
+ debug(55, 7) ("appending hdr: %p += %p\n", dest, src);
+
+ while ((e = httpHeaderGetEntry(src, &pos))) {
+ httpHeaderAddEntry(dest, httpHeaderEntryClone(e));
+ }
+}
+
/* use fresh entries to replace old ones */
void
-httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh)
+httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask *denied_mask)
{
- HttpHeaderEntry *e;
- HttpHeaderEntry *e_clone;
+ const HttpHeaderEntry *e;
HttpHeaderPos pos = HttpHeaderInitPos;
assert(old && fresh);
assert(old != fresh);
debug(55, 7) ("updating hdr: %p <- %p\n", old, fresh);
while ((e = httpHeaderGetEntry(fresh, &pos))) {
+ /* deny bad guys (ok to check for HDR_OTHER) here */
+ if (denied_mask && CBIT_TEST(*denied_mask, e->id))
+ continue;
httpHeaderDelByName(old, strBuf(e->name));
- e_clone = httpHeaderEntryClone(e);
- httpHeaderAddEntry(old, e_clone);
+ httpHeaderAddEntry(old, httpHeaderEntryClone(e));
}
}
@@ -338,8 +357,11 @@ httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh)
static int
httpHeaderReset(HttpHeader * hdr)
{
+ http_hdr_owner_type ho = hdr->owner;
+ assert(hdr);
+ ho = hdr->owner;
httpHeaderClean(hdr);
- httpHeaderInit(hdr);
+ httpHeaderInit(hdr, ho);
return 0;
}
@@ -477,13 +499,17 @@ httpHeaderDelByName(HttpHeader * hdr, const char *name)
return count;
}
-static int
+/* deletes all entries with a given id, returns the #entries deleted */
+int
httpHeaderDelById(HttpHeader * hdr, http_hdr_type id)
{
int count = 0;
HttpHeaderPos pos = HttpHeaderInitPos;
HttpHeaderEntry *e;
debug(55, 8) ("%p del-by-id %d\n", hdr, id);
+ assert(hdr);
+ assert_eid(id);
+ assert_eid(id != HDR_OTHER); /* does not make sense */
if (!CBIT_TEST(hdr->mask, id))
return 0;
while ((e = httpHeaderGetEntry(hdr, &pos))) {
@@ -501,11 +527,17 @@ httpHeaderDelById(HttpHeader * hdr, http_hdr_type id)
* deletes an entry at pos and leaves a gap; leaving a gap makes it
* possible to iterate(search) and delete fields at the same time
*/
-static void
+void
httpHeaderDelAt(HttpHeader * hdr, HttpHeaderPos pos)
{
- httpHeaderEntryDestroy(hdr->entries.items[pos]);
+ HttpHeaderEntry *e;
+ assert(pos >= HttpHeaderInitPos && pos < hdr->entries.count);
+ e = hdr->entries.items[pos];
hdr->entries.items[pos] = NULL;
+ /* decrement header length, allow for ": " and crlf */
+ hdr->len -= strLen(e->name) + 2 + strLen(e->value) + 2;
+ assert(hdr->len >= 0);
+ httpHeaderEntryDestroy(e);
}
@@ -525,6 +557,8 @@ httpHeaderAddEntry(HttpHeader * hdr, HttpHeaderEntry * e)
else
CBIT_SET(hdr->mask, e->id);
arrayAppend(&hdr->entries, e);
+ /* increment header length, allow for ": " and crlf */
+ hdr->len += strLen(e->name) + 2 + strLen(e->value) + 2;
}
/* return a list of entries with the same id separated by ',' and ws */
@@ -597,12 +631,8 @@ httpHeaderPutStr(HttpHeader * hdr, http_hdr_type id, const char *str)
void
httpHeaderPutAuth(HttpHeader * hdr, const char *authScheme, const char *realm)
{
- MemBuf mb;
assert(hdr && authScheme && realm);
- memBufDefInit(&mb);
- memBufPrintf(&mb, "%s realm=\"%s\"", authScheme, realm);
- httpHeaderPutStr(hdr, HDR_WWW_AUTHENTICATE, mb.buf);
- memBufClean(&mb);
+ httpHeaderPutStrf(hdr, HDR_WWW_AUTHENTICATE, "%s realm=\"%s\"", authScheme, realm);
}
void
@@ -699,9 +729,10 @@ httpHeaderGetCc(const HttpHeader * hdr)
return NULL;
s = httpHeaderGetList(hdr, HDR_CACHE_CONTROL);
cc = httpHdrCcParseCreate(&s);
- /* fix this for req headers @?@ */
- if (cc)
+ if (cc) {
httpHdrCcUpdateStats(cc, &HttpHeaderStats[0].ccTypeDistr);
+ httpHdrCcUpdateStats(cc, &HttpHeaderStats[hdr->owner].ccTypeDistr);
+ }
httpHeaderNoteParsedEntry(HDR_CACHE_CONTROL, s, !cc);
stringClean(&s);
return cc;
@@ -913,12 +944,10 @@ httpHeaderStoreReport(StoreEntry * e)
http_hdr_type ht;
assert(e);
- /* fix this (including summing for totals) for req hdrs @?@ */
- for (i = 0; i < 1 /*HttpHeaderStatCount */ ; i++) {
+ for (i = 1; i < HttpHeaderStatCount; i++) {
httpHeaderStatDump(HttpHeaderStats + i, e);
storeAppendPrintf(e, "%s\n", "
");
}
- storeAppendPrintf(e, "%s\n", "
");
/* field stats */
storeAppendPrintf(e, "Http Fields Stats (replies and requests)
\n");
storeAppendPrintf(e, "%2s\t %-20s\t %5s\t %6s\t %6s\n",
diff --git a/src/HttpHeaderTools.cc b/src/HttpHeaderTools.cc
index 65f5e5fef5..23db8abb66 100644
--- a/src/HttpHeaderTools.cc
+++ b/src/HttpHeaderTools.cc
@@ -1,5 +1,5 @@
/*
- * $Id: HttpHeaderTools.cc,v 1.13 1998/05/22 23:43:53 wessels Exp $
+ * $Id: HttpHeaderTools.cc,v 1.14 1998/05/27 22:51:42 rousskov Exp $
*
* DEBUG: section 66 HTTP Header Tools
* AUTHOR: Alex Rousskov
@@ -31,6 +31,7 @@
#include "squid.h"
static int httpHeaderStrCmp(const char *h1, const char *h2, int len);
+static void httpHeaderPutStrvf(HttpHeader * hdr, http_hdr_type id, const char *fmt, va_list vargs);
HttpHeaderFieldInfo *
@@ -105,6 +106,50 @@ httpHeaderIdByName(const char *name, int name_len, const HttpHeaderFieldInfo * i
return -1;
}
+/* same as httpHeaderPutStr, but formats the string using snprintf first */
+#ifdef __STDC__
+void
+httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+#else
+void
+httpHeaderPutStrf(va_alist)
+ va_dcl
+{
+ va_list args;
+ HttpHeader *hdr = NULL;
+ http_hdr_type id = HDR_ENUM_END;
+ const char *fmt = NULL;
+ va_start(args);
+ hdr = va_arg(args, HttpHeader *);
+ id = va_arg(args, http_hdr_type);
+ fmt = va_arg(args, char *);
+#endif
+ httpHeaderPutStrvf(hdr, id, fmt, args);
+ va_end(args);
+}
+
+/* used by httpHeaderPutStrf */
+static void
+httpHeaderPutStrvf(HttpHeader * hdr, http_hdr_type id, const char *fmt, va_list vargs)
+{
+#if OLD_CODE
+ LOCAL_ARRAY(char, buf, 4096);
+ buf[0] = '\0';
+ vsnprintf(buf, 4096, fmt, vargs);
+ httpHeaderPutStr(hdr, id, buf);
+#else
+ MemBuf mb;
+ memBufDefInit(&mb);
+ memBufVPrintf(&mb, fmt, vargs);
+ httpHeaderPutStr(hdr, id, mb.buf);
+ memBufClean(&mb);
+#endif
+}
+
+
/*
* return true if a given directive is found in at least one of the "connection" header-fields
* note: if HDR_PROXY_CONNECTION is present we ignore HDR_CONNECTION
@@ -158,8 +203,10 @@ void
strListAdd(String * str, const char *item, char del)
{
assert(str && item);
- if (strLen(*str))
- stringAppend(str, &del, 1);
+ if (strLen(*str)) {
+ char buf[3] = { del, ' ', '\0' };
+ stringAppend(str, buf, 2);
+ }
stringAppend(str, item, strlen(item));
}
@@ -274,7 +321,7 @@ httpHeaderTestParser(const char *hstr)
hstr_len -= 2;
else if (strstr(hstr, "\n\n"))
hstr_len -= 1;
- httpHeaderInit(&hdr);
+ httpHeaderInit(&hdr, hoReply);
/* debugLevels[55] = 8; */
parse_success = httpHeaderParse(&hdr, hstr, hstr + hstr_len);
/* debugLevels[55] = 2; */
diff --git a/src/HttpMsg.cc b/src/HttpMsg.cc
new file mode 100644
index 0000000000..33a6e11ec3
--- /dev/null
+++ b/src/HttpMsg.cc
@@ -0,0 +1,101 @@
+
+/*
+ * $Id: HttpMsg.cc,v 1.2 1998/05/27 22:51:43 rousskov Exp $
+ *
+ * DEBUG: section 74 HTTP Message
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
+ * --------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from the
+ * Internet community. Development is led by Duane Wessels of the
+ * National Laboratory for Applied Network Research and funded by
+ * the National Science Foundation.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "squid.h"
+
+
+/* find end of headers */
+int
+httpMsgIsolateHeaders(const char **parse_start, const char **blk_start, const char **blk_end)
+{
+ /* adopted with mods from mime_headers_end() */
+ const char *p1 = strstr(*parse_start, "\n\r\n");
+ const char *p2 = strstr(*parse_start, "\n\n");
+ const char *end = NULL;
+
+ if (p1 && p2)
+ end = p1 < p2 ? p1 : p2;
+ else
+ end = p1 ? p1 : p2;
+
+ if (end) {
+ *blk_start = *parse_start;
+ *blk_end = end + 1;
+ *parse_start = end + (end == p1 ? 3 : 2);
+ return 1;
+ }
+ /* no headers, case 1 */
+ if ((*parse_start)[0] == '\r' && (*parse_start)[1] == '\n') {
+ *blk_start = *parse_start;
+ *blk_end = *blk_start;
+ *parse_start += 2;
+ return 1;
+ }
+ /* no headers, case 2 */
+ if ((*parse_start)[0] == '\n') {
+ /* no headers */
+ *blk_start = *parse_start;
+ *blk_end = *blk_start;
+ *parse_start += 1;
+ return 1;
+ }
+ /* failure */
+ return 0;
+}
+
+/* returns true if connection should be "persistent"
+ * after processing this message */
+int
+httpMsgIsPersistent(float http_ver, const HttpHeader * hdr)
+{
+ if (http_ver >= 1.1) {
+ /*
+ * for modern versions of HTTP: persistent unless there is
+ * a "Connection: close" header.
+ */
+ return !httpHeaderHasConnDir(hdr, "close");
+ } else {
+ /*
+ * Persistent connections in Netscape 3.x are allegedly broken,
+ * return false if it is a browser connection. If there is a
+ * VIA header, then we assume this is NOT a browser connection.
+ */
+ const char *agent = httpHeaderGetStr(hdr, HDR_USER_AGENT);
+ if (agent && !httpHeaderHas(hdr, HDR_VIA)) {
+ if (!strncasecmp(agent, "Mozilla/3.", 10))
+ return 0;
+ if (!strncasecmp(agent, "Netscape/3.", 11))
+ return 0;
+ }
+ /* for old versions of HTTP: persistent if has "keep-alive" */
+ return httpHeaderHasConnDir(hdr, "keep-alive");
+ }
+}
diff --git a/src/HttpReply.cc b/src/HttpReply.cc
index 2d5b3833a9..e9629d5c60 100644
--- a/src/HttpReply.cc
+++ b/src/HttpReply.cc
@@ -1,6 +1,6 @@
/*
- * $Id: HttpReply.cc,v 1.24 1998/05/22 23:43:54 wessels Exp $
+ * $Id: HttpReply.cc,v 1.25 1998/05/27 22:51:44 rousskov Exp $
*
* DEBUG: section 58 HTTP Reply (Response)
* AUTHOR: Alex Rousskov
@@ -34,7 +34,18 @@
/* local constants */
+/* these entity-headers must be ignored if a bogus server sends them in 304 */
+static HttpHeaderMask Denied304HeadersMask;
+static http_hdr_type Denied304HeadersArr[] =
+{
+ HDR_ALLOW, HDR_CONTENT_ENCODING, HDR_CONTENT_LANGUAGE, HDR_CONTENT_LENGTH,
+ HDR_CONTENT_LOCATION, HDR_CONTENT_RANGE, HDR_LAST_MODIFIED, HDR_LINK,
+ HDR_OTHER
+};
+
/* local routines */
+static void httpReplyInit(HttpReply * rep);
+static void httpReplyClean(HttpReply * rep);
static void httpReplyDoDestroy(HttpReply * rep);
static void httpReplyHdrCacheInit(HttpReply * rep);
static void httpReplyHdrCacheClean(HttpReply * rep);
@@ -43,6 +54,15 @@ static int httpReplyParseError(HttpReply * rep);
static int httpReplyIsolateStart(const char **parse_start, const char **blk_start, const char **blk_end);
+/* module initialization */
+void
+httpReplyInitModule()
+{
+ httpHeaderMaskInit(&Denied304HeadersMask);
+ httpHeaderCalcMask(&Denied304HeadersMask, (const int *) Denied304HeadersArr, countof(Denied304HeadersArr));
+}
+
+
HttpReply *
httpReplyCreate()
{
@@ -59,7 +79,7 @@ httpReplyInit(HttpReply * rep)
rep->hdr_sz = 0;
rep->pstate = psReadyToParseStartLine;
httpBodyInit(&rep->body);
- httpHeaderInit(&rep->header);
+ httpHeaderInit(&rep->header, hoReply);
httpReplyHdrCacheInit(rep);
httpStatusLineInit(&rep->sline);
}
@@ -101,14 +121,14 @@ httpReplyAbsorb(HttpReply * rep, HttpReply * new_rep)
httpReplyDoDestroy(new_rep);
}
-/* parses a buffer that may not be 0-terminated */
+/* parses a 4K buffer that may not be 0-terminated; returns true on success */
int
httpReplyParse(HttpReply * rep, const char *buf)
{
/*
* this extra buffer/copy will be eliminated when headers become meta-data
* in store. Currently we have to xstrncpy the buffer becuase store.c may
- * feed a non 0-terminated buffer to us @?@.
+ * feed a non 0-terminated buffer to us.
*/
char *headers = memAllocate(MEM_4K_BUF);
int success;
@@ -237,7 +257,7 @@ httpReplyUpdateOnNotModified(HttpReply * rep, HttpReply * freshRep)
/* clean cache */
httpReplyHdrCacheClean(rep);
/* update raw headers */
- httpHeaderUpdate(&rep->header, &freshRep->header);
+ httpHeaderUpdate(&rep->header, &freshRep->header, &Denied304HeadersMask);
/* init cache */
httpReplyHdrCacheInit(rep);
}
@@ -371,73 +391,3 @@ httpReplyIsolateStart(const char **parse_start, const char **blk_start, const ch
*parse_start = *blk_end;
return 1;
}
-
-/* find end of headers */
-int
-httpMsgIsolateHeaders(const char **parse_start, const char **blk_start, const char **blk_end)
-{
- /* adopted with mods from mime_headers_end() */
- const char *p1 = strstr(*parse_start, "\n\r\n");
- const char *p2 = strstr(*parse_start, "\n\n");
- const char *end = NULL;
-
- if (p1 && p2)
- end = p1 < p2 ? p1 : p2;
- else
- end = p1 ? p1 : p2;
-
- if (end) {
- *blk_start = *parse_start;
- *blk_end = end + 1;
- *parse_start = end + (end == p1 ? 3 : 2);
- return 1;
- }
- /* no headers, case 1 */
- if ((*parse_start)[0] == '\r' && (*parse_start)[1] == '\n') {
- *blk_start = *parse_start;
- *blk_end = *blk_start;
- *parse_start += 2;
- return 1;
- }
- /* no headers, case 2 */
- if ((*parse_start)[0] == '\n') {
- /* no headers */
- *blk_start = *parse_start;
- *blk_end = *blk_start;
- *parse_start += 1;
- return 1;
- }
- /* failure */
- return 0;
-}
-
-/*
- *returns true if connection should be "persistent" after processing
- this message
- */
-int
-httpMsgIsPersistent(float http_ver, const HttpHeader * hdr)
-{
- if (http_ver >= 1.1) {
- /*
- * for modern versions of HTTP: persistent unless there is
- * a "Connection: close" header.
- */
- return !httpHeaderHasConnDir(hdr, "close");
- } else {
- /*
- * Persistent connections in Netscape 3.x are allegedly broken,
- * return false if it is a browser connection. If there is a
- * VIA header, then we assume this is NOT a browser connection.
- */
- const char *agent = httpHeaderGetStr(hdr, HDR_USER_AGENT);
- if (agent && !httpHeaderHas(hdr, HDR_VIA)) {
- if (!strncasecmp(agent, "Mozilla/3.", 10))
- return 0;
- if (!strncasecmp(agent, "Netscape/3.", 11))
- return 0;
- }
- /* for old versions of HTTP: persistent if has "keep-alive" */
- return httpHeaderHasConnDir(hdr, "keep-alive");
- }
-}
diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc
index ced595ab86..4d8ed75962 100644
--- a/src/HttpRequest.cc
+++ b/src/HttpRequest.cc
@@ -1,6 +1,6 @@
/*
- * $Id: HttpRequest.cc,v 1.4 1998/05/22 23:43:56 wessels Exp $
+ * $Id: HttpRequest.cc,v 1.5 1998/05/27 22:51:45 rousskov Exp $
*
* DEBUG: section 73 HTTP Request
* AUTHOR: Duane Wessels
@@ -41,6 +41,7 @@ requestCreate(method_t method, protocol_t protocol, const char *urlpath)
stringReset(&req->urlpath, urlpath);
req->max_age = -1;
req->max_forwards = -1;
+ httpHeaderInit(&req->header, hoRequest);
return req;
}
@@ -48,7 +49,9 @@ void
requestDestroy(request_t * req)
{
assert(req);
+#if OLD_CODE
safe_free(req->prefix);
+#endif
safe_free(req->body);
stringClean(&req->urlpath);
httpHeaderClean(&req->header);
@@ -89,9 +92,30 @@ httpRequestParseHeader(request_t * req, const char *parse_start)
return httpHeaderParse(&req->header, blk_start, blk_end);
}
+/* swaps out request-line and headers, appends terminator */
void
-httpRequestSetHeaders(request_t * req, method_t method, const char *uri, const char *header_str)
+httpRequestSwapOut(const request_t *req, StoreEntry *e)
{
+ assert(req && e);
+ /* store request-line */
+ storeAppendPrintf(e, "%s %s HTTP/1.0\r\n",
+ RequestMethodStr[req->method], req->urlpath);
+ /* store headers */
+ {
+ Packer p;
+ packerToStoreInit(&p, e);
+ httpHeaderPackInto(&req->header, &p);
+ packerClean(&p);
+ }
+ /* trailer */
+ storeAppend(e, "\r\n", 2);
+}
+
+#if UNUSED_CODE
+void
+httpRequestSetHeaders(request_t *req, method_t method, const char *uri, const char *header_str)
+{
+#if OLD_CODE
MemBuf mb;
assert(req && uri && header_str);
assert(!req->prefix);
@@ -102,8 +126,24 @@ httpRequestSetHeaders(request_t * req, method_t method, const char *uri, const c
req->prefix = xstrdup(mb.buf);
req->prefix_sz = mb.size;
memBufClean(&mb);
+#else
+ assert(req && uri && header_str);
+ assert(!req->header.len);
+#endif
httpHeaderParse(&req->header, header_str, header_str + strlen(header_str));
}
+#endif
+
+/* returns the length of request line + headers + crlf */
+int
+httpRequestPrefixLen(const request_t *req)
+{
+ assert(req);
+ return strlen(RequestMethodStr[req->method]) + 1 +
+ strLen(req->urlpath) + 1 +
+ 4+1+3 + 2 +
+ req->header.len + 2;
+}
/* returns true if header is allowed to be passed on */
int
diff --git a/src/Makefile.in b/src/Makefile.in
index 9a6f167055..d3343a9177 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
#
# Makefile for the Squid Object Cache server
#
-# $Id: Makefile.in,v 1.149 1998/05/11 18:44:29 rousskov Exp $
+# $Id: Makefile.in,v 1.150 1998/05/27 22:51:46 rousskov Exp $
#
# Uncomment and customize the following to suit your needs:
#
@@ -110,6 +110,7 @@ OBJS = \
HttpHeader.o \
HttpHeaderTools.o \
HttpBody.o \
+ HttpMsg.o \
HttpReply.o \
HttpRequest.o \
icmp.o \
diff --git a/src/MemBuf.cc b/src/MemBuf.cc
index f8f752cd15..722b3216b7 100644
--- a/src/MemBuf.cc
+++ b/src/MemBuf.cc
@@ -1,5 +1,5 @@
/*
- * $Id: MemBuf.cc,v 1.9 1998/05/22 23:43:57 wessels Exp $
+ * $Id: MemBuf.cc,v 1.10 1998/05/27 22:51:47 rousskov Exp $
*
* DEBUG: section 59 auto-growing Memory Buffer with printf
* AUTHOR: Alex Rousskov
@@ -29,7 +29,7 @@
*/
/*
- * To-Do: uses memory pools for .buf recycling @?@ @?@
+ * To-Do: use memory pools for .buf recycling @?@ @?@
*/
/*
@@ -85,8 +85,8 @@
* ...
*
* -- write
- * comm_write(buf.buf, memBufFreeFunc(&buf), ...);
- *
+ * comm_write_mbuf(fd, buf, handler, data);
+ *
* -- *iff* you did not give the buffer away, free it yourself
* -- memBufClean(&buf);
* }
@@ -141,7 +141,8 @@ memBufClean(MemBuf * mb)
assert(mb->buf);
assert(mb->freefunc); /* not frozen */
- (*mb->freefunc) (mb->buf); /* freeze */
+ (*mb->freefunc) (mb->buf); /* free */
+ mb->freefunc = NULL; /* freeze */
mb->buf = NULL;
mb->size = mb->capacity = 0;
}
@@ -197,7 +198,7 @@ memBufVPrintf(MemBuf * mb, const char *fmt, va_list vargs)
assert(mb->buf);
assert(mb->freefunc); /* not frozen */
/* @?@ we do not init buf with '\0', do we have to for vsnprintf?? @?@ */
- /* assert in Grow should quit first, but we do not want to have a scare (1) loop */
+ /* assert in Grow should quit first, but we do not want to have a scary infinite loop */
while (mb->capacity <= mb->max_capacity) {
mb_size_t free_space = mb->capacity - mb->size;
/* put as much as we can */
@@ -208,7 +209,8 @@ memBufVPrintf(MemBuf * mb, const char *fmt, va_list vargs)
else
break;
}
- mb->size += sz - 1; /* note that we cut 0-terminator as store does @?@ @?@ */
+ assert(sz > 0);
+ mb->size += sz - 1; /* note that we cut 0-terminator as store does */
}
/*
diff --git a/src/access_log.cc b/src/access_log.cc
index 6b9a200c69..e996739c29 100644
--- a/src/access_log.cc
+++ b/src/access_log.cc
@@ -1,7 +1,7 @@
/*
- * $Id: access_log.cc,v 1.30 1998/05/24 03:47:19 wessels Exp $
+ * $Id: access_log.cc,v 1.31 1998/05/27 22:51:47 rousskov Exp $
*
* DEBUG: section 46 Access Log
* AUTHOR: Duane Wessels
@@ -227,6 +227,7 @@ accessLogLog(AccessLogEntry * al)
if (!al->http.content_type || *al->http.content_type == '\0')
al->http.content_type = dash_str;
if (!al->cache.ident || *al->cache.ident == '\0') {
+ /* argh, binary headers did not come through */
t = mime_get_header(al->headers.request, "Proxy-authorization:");
if (t == NULL) {
al->cache.ident = dash_str;
diff --git a/src/asn.cc b/src/asn.cc
index dd5f844efd..99d5a584b1 100644
--- a/src/asn.cc
+++ b/src/asn.cc
@@ -1,5 +1,5 @@
/*
- * $Id: asn.cc,v 1.36 1998/05/11 18:44:32 rousskov Exp $
+ * $Id: asn.cc,v 1.37 1998/05/27 22:51:48 rousskov Exp $
*
* DEBUG: section 53 AS Number handling
* AUTHOR: Duane Wessels, Kostas Anagnostakis
@@ -188,8 +188,6 @@ asnCacheStart(int as)
#if OLD_CODE
asState->request->headers = xstrdup("\r\n");
asState->request->headers_sz = strlen(asState->request->headers);
-#else
- httpRequestSetHeaders(asState->request, METHOD_GET, asres, "");
#endif
if ((e = storeGet(k)) == NULL) {
e = storeCreateEntry(asres, asres, 0, METHOD_GET);
diff --git a/src/client_side.cc b/src/client_side.cc
index 187df63419..29e398e872 100644
--- a/src/client_side.cc
+++ b/src/client_side.cc
@@ -1,6 +1,6 @@
/*
- * $Id: client_side.cc,v 1.316 1998/05/27 20:31:33 wessels Exp $
+ * $Id: client_side.cc,v 1.317 1998/05/27 22:51:49 rousskov Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
@@ -56,8 +56,7 @@ static int clientCheckTransferDone(clientHttpRequest *);
static void CheckQuickAbort(clientHttpRequest *);
static void checkFailureRatio(err_type, hier_code);
static void clientProcessMiss(clientHttpRequest *);
-static void clientAppendReplyHeader(char *, const char *, size_t *, size_t);
-size_t clientBuildReplyHeader(clientHttpRequest *, char *, size_t, size_t *, char *, size_t);
+static void clientBuildReplyHeader(clientHttpRequest * http, HttpReply *rep);
static clientHttpRequest *parseHttpRequestAbort(ConnStateData * conn, const char *uri);
static clientHttpRequest *parseHttpRequest(ConnStateData *, method_t *, int *, char **, size_t *);
static RH clientRedirectDone;
@@ -230,9 +229,7 @@ clientRedirectDone(void *data, char *result)
new_request->headers = xstrdup(old_request->headers);
new_request->headers_sz = old_request->headers_sz;
#else
- new_request->prefix = xstrdup(old_request->prefix);
- new_request->prefix_sz = old_request->prefix_sz;
- httpHeaderUpdate(&new_request->header, &old_request->header);
+ httpHeaderAppend(&new_request->header, &old_request->header);
#endif
new_request->client_addr = old_request->client_addr;
EBIT_SET(new_request->flags, REQ_REDIRECTED);
@@ -538,11 +535,13 @@ checkNegativeHit(StoreEntry * e)
return 1;
}
+#if UNUSED_CODE
static void
updateCDJunkStats()
{
/* rewrite */
}
+#endif
void
clientUpdateCounters(clientHttpRequest * http)
@@ -636,9 +635,16 @@ httpRequestFree(void *data)
http->al.cache.msec = tvSubMsec(http->start, current_time);
http->al.cache.ident = conn->ident.ident;
if (request) {
+ Packer p;
+ MemBuf mb;
+ memBufDefInit(&mb);
+ packerToMemInit(&p, &mb);
+ httpHeaderPackInto(&request->header, &p);
http->al.http.method = request->method;
- http->al.headers.request = request->prefix;
+ http->al.headers.request = xstrdup(mb.buf);
http->al.hier = request->hier;
+ packerClean(&p);
+ memBufClean(&mb);
}
accessLogLog(&http->al);
clientUpdateCounters(http);
@@ -652,6 +658,7 @@ httpRequestFree(void *data)
checkFailureRatio(request->err_type, http->al.hier.code);
safe_free(http->uri);
safe_free(http->log_uri);
+ safe_free(http->al.headers.request);
safe_free(http->al.headers.reply);
if (entry) {
http->entry = NULL;
@@ -938,6 +945,7 @@ isTcpHit(log_type code)
return 0;
}
+#if OLD_CODE
static void
clientAppendReplyHeader(char *hdr, const char *line, size_t * sz, size_t max)
{
@@ -948,9 +956,10 @@ clientAppendReplyHeader(char *hdr, const char *line, size_t * sz, size_t max)
strcat(hdr + (*sz), crlf);
*sz = n;
}
+#endif
-/* this entire function has to be rewriten using new interfaces @?@ @?@ */
-size_t
+#if OLD_CODE /* use new interfaces instead */
+static size_t
clientBuildReplyHeader(clientHttpRequest * http,
char *hdr_in,
size_t hdr_in_sz,
@@ -1038,6 +1047,84 @@ clientBuildReplyHeader(clientHttpRequest * http,
memFree(MEM_4K_BUF, ybuf);
return len;
}
+#endif
+
+static void
+clientBuildReplyHeader(clientHttpRequest * http, HttpReply *rep)
+{
+ HttpHeader *hdr = &rep->header;
+ int is_hit = isTcpHit(http->log_type);
+#if DONT_FILTER_THESE
+ /* but you might want to if you run Squid as an HTTP accelerator */
+ httpHeaderDelById(hdr, HDR_ACCEPT_RANGES);
+ httpHeaderDelById(hdr, HDR_ETAG);
+#endif
+ httpHeaderDelById(hdr, HDR_PROXY_CONNECTION);
+ /* here: Keep-Alive is a field-name, not a connection directive! */
+ httpHeaderDelByName(hdr, "Keep-Alive");
+ /* remove Set-Cookie if a hit */
+ if (is_hit)
+ httpHeaderDelById(hdr, HDR_SET_COOKIE);
+ /* handle Connection header */
+ if (httpHeaderHas(hdr, HDR_CONNECTION)) {
+ /* anything that matches Connection list member will be deleted */
+ String strConnection = httpHeaderGetList(hdr, HDR_CONNECTION);
+ const HttpHeaderEntry *e;
+ HttpHeaderPos pos = HttpHeaderInitPos;
+ while ((e = httpHeaderGetEntry(hdr, &pos))) {
+ if (strListIsMember(&strConnection, strBuf(e->name), ','))
+ httpHeaderDelAt(hdr, pos);
+ }
+ httpHeaderDelById(hdr, HDR_CONNECTION);
+ stringClean(&strConnection);
+ }
+ /* Append X-Cache */
+ httpHeaderPutStrf(hdr, HDR_X_CACHE, "%s from %s",
+ is_hit ? "HIT" : "MISS", getMyHostname());
+#if USE_CACHE_DIGESTS
+ /* Append X-Cache-Lookup: -- temporary hack, to be removed @?@ @?@ */
+ httpHeaderPutStrf(hdr, HDR_X_CACHE_LOOKUP, "%s from %s:%d",
+ http->lookup_type ? http->lookup_type : "NONE",
+ getMyHostname(), Config.Port.http->i);
+#endif
+ /* Only replies with valid Content-Length can be sent with keep-alive */
+ if (http->request->method != METHOD_HEAD &&
+ http->entry->mem_obj->reply->content_length < 0)
+ EBIT_CLR(http->request->flags, REQ_PROXY_KEEPALIVE);
+ /* Signal keep-alive if needed */
+ if (EBIT_TEST(http->request->flags, REQ_PROXY_KEEPALIVE))
+ httpHeaderPutStr(hdr,
+ http->flags.accel ? HDR_CONNECTION : HDR_PROXY_CONNECTION,
+ "keep-alive");
+#if ADD_X_REQUEST_URI
+ /*
+ * Knowing the URI of the request is useful when debugging persistent
+ * connections in a client; we cannot guarantee the order of http headers,
+ * but X-Request-URI is likely to be the very last header to ease use from a
+ * debugger [hdr->entries.count-1].
+ */
+ httpHeaderPutStr(hdr, HDR_X_REQUEST_URI,
+ http->entry->mem_obj->url ? http->entry->mem_obj->url : http->uri);
+#endif
+}
+
+static HttpReply*
+clientBuildReply(clientHttpRequest * http, const char *buf, size_t size)
+{
+ HttpReply *rep = httpReplyCreate();
+ assert(size <= 4096); /* httpReplyParse depends on this */
+ if (httpReplyParse(rep, buf)) {
+ /* enforce 1.0 reply version */
+ rep->sline.version = 1.0;
+ /* do header conversions */
+ clientBuildReplyHeader(http, rep);
+ } else {
+ /* parsing failure, get rid of the invalid reply */
+ httpReplyDestroy(rep);
+ rep = NULL;
+ }
+ return rep;
+}
static void
clientCacheHit(void *data, char *buf, ssize_t size)
@@ -1062,6 +1149,10 @@ clientCacheHit(void *data, char *buf, ssize_t size)
}
}
+/*
+ * accepts chunk of a http message in buf, parses prefix, filters headers and
+ * such, writes processed message to the client's socket
+ */
static void
clientSendMoreData(void *data, char *buf, ssize_t size)
{
@@ -1069,11 +1160,18 @@ clientSendMoreData(void *data, char *buf, ssize_t size)
StoreEntry *entry = http->entry;
ConnStateData *conn = http->conn;
int fd = conn->fd;
+#if OLD_CODE
size_t hdrlen;
size_t l = 0;
size_t writelen;
char *newbuf;
FREE *freefunc = memFree4K;
+#else
+ HttpReply *rep = NULL;
+ FREE *freefunc = memFree4K;
+ const char *body_buf = buf;
+ ssize_t body_size = size;
+#endif
debug(33, 5) ("clientSendMoreData: %s, %d bytes\n", http->uri, (int) size);
assert(size <= SM_PAGE_SIZE);
assert(http->request != NULL);
@@ -1100,7 +1198,9 @@ clientSendMoreData(void *data, char *buf, ssize_t size)
freefunc(buf);
return;
}
+#if OLD_CODE
writelen = size;
+#endif
if (http->out.offset == 0) {
if (Config.onoff.log_mime_hdrs) {
size_t k;
@@ -1110,6 +1210,7 @@ clientSendMoreData(void *data, char *buf, ssize_t size)
xstrncpy(http->al.headers.reply, buf, k);
}
}
+#if OLD_CODE
newbuf = memAllocate(MEM_8K_BUF);
hdrlen = 0;
l = clientBuildReplyHeader(http, buf, size, &hdrlen, newbuf, 8192);
@@ -1133,9 +1234,20 @@ clientSendMoreData(void *data, char *buf, ssize_t size)
buf = newbuf;
freefunc = memFree8K;
newbuf = NULL;
+#else
+ rep = clientBuildReply(http, buf, size);
+ if (rep) {
+ body_size = size - rep->hdr_sz;
+ assert(body_size >= 0);
+ body_buf = buf + rep->hdr_sz;
+ debug(33, 3) ("clientSendMoreData: Appending %d bytes after %d bytes of headers\n",
+ body_size, rep->hdr_sz);
+#endif
} else {
+#if OLD_CODE
memFree(MEM_8K_BUF, newbuf);
newbuf = NULL;
+#endif
if (size < SM_PAGE_SIZE && entry->store_status == STORE_PENDING) {
/* wait for more to arrive */
storeClientCopy(entry,
@@ -1154,9 +1266,12 @@ clientSendMoreData(void *data, char *buf, ssize_t size)
* ick, this is gross
*/
if (http->request->method == METHOD_HEAD) {
- size_t k;
- if ((k = headersEnd(buf, size))) {
- writelen = k;
+ size_t k = 0;
+ if (rep)
+ body_size = 0; /* do not forward body for HEAD replies */
+ else
+ k = body_size = headersEnd(buf, size); /* unparseable reply, stop and end-of-headers */
+ if (rep || k) {
/* force end */
if (entry->store_status == STORE_PENDING)
http->out.offset = entry->mem_obj->inmem_hi;
@@ -1164,7 +1279,28 @@ clientSendMoreData(void *data, char *buf, ssize_t size)
http->out.offset = objectLen(entry);
}
}
+#if OLD_CODE
comm_write(fd, buf, writelen, clientWriteComplete, http, freefunc);
+#else
+ if (rep || (body_buf && body_size)) {
+ MemBuf mb;
+ /* init mb; put status line and headers if any */
+ if (rep) {
+ mb = httpReplyPack(rep);
+ httpReplyDestroy(rep);
+ rep = NULL;
+ } else {
+ memBufInit(&mb, body_size, body_size);
+ }
+ /* append body if any */
+ if (body_buf && body_size)
+ memBufAppend(&mb, body_buf, body_size);
+ /* write */
+ comm_write_mbuf(fd, mb, clientWriteComplete, http);
+ }
+ /* if we don't do it, who will? */
+ freefunc(buf);
+#endif
}
static
@@ -1537,10 +1673,14 @@ clientProcessRequest(clientHttpRequest * http)
storeBuffer(http->entry);
rep = httpReplyCreate();
httpReplySetHeaders(rep, 1.0, HTTP_OK, NULL, "text/plain",
- r->prefix_sz, 0, squid_curtime);
+ httpRequestPrefixLen(r), 0, squid_curtime);
httpReplySwapOut(rep, http->entry);
httpReplyDestroy(rep);
+#if OLD_CODE
storeAppend(http->entry, r->prefix, r->prefix_sz);
+#else
+ httpRequestSwapOut(r, http->entry);
+#endif
storeComplete(http->entry);
return;
}
@@ -1612,7 +1752,9 @@ clientProcessMiss(clientHttpRequest * http)
ErrorState *err = NULL;
debug(33, 4) ("clientProcessMiss: '%s %s'\n",
RequestMethodStr[r->method], url);
+#if OLD_CODE
debug(33, 10) ("clientProcessMiss: prefix:\n%s\n", r->prefix);
+#endif
/*
* We might have a left-over StoreEntry from a failed cache hit
* or IMS request.
@@ -2013,8 +2155,10 @@ clientReadRequest(int fd, void *data)
http->log_uri = xstrdup(urlCanonicalClean(request));
request->client_addr = conn->peer.sin_addr;
request->http_ver = http->http_ver;
+#if OLD_CODE
request->prefix = prefix;
request->prefix_sz = http->req_sz;
+#endif
if (!urlCheckRequest(request)) {
err = errorCon(ERR_UNSUP_REQ, HTTP_NOT_IMPLEMENTED);
err->src_addr = conn->peer.sin_addr;
@@ -2367,7 +2511,8 @@ clientHttpConnectionsOpen(void)
fatal("Cannot open HTTP Port");
}
-int
+#if OLD_CODE
+static int
handleConnectionHeader(int flag, char *where, char *what)
{
char *t, *p, *wh;
@@ -2411,6 +2556,7 @@ handleConnectionHeader(int flag, char *where, char *what)
xfree(wh);
return 1;
}
+#endif
void
clientHttpConnectionsClose(void)
diff --git a/src/enums.h b/src/enums.h
index 511c1bdfff..b0b21e72c3 100644
--- a/src/enums.h
+++ b/src/enums.h
@@ -191,9 +191,11 @@ typedef enum {
HDR_AUTHORIZATION,
HDR_CACHE_CONTROL,
HDR_CONNECTION,
+ HDR_CONTENT_BASE,
HDR_CONTENT_ENCODING,
HDR_CONTENT_LANGUAGE,
HDR_CONTENT_LENGTH,
+ HDR_CONTENT_LOCATION,
HDR_CONTENT_MD5,
HDR_CONTENT_RANGE,
HDR_CONTENT_TYPE,
@@ -228,6 +230,7 @@ typedef enum {
HDR_X_CACHE,
HDR_X_CACHE_LOOKUP, /* tmp hack, remove later */
HDR_X_FORWARDED_FOR,
+ HDR_X_REQUEST_URI, /* appended if ADD_X_REQUEST_URI is #defined */
HDR_X_SQUID_ERROR,
HDR_OTHER,
HDR_ENUM_END
@@ -259,6 +262,13 @@ typedef enum {
ftPContRange
} field_type;
+/* possible owners of http header */
+typedef enum {
+ hoNone,
+ hoRequest,
+ hoReply
+} http_hdr_owner_type;
+
typedef enum {
HIER_NONE,
DIRECT,
@@ -456,7 +466,6 @@ enum {
REQ_PROXYING,
REQ_REFRESH,
REQ_USED_PROXY_AUTH,
- REQ_CC_ONLY_IF_CACHED,
REQ_REDIRECTED
};
diff --git a/src/errorpage.cc b/src/errorpage.cc
index e6356c9ad8..6d3ad288aa 100644
--- a/src/errorpage.cc
+++ b/src/errorpage.cc
@@ -1,6 +1,6 @@
/*
- * $Id: errorpage.cc,v 1.133 1998/05/26 23:56:20 wessels Exp $
+ * $Id: errorpage.cc,v 1.134 1998/05/27 22:51:52 rousskov Exp $
*
* DEBUG: section 4 Error Generation
* AUTHOR: Duane Wessels
@@ -514,22 +514,20 @@ errorConvert(char token, ErrorState * err)
HttpReply *
errorBuildReply(ErrorState * err)
{
- char err_hdr[CVT_BUF_SZ];
HttpReply *rep = httpReplyCreate();
MemBuf content = errorBuildContent(err);
/* no LMT for error pages; error pages expire immediately */
httpReplySetHeaders(rep, 1.0, err->http_status, NULL, "text/html", content.size, 0, squid_curtime);
/*
* include some information for downstream caches. Implicit
- * replaceable content This isn't quite sufficient. xerrno is not
+ * replaceable content. This isn't quite sufficient. xerrno is not
* necessarily meaningful to another system, so we really should
* expand it. Additionally, we should identify ourselves. Someone
* might want to know. Someone _will_ want to know OTOH, the first
* X-CACHE-MISS entry should tell us who.
*/
- snprintf(err_hdr, CVT_BUF_SZ, "%s %d",
+ httpHeaderPutStrf(&rep->header, HDR_X_SQUID_ERROR, "%s %d",
err_type_str[err->page_id], err->xerrno);
- httpHeaderPutStr(&rep->header, HDR_X_SQUID_ERROR, err_hdr);
httpBodySet(&rep->body, content.buf, content.size + 1, NULL);
memBufClean(&content);
return rep;
diff --git a/src/http.cc b/src/http.cc
index 7553e7c85e..7824536ef9 100644
--- a/src/http.cc
+++ b/src/http.cc
@@ -1,6 +1,6 @@
/*
- * $Id: http.cc,v 1.275 1998/05/26 23:04:13 wessels Exp $
+ * $Id: http.cc,v 1.276 1998/05/27 22:51:53 rousskov Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
@@ -345,8 +345,7 @@ httpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size)
debug(11, 9) ("GOT HTTP REPLY HDR:\n---------\n%s\n----------\n",
httpState->reply_hdr);
/* Parse headers into reply structure */
- /* Old code never parsed headers if headersEnd failed, was it intentional ? @?@ @?@ */
- /* what happens if we fail to parse here? @?@ @?@ */
+ /* what happens if we fail to parse here? */
httpReplyParse(reply, httpState->reply_hdr); /* httpState->eof); */
storeTimestampsSet(entry);
/* Check if object is cacheable or not based on reply code */
@@ -618,10 +617,12 @@ httpBuildRequestHeader(request_t * request,
const HttpHeaderEntry *e;
HttpHeaderPos pos = HttpHeaderInitPos;
+#if OLD_CODE
assert(orig_request->prefix != NULL);
debug(11, 3) ("httpBuildRequestHeader:\n%s", orig_request->prefix);
- httpHeaderInit(hdr_out);
-
+#endif
+ httpHeaderInit(hdr_out, hoRequest);
+
/* append our IMS header */
if (entry && entry->lastmod > -1 && request->method == METHOD_GET)
httpHeaderPutTime(hdr_out, HDR_IF_MODIFIED_SINCE, entry->lastmod);
@@ -696,9 +697,8 @@ httpBuildRequestHeader(request_t * request,
if (orig_request->port == urlDefaultPort(orig_request->protocol)) {
httpHeaderPutStr(hdr_out, HDR_HOST, orig_request->host);
} else {
- snprintf(bbuf, BBUF_SZ, "%s:%d",
+ httpHeaderPutStrf(hdr_out, HDR_HOST, "%s:%d",
orig_request->host, (int) orig_request->port);
- httpHeaderPutStr(hdr_out, HDR_HOST, bbuf);
}
}
/* append Cache-Control, add max-age if not there already */
diff --git a/src/main.cc b/src/main.cc
index 541ecc813e..aa7327f933 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1,6 +1,6 @@
/*
- * $Id: main.cc,v 1.251 1998/05/15 15:16:25 wessels Exp $
+ * $Id: main.cc,v 1.252 1998/05/27 22:51:54 rousskov Exp $
*
* DEBUG: section 1 Startup and Main Loop
* AUTHOR: Harvest Derived
@@ -466,6 +466,7 @@ mainInitialize(void)
useragentOpenLog();
httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
httpAnonInitModule(); /* must go before accepting requests */
+ httpReplyInitModule(); /* must go before accepting replies */
errorInitialize();
accessLogInit();
#ifdef SQUID_SNMP
diff --git a/src/mime.cc b/src/mime.cc
index e4ae6fda02..a5e97988c7 100644
--- a/src/mime.cc
+++ b/src/mime.cc
@@ -1,6 +1,6 @@
/*
- * $Id: mime.cc,v 1.65 1998/05/08 23:29:28 wessels Exp $
+ * $Id: mime.cc,v 1.66 1998/05/27 22:51:55 rousskov Exp $
*
* DEBUG: section 25 MIME Parsing
* AUTHOR: Harvest Derived
@@ -219,6 +219,7 @@ headersEnd(const char *mime, size_t l)
return 0;
}
+#if UNUSED_CODE
/*
* mk_mime_hdr - Generates a MIME header using the given parameters.
* You can call mk_mime_hdr with a 'lmt = time(NULL) - ttl' to
@@ -253,9 +254,6 @@ mk_mime_hdr(char *result, const char *type, int size, time_t ttl, time_t lmt)
if (size > 0)
snprintf(content_length, 100, "Content-Length: %d\r\n", size);
- /* NOTE: don't know size of result thus didn't change
- * to snprintf(). Should be done sometime! */
-
snprintf(result, MAX_MIME, "Server: %s/%s\r\n%s%s%sContent-Type: %s\r\n%s",
appname,
version_string,
@@ -266,7 +264,7 @@ mk_mime_hdr(char *result, const char *type, int size, time_t ttl, time_t lmt)
content_length);
return 0;
}
-
+#endif
const char *
mime_get_auth(const char *hdr, const char *auth_scheme, const char **auth_field)
diff --git a/src/net_db.cc b/src/net_db.cc
index f0c3d0ee94..3039099ed6 100644
--- a/src/net_db.cc
+++ b/src/net_db.cc
@@ -1,6 +1,6 @@
/*
- * $Id: net_db.cc,v 1.110 1998/05/26 19:12:21 wessels Exp $
+ * $Id: net_db.cc,v 1.111 1998/05/27 22:51:56 rousskov Exp $
*
* DEBUG: section 37 Network Measurement Database
* AUTHOR: Duane Wessels
@@ -1053,8 +1053,6 @@ netdbExchangeStart(void *data)
#if OLD_CODE
ex->r->headers = xstrdup("\r\n");
ex->r->headers_sz = strlen(ex->r->headers);
-#else
- httpRequestSetHeaders(ex->r, METHOD_GET, uri, "");
#endif
ex->r->http_ver = 1.0;
ex->e = storeCreateEntry(uri, uri, 0, METHOD_GET);
diff --git a/src/peer_digest.cc b/src/peer_digest.cc
index adc588d8ea..06cf4bb57b 100644
--- a/src/peer_digest.cc
+++ b/src/peer_digest.cc
@@ -1,6 +1,6 @@
/*
- * $Id: peer_digest.cc,v 1.32 1998/05/26 23:45:32 rousskov Exp $
+ * $Id: peer_digest.cc,v 1.33 1998/05/27 22:51:57 rousskov Exp $
*
* DEBUG: section 72 Peer Digest Routines
* AUTHOR: Alex Rousskov
@@ -249,6 +249,7 @@ peerDigestRequest(peer * p)
requestLink(req);
assert(req);
/* add custom headers */
+#if OLD_CODE
/* rewrite this when requests get rid of "prefix" */
assert(!req->prefix);
{
@@ -258,6 +259,17 @@ peerDigestRequest(peer * p)
httpRequestSetHeaders(req, METHOD_GET, url, mb.buf);
memBufClean(&mb);
}
+#else
+ assert(!req->header.len);
+ {
+ HttpHdrCc *cc = httpHdrCcCreate();
+ EBIT_SET(cc->mask, CC_ONLY_IF_CACHED);
+ httpHeaderPutStr(&req->header, HDR_ACCEPT, StoreDigestMimeStr);
+ httpHeaderPutStr(&req->header, HDR_ACCEPT, "text/html");
+ httpHeaderPutCc(&req->header, cc);
+ httpHdrCcDestroy(cc);
+ }
+#endif
/* create fetch state structure */
fetch = memAllocate(MEM_DIGEST_FETCH_STATE);
cbdataAdd(fetch, MEM_DIGEST_FETCH_STATE);
@@ -491,7 +503,6 @@ peerDigestFetchedEnough(DigestFetchState * fetch, char *buf, ssize_t size, const
}
/* free state structures, disables digest on error */
-/* this probably should mimic httpRequestFree() but it does not! @?@ @?@ */
static void
peerDigestFetchFinish(DigestFetchState * fetch, char *buf, const char *err_msg)
{
@@ -501,7 +512,8 @@ peerDigestFetchFinish(DigestFetchState * fetch, char *buf, const char *err_msg)
const time_t expires = fetch->entry->expires;
const time_t fetch_resp_time = squid_curtime - fetch->start_time;
const int b_read = (fetch->entry->store_status == STORE_PENDING) ?
- mem->inmem_hi : mem->object_sz;
+ mem->inmem_hi : mem->object_sz;
+ const int req_len = req ? httpRequestPrefixLen(req) : 0;
assert(req);
/* final checks */
if (!err_msg) {
@@ -553,12 +565,12 @@ peerDigestFetchFinish(DigestFetchState * fetch, char *buf, const char *err_msg)
}
/* update global stats */
/* note: outgoing numbers are not precise! @?@ */
- kb_incr(&Counter.cd.kbytes_sent, req->prefix_sz);
+ kb_incr(&Counter.cd.kbytes_sent, req_len);
kb_incr(&Counter.cd.kbytes_recv, (size_t) b_read);
Counter.cd.msgs_sent++;
Counter.cd.msgs_recv++;
/* update peer stats */
- kb_incr(&peer->digest.stats.kbytes_sent, req->prefix_sz);
+ kb_incr(&peer->digest.stats.kbytes_sent, req_len);
kb_incr(&peer->digest.stats.kbytes_recv, (size_t) b_read);
peer->digest.stats.msgs_sent++;
peer->digest.stats.msgs_recv++;
diff --git a/src/protos.h b/src/protos.h
index 0e509aaeb5..e138a9f12d 100644
--- a/src/protos.h
+++ b/src/protos.h
@@ -90,7 +90,6 @@ extern void clientHttpConnectionsOpen(void);
extern void clientHttpConnectionsClose(void);
extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, int);
extern int isTcpHit(log_type);
-extern int handleConnectionHeader(int flag, char *where, char *what);
extern int commSetNonBlocking(int fd);
extern void commSetCloseOnExec(int fd);
@@ -313,15 +312,21 @@ extern int strListGetItem(const String * str, char del, const char **item, int *
extern const char *getStringPrefix(const char *str, const char *end);
extern int httpHeaderParseInt(const char *start, int *val);
extern int httpHeaderParseSize(const char *start, size_t * sz);
+#ifdef __STDC__
+extern void httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt, ...);
+#else
+extern void httpHeaderPutStrf()
+#endif
/* Http Header */
extern void httpHeaderInitModule();
extern void httpHeaderCleanModule();
/* init/clean */
-extern void httpHeaderInit(HttpHeader * hdr);
+extern void httpHeaderInit(HttpHeader * hdr, http_hdr_owner_type owner);
extern void httpHeaderClean(HttpHeader * hdr);
-/* update */
-extern void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh);
+/* append/update */
+extern void httpHeaderAppend(HttpHeader * dest, const HttpHeader * src);
+extern void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask *denied_mask);
/* parse/pack */
extern int httpHeaderParse(HttpHeader * hdr, const char *header_start, const char *header_end);
extern void httpHeaderPackInto(const HttpHeader * hdr, Packer * p);
@@ -343,6 +348,8 @@ extern const char *httpHeaderGetLastStr(const HttpHeader * hdr, http_hdr_type id
extern const char *httpHeaderGetAuth(const HttpHeader * hdr, http_hdr_type id, const char *authScheme);
extern String httpHeaderGetList(const HttpHeader * hdr, http_hdr_type id);
extern int httpHeaderDelByName(HttpHeader * hdr, const char *name);
+extern int httpHeaderDelById(HttpHeader * hdr, http_hdr_type id);
+extern void httpHeaderDelAt(HttpHeader * hdr, HttpHeaderPos pos);
/* avoid using these low level routines */
extern HttpHeaderEntry *httpHeaderGetEntry(const HttpHeader * hdr, HttpHeaderPos * pos);
extern HttpHeaderEntry *httpHeaderFindEntry(const HttpHeader * hdr, http_hdr_type id);
@@ -357,9 +364,9 @@ extern int httpMsgIsPersistent(float http_ver, const HttpHeader * hdr);
extern int httpMsgIsolateHeaders(const char **parse_start, const char **blk_start, const char **blk_end);
/* Http Reply */
+extern void httpReplyInitModule();
+/* create/destroy */
extern HttpReply *httpReplyCreate();
-extern void httpReplyInit(HttpReply * rep);
-extern void httpReplyClean(HttpReply * rep);
extern void httpReplyDestroy(HttpReply * rep);
/* reset: clean, then init */
extern void httpReplyReset(HttpReply * rep);
@@ -395,7 +402,8 @@ extern void requestDestroy(request_t *);
extern request_t *requestLink(request_t *);
extern void requestUnlink(request_t *);
extern int httpRequestParseHeader(request_t * req, const char *parse_start);
-extern void httpRequestSetHeaders(request_t *, method_t, const char *uri, const char *header_str);
+extern void httpRequestSwapOut(const request_t *req, StoreEntry *e);
+extern int httpRequestPrefixLen(const request_t *req);
extern int httpRequestHdrAllowed(const HttpHeaderEntry * e, String * strConnection);
extern void icmpOpen(void);
@@ -480,7 +488,6 @@ extern char *mime_get_header_field(const char *mime, const char *name, const cha
extern char *mime_headers_end(const char *mime);
#endif
extern size_t headersEnd(const char *, size_t);
-extern int mk_mime_hdr(char *result, const char *type, int size, time_t ttl, time_t lmt);
extern const char *mime_get_auth(const char *hdr, const char *auth_scheme, const char **auth_field);
extern void mimeInit(char *filename);
diff --git a/src/store.cc b/src/store.cc
index 909a327f52..63a88f8e52 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -1,6 +1,6 @@
/*
- * $Id: store.cc,v 1.420 1998/05/27 16:15:24 wessels Exp $
+ * $Id: store.cc,v 1.421 1998/05/27 22:52:00 rousskov Exp $
*
* DEBUG: section 20 Storage Manager
* AUTHOR: Harvest Derived
@@ -985,7 +985,7 @@ void
storeTimestampsSet(StoreEntry * entry)
{
time_t served_date = -1;
- HttpReply *reply = entry->mem_obj->reply;
+ const HttpReply *reply = entry->mem_obj->reply;
served_date = reply->date;
if (served_date < 0)
served_date = squid_curtime;
diff --git a/src/structs.h b/src/structs.h
index ce72dbe018..8cb8acc97e 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -488,7 +488,7 @@ struct _HttpStatusLine {
*/
struct _HttpBody {
/* private, never dereference these */
- char *buf; /* null terminating _text_ buffer, not for binary stuff */
+ char *buf; /* null terminated _text_ buffer, not for binary stuff */
FREE *freefunc; /* used to free() .buf */
int size;
};
@@ -560,6 +560,8 @@ struct _HttpHeader {
/* protected, do not use these, use interface functions instead */
Array 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' */
};
struct _HttpReply {
@@ -671,7 +673,7 @@ struct _clientHttpRequest {
off_t offset;
size_t size;
} out;
- size_t req_sz;
+ size_t req_sz; /* raw request size on input, not current request size */
StoreEntry *entry;
StoreEntry *old_entry;
log_type log_type;
@@ -1109,15 +1111,7 @@ struct _request_t {
char *headers;
size_t headers_sz;
#else
-#if TEST_STAGE_CODE
- const char *prefix;
- const size_t prefix_sz;
- const HttpHeader header;
-#else
- char *prefix;
- size_t prefix_sz;
HttpHeader header;
-#endif
#endif
char *body;
size_t body_sz;
diff --git a/src/typedefs.h b/src/typedefs.h
index b19116179f..6ebfedaca8 100644
--- a/src/typedefs.h
+++ b/src/typedefs.h
@@ -129,6 +129,7 @@ typedef struct _usecEntry usecEntry;
typedef void AIOCB(void *, int aio_return, int aio_errno);
typedef void CWCB(int fd, char *, size_t size, int flag, void *data);
typedef void CNCB(int fd, int status, void *);
+
typedef void FREE(void *);
typedef void FOCB(void *, int fd, int errcode);
typedef void EVH(void *);
diff --git a/src/urn.cc b/src/urn.cc
index 64763ada87..f5b17780ce 100644
--- a/src/urn.cc
+++ b/src/urn.cc
@@ -1,7 +1,7 @@
/*
*
- * $Id: urn.cc,v 1.33 1998/05/11 18:44:48 rousskov Exp $
+ * $Id: urn.cc,v 1.34 1998/05/27 22:52:03 rousskov Exp $
*
* DEBUG: section 52 URN Parsing
* AUTHOR: Kostas Anagnostakis
@@ -138,7 +138,7 @@ urnStart(request_t * r, StoreEntry * e)
urlres_r->headers = xstrdup("Accept: text/plain\r\n\r\n");
urlres_r->headers_sz = strlen(urlres_r->headers);
#else
- httpRequestSetHeaders(urlres_r, METHOD_GET, urlres, "Accept: text/plain\r\n");
+ httpHeaderPutStr(&urlres_r->header, HDR_ACCEPT, "text/plain");
#endif
if ((urlres_e = storeGet(k)) == NULL) {
urlres_e = storeCreateEntry(urlres, urlres, 0, METHOD_GET);
diff --git a/src/wais.cc b/src/wais.cc
index 4d7cb3cf02..096b4ef04c 100644
--- a/src/wais.cc
+++ b/src/wais.cc
@@ -1,6 +1,6 @@
/*
- * $Id: wais.cc,v 1.107 1998/05/11 18:44:48 rousskov Exp $
+ * $Id: wais.cc,v 1.108 1998/05/27 22:52:04 rousskov Exp $
*
* DEBUG: section 24 WAIS Relay
* AUTHOR: Harvest Derived
@@ -112,7 +112,7 @@ typedef struct {
method_t method;
char *relayhost;
int relayport;
- char *request_hdr;
+ const HttpHeader *request_hdr;
char request[MAX_URL];
} WaisStateData;
@@ -265,10 +265,15 @@ static void
waisSendRequest(int fd, void *data)
{
WaisStateData *waisState = data;
+#if OLD_CODE
int len = strlen(waisState->request) + 4;
char *buf = NULL;
+#else
+ MemBuf mb;
+#endif
const char *Method = RequestMethodStr[waisState->method];
debug(24, 5) ("waisSendRequest: FD %d\n", fd);
+#if OLD_CODE
if (Method)
len += strlen(Method);
if (waisState->request_hdr)
@@ -281,6 +286,18 @@ waisSendRequest(int fd, void *data)
snprintf(buf, len + 1, "%s %s\r\n", Method, waisState->request);
debug(24, 6) ("waisSendRequest: buf: %s\n", buf);
comm_write(fd, buf, len, waisSendComplete, waisState, xfree);
+#else
+ memBufPrintf(&mb, "%s %s", Method, waisState->request);
+ if (waisState->request_hdr) {
+ Packer p;
+ packerToMemInit(&p, &mb);
+ httpHeaderPackInto(waisState->request_hdr, &p);
+ packerClean(&p);
+ }
+ memBufPrintf(&mb, "\r\n");
+ debug(24, 6) ("waisSendRequest: buf: %s\n", mb.buf);
+ comm_write_mbuf(fd, mb, waisSendComplete, waisState);
+#endif
if (EBIT_TEST(waisState->entry->flag, ENTRY_CACHABLE))
storeSetPublicKey(waisState->entry); /* Make it public */
}
@@ -322,7 +339,7 @@ waisStart(request_t * request, StoreEntry * entry)
waisState->method = method;
waisState->relayhost = Config.Wais.relayHost;
waisState->relayport = Config.Wais.relayPort;
- waisState->request_hdr = request->prefix;
+ waisState->request_hdr = &request->header;
waisState->fd = fd;
waisState->entry = entry;
xstrncpy(waisState->request, url, MAX_URL);