This is a resubmission of the 3.0 patch for Bug #2001. This time
including the related fix for reply_header_max_size making it check the
limit while reading the header and not after..
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [EMAIL PROTECTED]
#   djj9wfqy63noyuy4
# target_branch: http://www.squid-cache.org/bzr/squid3/branches\
#   /SQUID_3_0/
# testament_sha1: 309c90bdcc487ef284f323dbc5e63b6eb80c0302
# timestamp: 2008-04-08 01:16:38 +0200
# source_branch: http://www.henriknordstrom.net/bzr/squid3/hno\
#   /largeresp-3.0
# base_revision_id: [EMAIL PROTECTED]
#   kfyafifqcq0retgb
# 
# Begin patch
=== modified file 'src/HttpMsg.cc'
--- src/HttpMsg.cc	2007-08-13 23:20:50 +0000
+++ src/HttpMsg.cc	2008-04-07 23:15:53 +0000
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpMsg.cc,v 1.43 2007/08/13 17:20:51 hno Exp $
+ * $Id: HttpMsg.cc,v 1.44 2007/12/21 23:50:24 hno Exp $
  *
  * DEBUG: section 74    HTTP Message
  * AUTHOR: Alex Rousskov
@@ -153,6 +153,14 @@
     // TODO: Remove? httpReplyParseStep() should do similar checks
     const size_t hdr_len = headersEnd(buf->content(), buf->contentSize());
 
+    // TODO: move to httpReplyParseStep()
+    if (hdr_len > Config.maxReplyHeaderSize || hdr_len <= 0 && (size_t)buf->contentSize() > Config.maxReplyHeaderSize) {
+        debugs(58, 1, "HttpMsg::parse: Too large reply header (" <<
+               hdr_len << " > " << Config.maxReplyHeaderSize);
+        *error = HTTP_HEADER_TOO_LARGE;
+        return false;
+    }
+
     if (hdr_len <= 0) {
         debugs(58, 3, "HttpMsg::parse: failed to find end of headers " <<
                "(eof: " << eof << ") in '" << buf->content() << "'");
@@ -163,14 +171,6 @@
         return false;
     }
 
-    // TODO: move to httpReplyParseStep()
-    if (hdr_len > Config.maxReplyHeaderSize) {
-        debugs(58, 1, "HttpMsg::parse: Too large reply header (" <<
-               hdr_len << " > " << Config.maxReplyHeaderSize);
-        *error = HTTP_HEADER_TOO_LARGE;
-        return false;
-    }
-
     if (!sanityCheckStartLine(buf, error)) {
         debugs(58,1, HERE << "first line of HTTP message is invalid");
         *error = HTTP_INVALID_HEADER;

=== modified file 'src/HttpReply.cc'
--- src/HttpReply.cc	2007-11-26 20:09:54 +0000
+++ src/HttpReply.cc	2008-03-30 14:29:57 +0000
@@ -496,3 +496,17 @@
 
     return expectBody;
 }
+
+HttpReply *
+HttpReply::clone() const
+{
+    HttpReply *rep = new HttpReply();
+    rep->header.append(&header);
+    rep->hdrCacheInit();
+    rep->hdr_sz = hdr_sz;
+    rep->http_ver = http_ver;
+    rep->pstate = pstate;
+    rep->protocol = protocol;
+    rep->sline = sline;
+    return rep;
+}

=== modified file 'src/HttpReply.h'
--- src/HttpReply.h	2007-08-13 23:20:50 +0000
+++ src/HttpReply.h	2008-03-30 14:29:57 +0000
@@ -122,6 +122,11 @@
 
     void packHeadersInto(Packer * p) const;
 
+    /// Clone this reply.
+    /// Could be done as a copy-contructor but we do not want to
+    /// accidently copy a HttpReply..
+    HttpReply *clone() const;
+
 private:
     /* initialize */
     void init();

=== modified file 'src/MemBuf.h'
--- src/MemBuf.h	2006-08-21 06:50:40 +0000
+++ src/MemBuf.h	2008-04-06 00:35:11 +0000
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: MemBuf.h,v 1.8 2006/08/21 00:50:41 robertc Exp $
+ * $Id: MemBuf.h,v 1.9 2007/12/21 23:48:04 hno Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -60,6 +60,7 @@
 
     // these space-related methods assume no growth and allow 0-termination
     char *space() { return buf + size; } // space to add data
