|
 |
d3a8ee |
------------------------------------------------------------
|
|
 |
d3a8ee |
revno: 12677
|
|
 |
d3a8ee |
revision-id: squid3@treenet.co.nz-20140309023519-t6wmqou7m816tgnl
|
|
 |
d3a8ee |
parent: squid3@treenet.co.nz-20140309021524-wtxyrfoagz95ezwp
|
|
 |
d3a8ee |
author: Alex Rousskov <rousskov@measurement-factory.com>
|
|
 |
d3a8ee |
committer: Amos Jeffries <squid3@treenet.co.nz>
|
|
 |
d3a8ee |
branch nick: 3.3
|
|
 |
d3a8ee |
timestamp: Sat 2014-03-08 19:35:19 -0700
|
|
 |
d3a8ee |
message:
|
|
 |
d3a8ee |
Avoid assertions on Range requests that trigger Squid-generated errors.
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
Added HttpRequest::ignoreRange() to encapsulate range ignoring logic.
|
|
 |
d3a8ee |
Currently the new method only contains the code common among all callers. More
|
|
 |
d3a8ee |
work is needed to check whether further caller homogenization is possible.
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
Documented that ClientSocketContext::getNextRangeOffset() may sometimes be
|
|
 |
d3a8ee |
called before it is ready to do its job.
|
|
 |
d3a8ee |
------------------------------------------------------------
|
|
 |
d3a8ee |
# Bazaar merge directive format 2 (Bazaar 0.90)
|
|
 |
d3a8ee |
# revision_id: squid3@treenet.co.nz-20140309023519-t6wmqou7m816tgnl
|
|
 |
d3a8ee |
# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.3
|
|
 |
d3a8ee |
# testament_sha1: 0e0335663a55b0dca989893fb98f81d8d9604572
|
|
 |
d3a8ee |
# timestamp: 2014-03-09 02:37:50 +0000
|
|
 |
d3a8ee |
# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.3
|
|
 |
d3a8ee |
# base_revision_id: squid3@treenet.co.nz-20140309021524-\
|
|
 |
d3a8ee |
# wtxyrfoagz95ezwp
|
|
 |
d3a8ee |
#
|
|
 |
d3a8ee |
# Begin patch
|
|
 |
d3a8ee |
=== modified file 'src/HttpRequest.cc'
|
|
 |
d3a8ee |
--- src/HttpRequest.cc 2013-09-11 01:03:45 +0000
|
|
 |
d3a8ee |
+++ src/HttpRequest.cc 2014-03-09 02:35:19 +0000
|
|
 |
d3a8ee |
@@ -658,6 +658,20 @@
|
|
 |
d3a8ee |
return rangeOffsetLimit;
|
|
 |
d3a8ee |
}
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
+void
|
|
 |
d3a8ee |
+HttpRequest::ignoreRange(const char *reason)
|
|
 |
d3a8ee |
+{
|
|
 |
d3a8ee |
+ if (range) {
|
|
 |
d3a8ee |
+ debugs(73, 3, static_cast<void*>(range) << " for " << reason);
|
|
 |
d3a8ee |
+ delete range;
|
|
 |
d3a8ee |
+ range = NULL;
|
|
 |
d3a8ee |
+ }
|
|
 |
d3a8ee |
+ // Some callers also reset isRanged but it may not be safe for all callers:
|
|
 |
d3a8ee |
+ // isRanged is used to determine whether a weak ETag comparison is allowed,
|
|
 |
d3a8ee |
+ // and that check should not ignore the Range header if it was present.
|
|
 |
d3a8ee |
+ // TODO: Some callers also delete HDR_RANGE, HDR_REQUEST_RANGE. Should we?
|
|
 |
d3a8ee |
+}
|
|
 |
d3a8ee |
+
|
|
 |
d3a8ee |
bool
|
|
 |
d3a8ee |
HttpRequest::canHandle1xx() const
|
|
 |
