]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
- removed ascii headers from reply and request structures
authorrousskov <>
Thu, 28 May 1998 04:51:37 +0000 (04:51 +0000)
committerrousskov <>
Thu, 28 May 1998 04:51:37 +0000 (04:51 +0000)
- 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

27 files changed:
ChangeLog
TODO
src/HttpBody.cc
src/HttpHdrExtField.cc
src/HttpHeader.cc
src/HttpHeaderTools.cc
src/HttpMsg.cc [new file with mode: 0644]
src/HttpReply.cc
src/HttpRequest.cc
src/Makefile.in
src/MemBuf.cc
src/access_log.cc
src/asn.cc
src/client_side.cc
src/enums.h
src/errorpage.cc
src/http.cc
src/main.cc
src/mime.cc
src/net_db.cc
src/peer_digest.cc
src/protos.h
src/store.cc
src/structs.h
src/typedefs.h
src/urn.cc
src/wais.cc

index 5fe353cdf666d1134197e079ac0ca4a2e8607490..890561aad6c08c43cd358d2908bebfaffa7778a0 100644 (file)
--- 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 5476fa3209bb470b8a76a11dfa07157ed7a95166..4c0fd7a41d4a7994f8ef05d02f55a49036dc3a68 100644 (file)
--- 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)
index d006a70e69353c724f737cb99ed7362c7326d378..340817192a967350dc2ddd03cead76326e6b8532 100644 (file)
@@ -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);
 }
index 10ae40ee01056d635813c5e85782bbe1d4bef1ca..c1b7fa0f9e45777d770c3b91d75be3f4727be95f 100644 (file)
@@ -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);
index e4ab1d3884887a4f3f23c1271d34d77fda7c19e1..baea9e766444e65d51d6d0631d861545f7109787 100644 (file)
@@ -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", "<br>");
     }
-    storeAppendPrintf(e, "%s\n", "<hr size=1 noshade>");
     /* field stats */
     storeAppendPrintf(e, "<h3>Http Fields Stats (replies and requests)</h3>\n");
     storeAppendPrintf(e, "%2s\t %-20s\t %5s\t %6s\t %6s\n",
index 65f5e5fef5b98a9afa4ff6c2c6b3777b5fd3a973..23db8abb66c1eae4ff54faab260dd1e60683cedb 100644 (file)
@@ -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 (file)
index 0000000..33a6e11
--- /dev/null
@@ -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");
+    }
+}
index 2d5b3833a9951a0546e013660972af025ffd54ac..e9629d5c60458dcaa581dc8eb249df65cf14bc6a 100644 (file)
@@ -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
 
 /* 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");
-    }
-}
index ced595ab86a1199746170cf9e2a5aee7ed5d235e..4d8ed75962b0a47a504bd2a04b10eb6113112d50 100644 (file)
@@ -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 <crlf> 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
index 9a6f1670554986147d5d52382fc9865e203a9732..d3343a91779f28eed28e75d37a83c18f43b4bf40 100644 (file)
@@ -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 \
index f8f752cd15e83a8942975243c8e10d7eaac89a06..722b3216b76ca5963b4ac69d91b70f5d2866ebe9 100644 (file)
@@ -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 */
 }
 
 /*
index 6b9a200c69d24f37687cd278848bcca2987a942c..e996739c2951b58ac67b9ec6a6a1112ff33b0dab 100644 (file)
@@ -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;
index dd5f844efd49a1118b914c1ef028b648e031b80e..99d5a584b12a36e91e025e15b5233170040c2b12 100644 (file)
@@ -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);
index 187df63419b69026a2cd0f095507dd88680d7dbf..29e398e8722774ee8b8554f9c084474ba52a913a 100644 (file)
@@ -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)
index 511c1bdfff2fdef41a0a14c79dd836a6680419f0..b0b21e72c3554171e1bf17f7669485af83c3009b 100644 (file)
@@ -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
 };
 
index e6356c9ad8eb7d74aa8be67175a567dd62af966f..6d3ad288aa645955fab65ff4b76051e0d55f14f8 100644 (file)
@@ -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;
index 7553e7c85ec26cb2f55f16620cc8da306e972f58..7824536ef9b01b01ad9d195222c5be65704b3d45 100644 (file)
@@ -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 */
index 541ecc813e8026e4b3cb85433caad352f5e98258..aa7327f9334b1f6aa6ed9ab54b155c0dca29afca 100644 (file)
@@ -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
index e4ae6fda02575eba0b7b8cefba1f34a0792d063b..a5e97988c7e178dc2cc063b500b578a04c2db263 100644 (file)
@@ -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)
index f0c3d0ee9472bc1c253a99a284e75b5ec65ce529..3039099ed61d9f61bf09fe3e4f95f0d49f085f58 100644 (file)
@@ -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);
index adc588d8ea382c9765bd68d537bf95faca70f9ec..06cf4bb57b92764eb00d25666a4d6462f686a791 100644 (file)
@@ -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++;
index 0e509aaeb5372dffcc0ad00cdaa07d62c2c34df7..e138a9f12dfd0ec49c5f02e381719a2b56aa49c9 100644 (file)
@@ -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);
index 909a327f52cf94abe03aafaeadeb20fe830f09d6..63a88f8e5255ae5284cfb3cf0dd3a7c49a1f1440 100644 (file)
@@ -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;
index ce72dbe018955b1fd2b053ff6631b699c3761146..8cb8acc97eeb2513c8cd26d517b68579a85eb82a 100644 (file)
@@ -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;
index b19116179f08860a43b55047f256b6afad82fb56..6ebfedaca83a3f15337a56a115abb1ed25f41f32 100644 (file)
@@ -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 *);
index 64763ada872b57e18dca7f804a35a02c7949082c..f5b17780ceb7cb9f1b7e4534a9241fe6688332e0 100644 (file)
@@ -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);
index 4d7cb3cf02ba3bb8c791064b914e30e158838717..096b4ef04ceb6e04ca3a455429cb96ff2df2b34e 100644 (file)
@@ -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);