+    char *space(mb_size_t required) { if (size + required > capacity) grow(size + required); return buf + size; } // space to add data
 
     mb_size_t spaceSize() const;
     bool hasSpace() const { return size+1 < capacity; }

=== modified file 'src/client_side_reply.cc'
--- src/client_side_reply.cc	2008-03-14 04:45:16 +0000
+++ src/client_side_reply.cc	2008-03-30 14:29:57 +0000
@@ -352,68 +352,47 @@
         sendClientOldEntry();
     }
 
-    // we have a partial reply from the origin
-    else if (STORE_PENDING == http->storeEntry()->store_status && 0 == status) {
-        // header is too large, send old entry
-
-        if (reqsize >= HTTP_REQBUF_SZ) {
-            debugs(88, 3, "handleIMSReply: response from origin is too large '" << http->storeEntry()->url() << "', sending old entry to client" );
-            http->logType = LOG_TCP_REFRESH_FAIL;
-            sendClientOldEntry();
-        }
-
-        // everything looks fine, we're just waiting for more data
-        else {
-            debugs(88, 3, "handleIMSReply: incomplete headers for '" << http->storeEntry()->url() << "', waiting for more data" );
-            reqofs = reqsize;
-            waitForMoreData();
-        }
-    }
-
-    // we have a reply from the origin
+    HttpReply *old_rep = (HttpReply *) old_entry->getReply();
+
+    // origin replied 304
+
+    if (status == HTTP_NOT_MODIFIED) {
+	http->logType = LOG_TCP_REFRESH_UNMODIFIED;
+
+	// update headers on existing entry
+	HttpReply *old_rep = (HttpReply *) old_entry->getReply();
+	old_rep->updateOnNotModified(http->storeEntry()->getReply());
+	old_entry->timestampsSet();
+
+	// if client sent IMS
+
+	if (http->request->flags.ims) {
+	    // forward the 304 from origin
+	    debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and forwarding 304 to client");
+	    sendClientUpstreamResponse();
+	} else {
+	    // send existing entry, it's still valid
+	    debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and sending " <<
+		   old_rep->sline.status << " to client");
+	    sendClientOldEntry();
+	}
+    }
+
+    // origin replied with a non-error code
+    else if (status > HTTP_STATUS_NONE && status < HTTP_INTERNAL_SERVER_ERROR) {
+	// forward response from origin
+	http->logType = LOG_TCP_REFRESH_MODIFIED;
+	debugs(88, 3, "handleIMSReply: origin replied " << status << ", replacing existing entry and forwarding to client");
+	sendClientUpstreamResponse();
+    }
+
+    // origin replied with an error
     else {
-        HttpReply *old_rep = (HttpReply *) old_entry->getReply();
-
-        // origin replied 304
-
-        if (status == HTTP_NOT_MODIFIED) {
-            http->logType = LOG_TCP_REFRESH_UNMODIFIED;
-
-            // update headers on existing entry
-            HttpReply *old_rep = (HttpReply *) old_entry->getReply();
-            old_rep->updateOnNotModified(http->storeEntry()->getReply());
-            old_entry->timestampsSet();
-
-            // if client sent IMS
-
-            if (http->request->flags.ims) {
-                // forward the 304 from origin
-                debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and forwarding 304 to client");
-                sendClientUpstreamResponse();
-            } else {
-                // send existing entry, it's still valid
-                debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and sending " <<
-                       old_rep->sline.status << " to client");
-                sendClientOldEntry();
-            }
-        }
-
-        // origin replied with a non-error code
-        else if (status > HTTP_STATUS_NONE && status < HTTP_INTERNAL_SERVER_ERROR) {
-            // forward response from origin
-            http->logType = LOG_TCP_REFRESH_MODIFIED;
-            debugs(88, 3, "handleIMSReply: origin replied " << status << ", replacing existing entry and forwarding to client");
-            sendClientUpstreamResponse();
-        }
-
-        // origin replied with an error
-        else {
-            // ignore and let client have old entry
-            http->logType = LOG_TCP_REFRESH_FAIL;
-            debugs(88, 3, "handleIMSReply: origin replied with error " <<
-                   status << ", sending old entry (" << old_rep->sline.status << ") to client");
-            sendClientOldEntry();
-        }
+	// ignore and let client have old entry
+	http->logType = LOG_TCP_REFRESH_FAIL;
+	debugs(88, 3, "handleIMSReply: origin replied with error " <<
+	       status << ", sending old entry (" << old_rep->sline.status << ") to client");
+	sendClientOldEntry();
     }
 }
 
