# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: henrik@henriknordstrom.net-20080330163800-\ # m06h0iqek6nq8fyb # target_branch: /data/bzr/squid3/branches/SQUID_3_0 # testament_sha1: c5c5604c9077c76cd2fc94aecdb4620126c26299 # timestamp: 2008-03-30 18:45:34 +0200 # source_branch: http://www.henriknordstrom.net/bzr/squid3/hno\ # /largeresp-3.0 # base_revision_id: amosjeffries@squid-cache.org-20080329065653-\ # nxa2s3jig4ce6nwb # # Begin patch === 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/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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 kAoOMgw=