]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Merged largeresp
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Sun, 30 Mar 2008 14:29:57 +0000 (16:29 +0200)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Sun, 30 Mar 2008 14:29:57 +0000 (16:29 +0200)
src/HttpReply.cc
src/HttpReply.h
src/client_side_reply.cc
src/client_side_reply.h

index 36e97b3ed0af7d995bce7dc72203f53b69f86c98..07e4c93abf53b6fe4174efa5e3c8ab154ae5dc8d 100644 (file)
@@ -496,3 +496,17 @@ HttpReply::expectingBody(method_t req_method, int64_t& theSize) const
 
     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;
+}
index 6dfb3d0705d855eb5a1ae67dbe336230ab22ed7a..0e4ca3ef283e9fa9c186840a33a2a745184bb84d 100644 (file)
@@ -122,6 +122,11 @@ public:
 
     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();
index cf9e5df34ee2af5c6a355d2c3c1851ebf5e464fc..cd6d0c93d0d9209430849f8d7860e70827c0818f 100644 (file)
@@ -352,68 +352,47 @@ clientReplyContext::handleIMSReply(StoreIOBuffer result)
         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();
-        }
+    HttpReply *old_rep = (HttpReply *) old_entry->getReply();
 
-        // 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
-    else {
-        HttpReply *old_rep = (HttpReply *) old_entry->getReply();
+    // origin replied 304
 
-        // origin replied 304
+    if (status == HTTP_NOT_MODIFIED) {
+       http->logType = LOG_TCP_REFRESH_UNMODIFIED;
 
-        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();
 
-            // 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 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();
-            }
-        }
+       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 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();
-        }
+    // 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();
     }
 }
 
@@ -472,33 +451,6 @@ clientReplyContext::cacheHit(StoreIOBuffer result)
     /* 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 @@ clientReplyContext::buildReplyHeader()
 
 
 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 @@ clientReplyContext::next() const
     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 @@ clientReplyContext::processReplyAccessResult(bool accessAllowed)
     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 @@ clientReplyContext::processReplyAccessResult(bool accessAllowed)
 
     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 @@ clientReplyContext::sendMoreData (StoreIOBuffer result)
 
     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 @@ clientReplyContext::sendMoreData (StoreIOBuffer result)
         return;
     }
 
-    buildReply(buf, reqofs);
+    cloneReply();
 
-    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);
-            }
-        }
+    /* handle headers */
 
-        holdingBuffer = result;
-        processReplyAccess();
-        return;
+    if (Config.onoff.log_mime_hdrs) {
+       size_t k;
 
-    } 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;
+       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;
 }
 
 
index df572ac5b28b9e4abab8eca1d8c73e88c5af9fb7..be06131b01b4c40d7cfa9ef16dbacf41c73e33e0 100644 (file)
@@ -124,15 +124,13 @@ private:
     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();