@@ -472,33 +451,6 @@
     /* update size of the request */
     reqsize = result.length + reqofs;
 
-    if (e->getReply()->sline.status == 0) {
-        /*
-         * we don't have full reply headers yet; either wait for more or
-         * punt to clientProcessMiss.
-         */
-
-        if (e->mem_status == IN_MEMORY || e->store_status == STORE_OK) {
-            processMiss();
-        } else if (result.length + reqofs >= HTTP_REQBUF_SZ
-                   && http->out.offset == 0) {
-            processMiss();
-        } else {
-            debugs(88, 3, "clientCacheHit: waiting for HTTP reply headers");
-            reqofs += result.length;
-            assert(reqofs <= HTTP_REQBUF_SZ);
-            /* get the next users' buffer */
-            StoreIOBuffer tempBuffer;
-            tempBuffer.offset = http->out.offset + reqofs;
-            tempBuffer.length = next()->readBuffer.length - reqofs;
-            tempBuffer.data = next()->readBuffer.data + reqofs;
-            storeClientCopy(sc, e,
-                            tempBuffer, CacheHit, this);
-        }
-
-        return;
-    }
-
     /*
      * Got the headers, now grok them
      */
@@ -1371,32 +1323,14 @@
 
 
 void
-clientReplyContext::buildReply(const char *buf, size_t size)
+clientReplyContext::cloneReply()
 {
-    size_t k = headersEnd(buf, size);
-
-    if (!k)
-        return;
-
     assert(reply == NULL);
 
-    HttpReply *rep = new HttpReply;
+    HttpReply *rep = http->storeEntry()->getReply()->clone();
 
     reply = HTTPMSGLOCK(rep);
 
-    if (!reply->parseCharBuf(buf, k)) {
-        /* parsing failure, get rid of the invalid reply */
-        HTTPMSGUNLOCK(reply);
-
-        if (http->request->range) {
-            debugs(0,0,HERE << "look for bug here");
-            /* this will fail and destroy request->range */
-            //          clientBuildRangeHeader(http, reply);
-        }
-
-        return;
-    }
-
     /* enforce 1.0 reply version */
     reply->sline.version = HttpVersion(1,0);
 
@@ -1703,32 +1637,6 @@
     return getNextNode();
 }
 
-void
-clientReplyContext::waitForMoreData ()
-{
-    debugs(88, 5, "clientReplyContext::waitForMoreData: Waiting for more data to parse reply headers in client side.");
-    /* We don't have enough to parse the metadata yet */
-    /* TODO: the store should give us out of band metadata and
-     * obsolete this routine 
-     */
-    /* wait for more to arrive */
-    startSendProcess();
-}
-
-void
-clientReplyContext::startSendProcess()
-{
-    debugs(88, 5, "clientReplyContext::startSendProcess: triggering store read to SendMoreData");
-    assert(reqofs <= HTTP_REQBUF_SZ);
-    /* TODO: copy into the supplied buffer */
-    StoreIOBuffer tempBuffer;
-    tempBuffer.offset = reqofs;
-    tempBuffer.length = next()->readBuffer.length - reqofs;
-    tempBuffer.data = next()->readBuffer.data + reqofs;
-    storeClientCopy(sc, http->storeEntry(),
-                    tempBuffer, SendMoreData, this);
-}
-
 /*
  * Calculates the maximum size allowed for an HTTP response
  */
@@ -1841,8 +1749,10 @@
     http->loggingEntry(http->storeEntry());
 
     ssize_t body_size = reqofs - reply->hdr_sz;