d3a8ee |
{
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
=== modified file 'src/HttpRequest.h'
|
|
 |
d3a8ee |
--- src/HttpRequest.h 2013-07-26 12:21:20 +0000
|
|
 |
d3a8ee |
+++ src/HttpRequest.h 2014-03-09 02:35:19 +0000
|
|
 |
d3a8ee |
@@ -246,6 +246,8 @@
|
|
 |
d3a8ee |
*/
|
|
 |
d3a8ee |
CbcPointer<ConnStateData> clientConnectionManager;
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
+ /// forgets about the cached Range header (for a reason)
|
|
 |
d3a8ee |
+ void ignoreRange(const char *reason);
|
|
 |
d3a8ee |
int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
private:
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
=== modified file 'src/client_side.cc'
|
|
 |
d3a8ee |
--- src/client_side.cc 2013-09-29 17:28:00 +0000
|
|
 |
d3a8ee |
+++ src/client_side.cc 2014-03-09 02:35:19 +0000
|
|
 |
d3a8ee |
@@ -1281,9 +1281,7 @@
|
|
 |
d3a8ee |
* offset data, but we won't be requesting it.
|
|
 |
d3a8ee |
* So, we can either re-request, or generate an error
|
|
 |
d3a8ee |
*/
|
|
 |
d3a8ee |
- debugs(33, 3, "clientBuildRangeHeader: will not do ranges: " << range_err << ".");
|
|
 |
d3a8ee |
- delete http->request->range;
|
|
 |
d3a8ee |
- http->request->range = NULL;
|
|
 |
d3a8ee |
+ http->request->ignoreRange(range_err);
|
|
 |
d3a8ee |
} else {
|
|
 |
d3a8ee |
/* XXX: TODO: Review, this unconditional set may be wrong. - TODO: review. */
|
|
 |
d3a8ee |
httpStatusLineSet(&rep->sline, rep->sline.version,
|
|
 |
d3a8ee |
@@ -1662,9 +1660,16 @@
|
|
 |
d3a8ee |
int64_t
|
|
 |
d3a8ee |
ClientSocketContext::getNextRangeOffset() const
|
|
 |
d3a8ee |
{
|
|
 |
d3a8ee |
+ debugs (33, 5, "range: " << http->request->range <<
|
|
 |
d3a8ee |
+ "; http offset " << http->out.offset <<
|
|
 |
d3a8ee |
+ "; reply " << reply);
|
|
 |
d3a8ee |
+
|
|
 |
d3a8ee |
+ // XXX: This method is called from many places, including pullData() which
|
|
 |
d3a8ee |
+ // may be called before prepareReply() [on some Squid-generated errors].
|
|
 |
d3a8ee |
+ // Hence, we may not even know yet whether we should honor/do ranges.
|
|
 |
d3a8ee |
+
|
|
 |
d3a8ee |
if (http->request->range) {
|
|
 |
d3a8ee |
/* offset in range specs does not count the prefix of an http msg */
|
|
 |
d3a8ee |
- debugs (33, 5, "ClientSocketContext::getNextRangeOffset: http offset " << http->out.offset);
|
|
 |
d3a8ee |
/* check: reply was parsed and range iterator was initialized */
|
|
 |
d3a8ee |
assert(http->range_iter.valid);
|
|
 |
d3a8ee |
/* filter out data according to range specs */
|
|
 |
d3a8ee |
@@ -1701,7 +1706,7 @@
|
|
 |
d3a8ee |
void
|
|
 |
d3a8ee |
ClientSocketContext::pullData()
|
|
 |
d3a8ee |
{
|
|
 |
d3a8ee |
- debugs(33, 5, HERE << clientConnection << " attempting to pull upstream data");
|
|
 |
d3a8ee |
+ debugs(33, 5, reply << " written " << http->out.size << " into " << clientConnection);
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
/* More data will be coming from the stream. */
|
|
 |
d3a8ee |
StoreIOBuffer readBuffer;
|
|
 |
d3a8ee |
@@ -2492,7 +2497,7 @@
|
|
 |
d3a8ee |
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
|
|
 |
d3a8ee |
assert(repContext);
|
|
 |
d3a8ee |
debugs(33, 5, "Responding with delated error for " << http->uri);
|
|
 |
d3a8ee |
- repContext->setReplyToStoreEntry(sslServerBump->entry);
|
|
 |
d3a8ee |
+ repContext->setReplyToStoreEntry(sslServerBump->entry, "delayed SslBump error");
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
// save the original request for logging purposes
|
|
 |
d3a8ee |
if (!context->http->al->request)
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
=== modified file 'src/client_side_reply.cc'
|
|
 |
d3a8ee |
--- src/client_side_reply.cc 2013-12-15 05:23:23 +0000
|
|
 |
d3a8ee |
+++ src/client_side_reply.cc 2014-03-09 02:35:19 +0000
|
|
 |
d3a8ee |
@@ -134,13 +134,18 @@
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
http->al->http.code = errstate->httpStatus;
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
+ if (http->request)
|
|
 |
d3a8ee |
+ http->request->ignoreRange("responding with a Squid-generated error");
|
|
 |
d3a8ee |
+
|
|
 |
d3a8ee |
createStoreEntry(method, RequestFlags());
|
|
 |
d3a8ee |
assert(errstate->callback_data == NULL);
|
|
 |
d3a8ee |
errorAppendEntry(http->storeEntry(), errstate);
|
|
 |
d3a8ee |
/* Now the caller reads to get this */
|
|
 |
d3a8ee |
}
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
-void clientReplyContext::setReplyToStoreEntry(StoreEntry *entry)
|
|
 |
d3a8ee |
+// Assumes that the entry contains an error response without Content-Range.
|
|
 |
d3a8ee |
+// To use with regular entries, make HTTP Range header removal conditional.
|
|
 |
d3a8ee |
+void clientReplyContext::setReplyToStoreEntry(StoreEntry *entry, const char *reason)
|
|
 |
d3a8ee |
{
|
|
 |
d3a8ee |
entry->lock(); // removeClientStoreReference() unlocks
|
|
 |
d3a8ee |
sc = storeClientListAdd(entry, this);
|
|
 |
d3a8ee |
@@ -149,6 +154,8 @@
|
|
 |
d3a8ee |
#endif
|
|
 |
d3a8ee |
reqofs = 0;
|
|
 |
d3a8ee |
reqsize = 0;
|
|
 |
d3a8ee |
+ if (http->request)
|
|
 |
d3a8ee |
+ http->request->ignoreRange(reason);
|
|
 |
d3a8ee |
flags.storelogiccomplete = 1;
|
|
 |
d3a8ee |
http->storeEntry(entry);
|
|
 |
d3a8ee |
}
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
=== modified file 'src/client_side_reply.h'
|
|
 |
d3a8ee |
--- src/client_side_reply.h 2012-09-10 12:49:35 +0000
|
|
 |
d3a8ee |
+++ src/client_side_reply.h 2014-03-09 02:35:19 +0000
|
|
 |
d3a8ee |
@@ -73,7 +73,7 @@
|
|
 |
d3a8ee |
int storeOKTransferDone() const;
|
|
 |
d3a8ee |
int storeNotOKTransferDone() const;
|
|
 |
d3a8ee |
/// replaces current response store entry with the given one
|
|
 |
d3a8ee |
- void setReplyToStoreEntry(StoreEntry *e);
|
|
 |
d3a8ee |
+ void setReplyToStoreEntry(StoreEntry *e, const char *reason);
|
|
 |
d3a8ee |
/// builds error using clientBuildError() and calls setReplyToError() below
|
|
 |
d3a8ee |
void setReplyToError(err_type, http_status, const HttpRequestMethod&, char const *, Ip::Address &, HttpRequest *, const char *,
|
|
 |
d3a8ee |
#if USE_AUTH
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
=== modified file 'src/client_side_request.cc'
|
|
 |
d3a8ee |
--- src/client_side_request.cc 2014-03-09 02:10:07 +0000
|
|
 |
d3a8ee |
+++ src/client_side_request.cc 2014-03-09 02:35:19 +0000
|
|
 |
d3a8ee |
@@ -1131,8 +1131,7 @@
|
|
 |
d3a8ee |
else {
|
|
 |
d3a8ee |
req_hdr->delById(HDR_RANGE);
|
|
 |
d3a8ee |
req_hdr->delById(HDR_REQUEST_RANGE);
|
|
 |
d3a8ee |
- delete request->range;
|
|
 |
d3a8ee |
- request->range = NULL;
|
|
 |
d3a8ee |
+ request->ignoreRange("neither HEAD nor GET");
|
|
 |
d3a8ee |
}
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
if (req_hdr->has(HDR_AUTHORIZATION))
|
|
 |
d3a8ee |
@@ -1664,7 +1663,7 @@
|
|
 |
d3a8ee |
clientStreamNode *node = (clientStreamNode *)client_stream.tail->prev->data;
|
|
 |
d3a8ee |
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
|
|
 |
d3a8ee |
assert (repContext);
|
|
 |
d3a8ee |
- repContext->setReplyToStoreEntry(e);
|
|
 |
d3a8ee |
+ repContext->setReplyToStoreEntry(e, "immediate SslBump error");
|
|
 |
d3a8ee |
errorAppendEntry(e, calloutContext->error);
|
|
 |
d3a8ee |
calloutContext->error = NULL;
|
|
 |
d3a8ee |
if (calloutContext->readNextRequest)
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
=== modified file 'src/http.cc'
|
|
 |
d3a8ee |
--- src/http.cc 2013-11-21 21:54:29 +0000
|
|
 |
d3a8ee |
+++ src/http.cc 2014-03-09 02:35:19 +0000
|
|
 |
d3a8ee |
@@ -1736,8 +1736,7 @@
|
|
 |
d3a8ee |
/* don't cache the result */
|
|
 |
d3a8ee |
request->flags.cachable = 0;
|
|
 |
d3a8ee |
/* pretend it's not a range request */
|
|
 |
d3a8ee |
- delete request->range;
|
|
 |
d3a8ee |
- request->range = NULL;
|
|
 |
d3a8ee |
+ request->ignoreRange("want to request the whole object");
|
|
 |
d3a8ee |
request->flags.isRanged=false;
|
|
 |
d3a8ee |
}
|
|
 |
d3a8ee |
|
|
 |
d3a8ee |
|