-
-    assert(body_size >= 0);
+    if (body_size < 0) {
+	reqofs = reply->hdr_sz;
+	body_size = 0;
+    }
 
     debugs(88, 3, "clientReplyContext::sendMoreData: Appending " <<
            (int) body_size << " bytes after " << reply->hdr_sz <<
@@ -1872,7 +1782,7 @@
 
     StoreIOBuffer tempBuffer;
     char *buf = next()->readBuffer.data;
-    char *body_buf = buf + reply->hdr_sz;
+    char *body_buf = buf + reply->hdr_sz - next()->readBuffer.offset;
 
     //Server side may disable ranges under some circumstances.
 
@@ -1916,23 +1826,11 @@
 
     char *body_buf = buf;
 
-    /* This is always valid until we get the headers as metadata from
-     * storeClientCopy. 
-     * Then it becomes reqofs == next->readBuffer.offset()
-     */
-    assert(reqofs == 0 || flags.storelogiccomplete);
-
-    if (flags.headersSent && buf != result.data) {
+    if (buf != result.data) {
         /* we've got to copy some data */
         assert(result.length <= next()->readBuffer.length);
         xmemcpy(buf, result.data, result.length);
         body_buf = buf;
-    } else if (!flags.headersSent &&
-               buf + reqofs !=result.data) {
-        /* we've got to copy some data */
-        assert(result.length + reqofs <= next()->readBuffer.length);
-        xmemcpy(buf + reqofs, result.data, result.length);
-        body_buf = buf;
     }
 
     /* We've got the final data to start pushing... */
@@ -1971,38 +1869,23 @@
         return;
     }
 
-    buildReply(buf, reqofs);
-
-    if (reply) {
-
-        /* handle headers */
-
-        if (Config.onoff.log_mime_hdrs) {
-            size_t k;
-
-            if ((k = headersEnd(buf, reqofs))) {
-                safe_free(http->al.headers.reply);
-                http->al.headers.reply = (char *)xcalloc(k + 1, 1);
-                xstrncpy(http->al.headers.reply, buf, k);
-            }
-        }
-
-        holdingBuffer = result;
-        processReplyAccess();
-        return;
-
-    } else if (reqofs < HTTP_REQBUF_SZ && entry->store_status == STORE_PENDING) {
-        waitForMoreData();
-        return;
-    } else {
-        debugs(88, 0, "clientReplyContext::sendMoreData: Unable to parse reply headers within a single HTTP_REQBUF_SZ length buffer");
-        StoreIOBuffer tempBuffer;
-        tempBuffer.flags.error = 1;
-        /* XXX FIXME: make an html error page here */
-        sendStreamError(tempBuffer);
-        return;
+    cloneReply();
+
+    /* handle headers */
+
+    if (Config.onoff.log_mime_hdrs) {
+	size_t k;
+
+	if ((k = headersEnd(buf, reqofs))) {
+	    safe_free(http->al.headers.reply);
+	    http->al.headers.reply = (char *)xcalloc(k + 1, 1);
+	    xstrncpy(http->al.headers.reply, buf, k);
+	}
     }
-    fatal ("clientReplyContext::sendMoreData: Unreachable code reached \n");
+
+    holdingBuffer = result;
+    processReplyAccess();
+    return;
 }
 
 

=== modified file 'src/client_side_reply.h'
--- src/client_side_reply.h	2008-02-26 06:08:50 +0000
+++ src/client_side_reply.h	2008-03-30 14:29:57 +0000
@@ -124,15 +124,13 @@
     bool errorInStream(StoreIOBuffer const &result, size_t const &sizeToProcess)const ;
     void sendStreamError(StoreIOBuffer const &result);
     void pushStreamData(StoreIOBuffer const &result, char *source);
-    void waitForMoreData ();
     clientStreamNode * next() const;
-    void startSendProcess();
     StoreIOBuffer holdingBuffer;
     HttpReply *reply;
     void processReplyAccess();
     static PF ProcessReplyAccessResult;
     void processReplyAccessResult(bool accessAllowed);
-    void buildReply(const char *buf, size_t size);
+    void cloneReply();
     void buildReplyHeader ();
     bool alwaysAllowResponse(http_status sline) const;
     int checkTransferDone();

=== modified file 'src/http.cc'
--- src/http.cc	2007-11-19 05:00:58 +0000
+++ src/http.cc	2008-03-30 16:38:00 +0000
@@ -1213,12 +1213,16 @@
      * handler until we get a notification from someone that
      * its okay to read again.
      */
-    if (read_sz < 2)
-        return;
+    if (read_sz < 2) {
+	if (flags.headers_parsed)
+	    return;
+	else
+	    read_sz = 1024;
+    }
 
     if (flags.do_next_read) {
-        flags.do_next_read = 0;
-        entry->delayAwareRead(fd, readBuf->space(), read_sz, ReadReplyWrapper, this);
+	flags.do_next_read = 0;
+	entry->delayAwareRead(fd, readBuf->space(read_sz), read_sz, ReadReplyWrapper, this);
     }
 }
 

# Begin bundle
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
tK12hxofbB+0bGiD4FEf/F3JFOFCQjy5iZA=

Reply via email to