You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2014/03/29 00:31:23 UTC
[01/13] git commit: TS-2675: minor metalink refactorings
Repository: trafficserver
Updated Branches:
refs/heads/master 88a0d3bcd -> ad6806ea7
TS-2675: minor metalink refactorings
- strcasecmp(3) says #include <strings.h>
- C style casts for consistency
- Give some variables better names
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/3ba82881
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/3ba82881
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/3ba82881
Branch: refs/heads/master
Commit: 3ba8288154599a7717b6d54ab08df79e5396708e
Parents: 88a0d3b
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 11:15:35 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:53 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 32 ++++++++++++--------------
1 file changed, 15 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3ba82881/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index ea253dd..be48601 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -30,13 +30,11 @@
*/
-#include <stdio.h>
-#include <string.h>
+#include <strings.h>
#include <openssl/sha.h>
#include "ts/ts.h"
-#include "ink_defs.h"
/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transform.
* Compute the SHA-256 digest of the content, write it to the cache and store
@@ -55,7 +53,7 @@
typedef struct {
TSVConn connp;
- TSIOBuffer bufp;
+ TSIOBuffer cache_bufp;
} WriteData;
@@ -98,7 +96,7 @@ typedef struct {
/* Digest header field value index */
int idx;
- TSIOBuffer read_bufp;
+ TSIOBuffer cache_bufp;
} SendData;
@@ -117,7 +115,7 @@ write_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
* TSVConnClose() */
TSVConnClose(data->connp);
- TSIOBufferDestroy(data->bufp);
+ TSIOBufferDestroy(data->cache_bufp);
TSfree(data);
return 0;
@@ -195,10 +193,10 @@ cache_open_write(TSCont contp, void *edata)
contp = TSContCreate(write_handler, NULL);
TSContDataSet(contp, write_data);
- write_data->bufp = TSIOBufferCreate();
- TSIOBufferReader readerp = TSIOBufferReaderAlloc(write_data->bufp);
+ write_data->cache_bufp = TSIOBufferCreate();
+ TSIOBufferReader readerp = TSIOBufferReaderAlloc(write_data->cache_bufp);
- int nbytes = TSIOBufferWrite(write_data->bufp, value, length);
+ int nbytes = TSIOBufferWrite(write_data->cache_bufp, value, length);
TSVConnWrite(write_data->connp, contp, readerp, nbytes);
@@ -418,10 +416,10 @@ cache_open_read(TSCont contp, void *edata)
SendData *data = (SendData *) TSContDataGet(contp);
TSVConn connp = (TSVConn) edata;
- data->read_bufp = TSIOBufferCreate();
+ data->cache_bufp = TSIOBufferCreate();
/* Reuse the TSCacheRead() continuation */
- TSVConnRead(connp, contp, data->read_bufp, INT64_MAX);
+ TSVConnRead(connp, contp, data->cache_bufp, INT64_MAX);
return 0;
}
@@ -497,12 +495,12 @@ vconn_read_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TSContDestroy(contp);
- TSIOBufferReader readerp = TSIOBufferReaderAlloc(data->read_bufp);
+ TSIOBufferReader readerp = TSIOBufferReaderAlloc(data->cache_bufp);
TSIOBufferBlock blockp = TSIOBufferReaderStart(readerp);
value = TSIOBufferBlockReadStart(blockp, readerp, &length);
if (TSUrlParse(data->resp_bufp, data->url_loc, &value, value + length) != TS_PARSE_DONE) {
- TSIOBufferDestroy(data->read_bufp);
+ TSIOBufferDestroy(data->cache_bufp);
TSCacheKeyDestroy(data->key);
@@ -516,7 +514,7 @@ vconn_read_ready(TSCont contp, void * /* edata ATS_UNUSED */)
return 0;
}
- TSIOBufferDestroy(data->read_bufp);
+ TSIOBufferDestroy(data->cache_bufp);
if (TSCacheKeyDigestFromUrlSet(data->key, data->url_loc) != TS_SUCCESS) {
TSCacheKeyDestroy(data->key);
@@ -764,9 +762,9 @@ TSPluginInit(int /* argc ATS_UNUSED */, const char */* argv ATS_UNUSED */[])
{
TSPluginRegistrationInfo info;
- info.plugin_name = const_cast<char*>("metalink");
- info.vendor_name = const_cast<char*>("Apache Software Foundation");
- info.support_email = const_cast<char*>("dev@trafficserver.apache.org");
+ info.plugin_name = (char *) "metalink";
+ info.vendor_name = (char *) "Apache Software Foundation";
+ info.support_email = (char *) "dev@trafficserver.apache.org";
if (TSPluginRegister(TS_SDK_VERSION_3_0, &info) != TS_SUCCESS) {
TSError("Plugin registration failed");
[07/13] git commit: TS-2675: metalink: Handle the end of the input
independently from the TS_EVENT_VCONN_WRITE_COMPLETE event from downstream
Posted by jp...@apache.org.
TS-2675: metalink: Handle the end of the input independently from the TS_EVENT_VCONN_WRITE_COMPLETE event from downstream
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/52622d28
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/52622d28
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/52622d28
Branch: refs/heads/master
Commit: 52622d2809464ace2ab36e888a19f51a9edb508e
Parents: d25b00c
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 12:56:53 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 170 +++++++++++++------------
1 file changed, 88 insertions(+), 82 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/52622d28/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index 77f62dc..f792d8a 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -225,20 +225,41 @@ write_handler(TSCont contp, TSEvent event, void *edata)
}
/* Copy content from the input buffer to the output buffer without modification
- * while at the same time feeding it to the message digest */
+ * and feed it through the message digest at the same time.
+ *
+ * 1. Check if any more input is possible before doing anything else to avoid
+ * failed asserts.
+ * 2. Then deal with any input that's available now.
+ * 3. Check if the input is complete after dealing with any available input
+ * in case it was the last of it. If it is complete, do any bookkeeping
+ * that downstream needs and finish computing the digest. Otherwise
+ * either wait for more input or abort if no more input is possible.
+ *
+ * Events are sent from downstream and don't communicate the state of the input
+ * (TS_EVENT_VCONN_WRITE_READY, TS_EVENT_VCONN_WRITE_COMPLETE, and
+ * TS_EVENT_IMMEDIATE?) Clean up the output buffer on
+ * TS_EVENT_VCONN_WRITE_COMPLETE and not before.
+ *
+ * Gather the state of the input from TSVIONTodoGet() and TSVIOReaderGet().
+ * TSVIOReaderGet() is NULL when no more input is possible and the input is
+ * complete only when TSVIONTodoGet() is zero. Handle the end of the input
+ * independently from the TS_EVENT_VCONN_WRITE_COMPLETE event from downstream. */
static int
vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
{
const char *value;
int64_t length;
- TransformData *data = (TransformData *) TSContDataGet(contp);
+
+ char digest[32];
+
+ TransformData *transform_data = (TransformData *) TSContDataGet(contp);
TSVIO input_viop = TSVConnWriteVIOGet(contp);
/* Initialize data here because can't call TSVConnWrite() before
* TS_HTTP_RESPONSE_TRANSFORM_HOOK */
- if (!data->output_bufp) {
+ if (!transform_data->output_bufp) {
/* Avoid failed assert "sdk_sanity_check_iocore_structure(connp) ==
* TS_SUCCESS" in TSVConnWrite() if the response is 304 Not Modified */
@@ -246,127 +267,112 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
if (!output_connp) {
TSContDestroy(contp);
- TSfree(data);
+ TSfree(transform_data);
return 0;
}
- data->output_bufp = TSIOBufferCreate();
- TSIOBufferReader readerp = TSIOBufferReaderAlloc(data->output_bufp);
+ transform_data->output_bufp = TSIOBufferCreate();
+ TSIOBufferReader readerp = TSIOBufferReaderAlloc(transform_data->output_bufp);
/* Determines the "Content-Length: ..." header
* (or "Transfer-Encoding: chunked") */
/* Avoid failed assert "nbytes >= 0" if "Transfer-Encoding: chunked" */
int nbytes = TSVIONBytesGet(input_viop);
- data->output_viop = TSVConnWrite(output_connp, contp, readerp, nbytes < 0 ? INT64_MAX : nbytes);
+ transform_data->output_viop = TSVConnWrite(output_connp, contp, readerp, nbytes < 0 ? INT64_MAX : nbytes);
- SHA256_Init(&data->c);
- }
-
- /* If the response has a "Content-Length: ..." header then ntodo will never
- * be zero because there will instead be a TS_EVENT_VCONN_WRITE_COMPLETE
- * event from downstream after nbytes of content.
- *
- * Otherwise (if the response is "Transfer-Encoding: chunked") ntodo will be
- * zero when the upstream nbytes is known at the end of the content, because
- * there won't be a TS_EVENT_VCONN_WRITE_COMPLETE event while the downstream
- * nbytes is INT64_MAX.
- *
- * In that case to get it to send a TS_EVENT_VCONN_WRITE_COMPLETE event,
- * update the downstream nbytes and reenable it. Zero the downstream nbytes
- * is a shortcut. */
- int ntodo = TSVIONTodoGet(input_viop);
- if (!ntodo) {
- TSVIONBytesSet(data->output_viop, 0);
-
- TSVIOReenable(data->output_viop);
-
- return 0;
+ SHA256_Init(&transform_data->c);
}
/* Avoid failed assert "sdk_sanity_check_iocore_structure(readerp) ==
* TS_SUCCESS" in TSIOBufferReaderAvail() if the client or server disconnects
- * or the content length is zero.
- *
- * Don't update the downstream nbytes and reenable it because if not at the
- * end yet and can't read any more content then can't compute the digest.
- *
- * (There hasn't been a TS_EVENT_VCONN_WRITE_COMPLETE event from downstream
- * yet so if the response has a "Content-Length: ..." header, it is greater
- * than the content so far. ntodo is still greater than zero so if the
- * response is "Transfer-Encoding: chunked", not at the end yet.) */
+ * or the content length is zero */
TSIOBufferReader readerp = TSVIOReaderGet(input_viop);
- if (!readerp) {
- TSContDestroy(contp);
+ if (readerp) {
- TSIOBufferDestroy(data->output_bufp);
- TSfree(data);
+ int avail = TSIOBufferReaderAvail(readerp);
+ if (avail) {
+ TSIOBufferCopy(transform_data->output_bufp, readerp, avail, 0);
- return 0;
- }
-
- int avail = TSIOBufferReaderAvail(readerp);
+ /* Feed content to the message digest */
+ TSIOBufferBlock blockp = TSIOBufferReaderStart(readerp);
+ while (blockp) {
- if (avail) {
- TSIOBufferCopy(data->output_bufp, readerp, avail, 0);
+ value = TSIOBufferBlockReadStart(blockp, readerp, &length);
+ SHA256_Update(&transform_data->c, value, length);
- /* Feed content to the message digest */
- TSIOBufferBlock blockp = TSIOBufferReaderStart(readerp);
- while (blockp) {
+ blockp = TSIOBufferBlockNext(blockp);
+ }
- value = TSIOBufferBlockReadStart(blockp, readerp, &length);
- SHA256_Update(&data->c, value, length);
+ TSIOBufferReaderConsume(readerp, avail);
- blockp = TSIOBufferBlockNext(blockp);
+ /* Call TSVIONDoneSet() for TSVIONTodoGet() condition */
+ int ndone = TSVIONDoneGet(input_viop);
+ TSVIONDoneSet(input_viop, ndone + avail);
}
+ }
- TSIOBufferReaderConsume(readerp, avail);
+ int ntodo = TSVIONTodoGet(input_viop);
+ if (ntodo) {
- /* Call TSVIONDoneSet() for TSVIONTodoGet() condition */
- int ndone = TSVIONDoneGet(input_viop);
- TSVIONDoneSet(input_viop, ndone + avail);
+ /* Don't update the downstream nbytes because the input isn't complete */
+ if (!readerp) {
+ TSContDestroy(contp);
+
+ TSIOBufferDestroy(transform_data->output_bufp);
+ TSfree(transform_data);
- TSVIOReenable(data->output_viop);
+ return 0;
+ }
+
+ TSVIOReenable(transform_data->output_viop);
TSContCall(TSVIOContGet(input_viop), TS_EVENT_VCONN_WRITE_READY, input_viop);
- }
- return 0;
-}
+ } else {
-/* Write the digest to the cache */
+ int ndone = TSVIONDoneGet(input_viop);
+ TSVIONBytesSet(transform_data->output_viop, ndone);
-static int
-transform_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
-{
- char digest[32];
+ TSVIOReenable(transform_data->output_viop);
- TransformData *transform_data = (TransformData *) TSContDataGet(contp);
- TSContDestroy(contp);
+ /* Write the digest to the cache */
- TSIOBufferDestroy(transform_data->output_bufp);
+ SHA256_Final((unsigned char *) digest, &transform_data->c);
- SHA256_Final((unsigned char *) digest, &transform_data->c);
+ WriteData *write_data = (WriteData *) TSmalloc(sizeof(WriteData));
+ write_data->txnp = transform_data->txnp;
- WriteData *write_data = (WriteData *) TSmalloc(sizeof(WriteData));
- write_data->txnp = transform_data->txnp;
+ write_data->key = TSCacheKeyCreate();
+ if (TSCacheKeyDigestSet(write_data->key, digest, sizeof(digest)) != TS_SUCCESS) {
- TSfree(transform_data);
+ TSCacheKeyDestroy(write_data->key);
+ TSfree(write_data);
- write_data->key = TSCacheKeyCreate();
- if (TSCacheKeyDigestSet(write_data->key, digest, sizeof(digest)) != TS_SUCCESS) {
+ return 0;
+ }
- TSCacheKeyDestroy(write_data->key);
- TSfree(write_data);
+ /* Can't reuse the TSTransformCreate() continuation because don't know
+ * whether to destroy it in cache_open_write()/cache_open_write_failed() or
+ * transform_vconn_write_complete() */
+ contp = TSContCreate(write_handler, NULL);
+ TSContDataSet(contp, write_data);
- return 0;
+ TSCacheWrite(contp, write_data->key);
}
- contp = TSContCreate(write_handler, NULL);
- TSContDataSet(contp, write_data);
+ return 0;
+}
- TSCacheWrite(contp, write_data->key);
+static int
+transform_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
+{
+ TransformData *data = (TransformData *) TSContDataGet(contp);
+ TSContDestroy(contp);
+
+ TSIOBufferDestroy(data->output_bufp);
+ TSfree(data);
return 0;
}
[09/13] git commit: TS-2675: metalink: Don't finish computing the
digest more than once and test that the proxy rewrites the Location header if
the file is already cached
Posted by jp...@apache.org.
TS-2675: metalink: Don't finish computing the digest more than once and test that the proxy rewrites the Location header if the file is already cached
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/f9d74b9f
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/f9d74b9f
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/f9d74b9f
Branch: refs/heads/master
Commit: f9d74b9feefa2f7a4c8d59b6633efe9de8415d50
Parents: ea2f6f3
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Mon Mar 17 09:19:31 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 13 ++-
plugins/experimental/metalink/test/location | 124 +++++++++++++++++++++++
2 files changed, 136 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f9d74b9f/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index 3ad589d..ae8771c 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -367,7 +367,15 @@ vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
TSContCall(TSVIOContGet(input_viop), TS_EVENT_VCONN_WRITE_READY, input_viop);
- } else {
+ /* Don't finish computing the digest (and tell downstream and thank upstream)
+ * more than once! There might be multiple TS_EVENT_IMMEDIATE events between
+ * the end of the input and the TS_EVENT_VCONN_WRITE_COMPLETE event from
+ * downstream, e.g. INKVConnInternal::reenable() is called by
+ * HttpTunnel::producer_handler() when more input is available and
+ * TransformVConnection::do_io_shutdown() is called by
+ * HttpSM::tunnel_handler_transform_write() when we send our own
+ * TS_EVENT_VCONN_WRITE_COMPLETE event upstream. */
+ } else if (transform_data->txnp) {
int ndone = TSVIONDoneGet(input_viop);
TSVIONBytesSet(transform_data->output_viop, ndone);
@@ -388,6 +396,9 @@ vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
WriteData *write_data = (WriteData *) TSmalloc(sizeof(WriteData));
write_data->txnp = transform_data->txnp;
+ /* Don't finish computing the digest more than once! */
+ transform_data->txnp = NULL;
+
write_data->key = TSCacheKeyCreate();
if (TSCacheKeyDigestSet(write_data->key, digest, sizeof(digest)) != TS_SUCCESS) {
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f9d74b9f/plugins/experimental/metalink/test/location
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/location b/plugins/experimental/metalink/test/location
new file mode 100755
index 0000000..77b601e
--- /dev/null
+++ b/plugins/experimental/metalink/test/location
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+print '''1..2 location
+# The proxy rewrites the Location header if the file is already cached'''
+
+from twisted.internet import error, protocol, reactor, tcp
+from twisted.web import http
+
+def callback():
+ print 'not ok 1 - Why didn\'t the test finish yet?'
+
+ reactor.stop()
+
+reactor.callLater(1, callback)
+
+class factory(http.HTTPFactory):
+ class protocol(http.HTTPChannel):
+ class requestFactory(http.Request):
+ def requestReceived(ctx, method, target, version):
+
+ ctx.client = None
+ ctx.clientproto = version
+
+ if target == '/location':
+
+ ctx.write('location')
+ ctx.finish()
+
+ else:
+
+ ctx.setHeader('Digest', 'SHA-256=5urqGOiF4QeIKbVt80iWvlq1FDno8LoAyxYkssVywQ4=')
+ ctx.setHeader('Location', 'http://example.com')
+ ctx.finish()
+
+origin = tcp.Port(0, factory())
+origin.startListening()
+
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
+
+class factory(protocol.ClientFactory):
+ def clientConnectionFailed(ctx, connector, reason):
+
+ print 'Bail out!'
+ reason.printTraceback()
+
+ reactor.stop()
+
+ class protocol(http.HTTPClient):
+ def connectionLost(ctx, reason):
+ try:
+ reactor.stop()
+
+ except error.ReactorNotRunning:
+ pass
+
+ else:
+ print 'not ok 1 - Did the proxy crash? (The client connection closed.)'
+
+ # Get a response with a Location and a Digest header and check that the
+ # Location header is not rewritten. Then get the same response after
+ # caching a matching file from a different URL and check that this time the
+ # header is rewritten.
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\nGET {0}:{1}/location HTTP/1.1\r\n\r\nGET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
+
+ def handleResponsePart(ctx, data):
+ try:
+ h, r = data.split('0\r\n\r\n', 1)
+
+ except ValueError:
+ pass
+
+ else:
+
+ ctx.firstLine = True
+ ctx.setLineMode(r)
+
+ def handleStatus(ctx, version, status, message):
+ def handleHeader(k, v):
+ if k.lower() == 'location':
+ if v != 'http://example.com':
+ print 'not',
+
+ print 'ok 1 - Before'
+
+ ctx.handleHeader = handleHeader
+
+ def handleStatus(version, status, message):
+ del ctx.handleHeader
+
+ def handleStatus(version, staus, message):
+ def handleHeader(k, v):
+ if k.lower() == 'location':
+ if v != 'http://{0}:{1}/location'.format(*origin.socket.getsockname()):
+ print 'not',
+
+ print 'ok 2 - After'
+
+ reactor.stop()
+
+ ctx.handleHeader = handleHeader
+
+ ctx.handleStatus = handleStatus
+
+ ctx.handleStatus = handleStatus
+
+tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect()
+
+reactor.run()
[10/13] git commit: TS-2675: metalink: Drop redundant TSUrlStringGet()
Posted by jp...@apache.org.
TS-2675: metalink: Drop redundant TSUrlStringGet()
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/d25edd9f
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/d25edd9f
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/d25edd9f
Branch: refs/heads/master
Commit: d25edd9fac32e770671297caa6510f8d360aa338
Parents: a31459d
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 13:19:44 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 30 +++++++++++++-------------
1 file changed, 15 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d25edd9f/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index f18f266..e604272 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -100,6 +100,9 @@ typedef struct {
TSIOBuffer cache_bufp;
+ const char *value;
+ int64_t length;
+
} SendData;
/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transform */
@@ -468,9 +471,6 @@ cache_open_read_failed(TSCont contp, void * /* edata ATS_UNUSED */)
static int
rewrite_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
{
- char *value;
- int length;
-
SendData *data = (SendData *) TSContDataGet(contp);
TSContDestroy(contp);
@@ -479,12 +479,8 @@ rewrite_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
/* Yes: Rewrite the "Location: ..." header and reenable the response */
case TS_EVENT_CACHE_OPEN_READ:
- /* Allocation! Must free! */
- value = TSUrlStringGet(data->resp_bufp, data->url_loc, &length);
TSMimeHdrFieldValuesClear(data->resp_bufp, data->hdr_loc, data->location_loc);
- TSMimeHdrFieldValueStringInsert(data->resp_bufp, data->hdr_loc, data->location_loc, -1, value, length);
-
- TSfree(value);
+ TSMimeHdrFieldValueStringInsert(data->resp_bufp, data->hdr_loc, data->location_loc, -1, data->value, data->length);
break;
@@ -496,9 +492,10 @@ rewrite_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
TSAssert(!"Unexpected event");
}
+ TSIOBufferDestroy(data->cache_bufp);
+
TSCacheKeyDestroy(data->key);
- TSHandleMLocRelease(data->resp_bufp, TS_NULL_MLOC, data->url_loc);
TSHandleMLocRelease(data->resp_bufp, data->hdr_loc, data->location_loc);
TSHandleMLocRelease(data->resp_bufp, TS_NULL_MLOC, data->hdr_loc);
@@ -513,8 +510,6 @@ rewrite_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
static int
vconn_read_ready(TSCont contp, void * /* edata ATS_UNUSED */)
{
- const char *value;
- int64_t length;
SendData *data = (SendData *) TSContDataGet(contp);
TSContDestroy(contp);
@@ -523,8 +518,11 @@ vconn_read_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TSIOBufferBlock blockp = TSIOBufferReaderStart(readerp);
/* No allocation, freed with data->cache_bufp? */
- value = TSIOBufferBlockReadStart(blockp, readerp, &length);
- if (TSUrlParse(data->resp_bufp, data->url_loc, &value, value + length) != TS_PARSE_DONE) {
+ const char *value = data->value = TSIOBufferBlockReadStart(blockp, readerp, &data->length);
+
+ /* The start pointer is both an input and an output parameter. After a
+ * successful parse the start pointer equals the end pointer. */
+ if (TSUrlParse(data->resp_bufp, data->url_loc, &value, value + data->length) != TS_PARSE_DONE) {
TSIOBufferDestroy(data->cache_bufp);
TSCacheKeyDestroy(data->key);
@@ -539,9 +537,9 @@ vconn_read_ready(TSCont contp, void * /* edata ATS_UNUSED */)
return 0;
}
- TSIOBufferDestroy(data->cache_bufp);
-
if (TSCacheKeyDigestFromUrlSet(data->key, data->url_loc) != TS_SUCCESS) {
+ TSIOBufferDestroy(data->cache_bufp);
+
TSCacheKeyDestroy(data->key);
TSHandleMLocRelease(data->resp_bufp, TS_NULL_MLOC, data->url_loc);
@@ -554,6 +552,8 @@ vconn_read_ready(TSCont contp, void * /* edata ATS_UNUSED */)
return 0;
}
+ TSHandleMLocRelease(data->resp_bufp, TS_NULL_MLOC, data->url_loc);
+
/* Check if the URL stored at the digest is cached */
contp = TSContCreate(rewrite_handler, NULL);
[08/13] git commit: TS-2675: metalink: Plug memory leaks reported by
Valgrind
Posted by jp...@apache.org.
TS-2675: metalink: Plug memory leaks reported by Valgrind
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/a31459d4
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/a31459d4
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/a31459d4
Branch: refs/heads/master
Commit: a31459d42c0794bab9cdf46805e97c6abe1ab769
Parents: 52622d2
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 13:07:53 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 28 ++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a31459d4/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index f792d8a..f18f266 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -114,7 +114,7 @@ cache_open_write(TSCont contp, void *edata)
TSMLoc hdr_loc;
TSMLoc url_loc;
- const char *value;
+ char *value;
int length;
WriteData *data = (WriteData *) TSContDataGet(contp);
@@ -142,6 +142,7 @@ cache_open_write(TSCont contp, void *edata)
return 0;
}
+ /* Allocation! Must free! */
value = TSUrlStringGet(req_bufp, url_loc, &length);
if (!value) {
TSContDestroy(contp);
@@ -164,6 +165,8 @@ cache_open_write(TSCont contp, void *edata)
int nbytes = TSIOBufferWrite(data->cache_bufp, value, length);
+ TSfree(value);
+
/* Reuse the TSCacheWrite() continuation */
TSVConnWrite(data->connp, contp, readerp, nbytes);
@@ -251,7 +254,7 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
const char *value;
int64_t length;
- char digest[32];
+ char digest[32]; /* SHA-256 */
TransformData *transform_data = (TransformData *) TSContDataGet(contp);
@@ -299,6 +302,7 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TSIOBufferBlock blockp = TSIOBufferReaderStart(readerp);
while (blockp) {
+ /* No allocation? */
value = TSIOBufferBlockReadStart(blockp, readerp, &length);
SHA256_Update(&transform_data->c, value, length);
@@ -464,7 +468,7 @@ cache_open_read_failed(TSCont contp, void * /* edata ATS_UNUSED */)
static int
rewrite_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
{
- const char *value;
+ char *value;
int length;
SendData *data = (SendData *) TSContDataGet(contp);
@@ -474,9 +478,14 @@ rewrite_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
/* Yes: Rewrite the "Location: ..." header and reenable the response */
case TS_EVENT_CACHE_OPEN_READ:
+
+ /* Allocation! Must free! */
value = TSUrlStringGet(data->resp_bufp, data->url_loc, &length);
TSMimeHdrFieldValuesClear(data->resp_bufp, data->hdr_loc, data->location_loc);
TSMimeHdrFieldValueStringInsert(data->resp_bufp, data->hdr_loc, data->location_loc, -1, value, length);
+
+ TSfree(value);
+
break;
/* No: Do nothing, just reenable the response */
@@ -513,6 +522,7 @@ vconn_read_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TSIOBufferReader readerp = TSIOBufferReaderAlloc(data->cache_bufp);
TSIOBufferBlock blockp = TSIOBufferReaderStart(readerp);
+ /* No allocation, freed with data->cache_bufp? */
value = TSIOBufferBlockReadStart(blockp, readerp, &length);
if (TSUrlParse(data->resp_bufp, data->url_loc, &value, value + length) != TS_PARSE_DONE) {
TSIOBufferDestroy(data->cache_bufp);
@@ -588,8 +598,7 @@ location_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
const char *value;
int length;
- /* ATS_BASE64_DECODE_DSTLEN() */
- char digest[33];
+ char digest[33]; /* ATS_BASE64_DECODE_DSTLEN() */
SendData *data = (SendData *) TSContDataGet(contp);
TSContDestroy(contp);
@@ -602,17 +611,21 @@ location_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
/* No: Check if the "Digest: SHA-256=..." digest already exists in the cache */
case TS_EVENT_CACHE_OPEN_READ_FAILED:
+ /* No allocation, freed with data->resp_bufp? */
value = TSMimeHdrFieldValueStringGet(data->resp_bufp, data->hdr_loc, data->digest_loc, data->idx, &length);
if (TSBase64Decode(value + 8, length - 8, (unsigned char *) digest, sizeof(digest), NULL) != TS_SUCCESS
|| TSCacheKeyDigestSet(data->key, digest, 32 /* SHA-256 */ ) != TS_SUCCESS) {
break;
}
+ TSHandleMLocRelease(data->resp_bufp, data->hdr_loc, data->digest_loc);
+
+ /* Check if the "Digest: SHA-256=..." digest already exists in the cache */
+
contp = TSContCreate(digest_handler, NULL);
TSContDataSet(contp, data);
TSCacheRead(contp, data->key);
- TSHandleMLocRelease(data->resp_bufp, data->hdr_loc, data->digest_loc);
return 0;
@@ -685,6 +698,8 @@ http_send_response_hdr(TSCont contp, void *edata)
/* If can't parse or lookup the "Location: ..." URL, should still check if
* the response has a "Digest: SHA-256=..." header? No: Can't parse or
* lookup the URL in the "Location: ..." header is an error. */
+
+ /* No allocation, freed with data->resp_bufp? */
value = TSMimeHdrFieldValueStringGet(data->resp_bufp, data->hdr_loc, data->location_loc, -1, &length);
if (TSUrlParse(data->resp_bufp, data->url_loc, &value, value + length) != TS_PARSE_DONE) {
@@ -719,6 +734,7 @@ http_send_response_hdr(TSCont contp, void *edata)
int count = TSMimeHdrFieldValuesCount(data->resp_bufp, data->hdr_loc, data->digest_loc);
for (data->idx = 0; data->idx < count; data->idx += 1) {
+ /* No allocation, freed with data->resp_bufp? */
value = TSMimeHdrFieldValueStringGet(data->resp_bufp, data->hdr_loc, data->digest_loc, data->idx, &length);
if (length < 8 + 44 /* 32 bytes, Base64 */ || strncasecmp(value, "SHA-256=", 8)) {
continue;
[04/13] git commit: TS-2675: metalink: Fix crash if
INKVConnInternal::do_io_close() gets called after a message is already
complete
Posted by jp...@apache.org.
TS-2675: metalink: Fix crash if INKVConnInternal::do_io_close() gets called after a message is already complete
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ccc549e9
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ccc549e9
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ccc549e9
Branch: refs/heads/master
Commit: ccc549e9bbc394e95cf7d1852f7d8a73efb1b4db
Parents: 54316fd
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 13:59:01 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 36 ++++----
.../metalink/test/pipeliningDisconnect | 93 ++++++++++++++++++++
2 files changed, 108 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ccc549e9/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index 5def165..8ebd2cc 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -261,22 +261,27 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TransformData *transform_data = (TransformData *) TSContDataGet(contp);
+ int closed = TSVConnClosedGet(contp);
+ if (closed) {
+ TSContDestroy(contp);
+
+ /* Avoid failed assert "sdk_sanity_check_iocore_structure(bufp) ==
+ * TS_SUCCESS" in TSIOBufferDestroy() if the response is 304 Not Modified */
+ if (transform_data->output_bufp) {
+ TSIOBufferDestroy(transform_data->output_bufp);
+ }
+
+ TSfree(transform_data);
+
+ return 0;
+ }
+
TSVIO input_viop = TSVConnWriteVIOGet(contp);
/* Initialize data here because can't call TSVConnWrite() before
* TS_HTTP_RESPONSE_TRANSFORM_HOOK */
if (!transform_data->output_bufp) {
-
- /* Avoid failed assert "sdk_sanity_check_iocore_structure(connp) ==
- * TS_SUCCESS" in TSVConnWrite() if the response is 304 Not Modified */
TSVConn output_connp = TSTransformOutputVConnGet(contp);
- if (!output_connp) {
- TSContDestroy(contp);
-
- TSfree(transform_data);
-
- return 0;
- }
transform_data->output_bufp = TSIOBufferCreate();
TSIOBufferReader readerp = TSIOBufferReaderAlloc(transform_data->output_bufp);
@@ -322,17 +327,6 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
int ntodo = TSVIONTodoGet(input_viop);
if (ntodo) {
-
- /* Don't update the downstream nbytes because the input isn't complete */
- if (!readerp) {
- TSContDestroy(contp);
-
- TSIOBufferDestroy(transform_data->output_bufp);
- TSfree(transform_data);
-
- return 0;
- }
-
TSVIOReenable(transform_data->output_viop);
TSContCall(TSVIOContGet(input_viop), TS_EVENT_VCONN_WRITE_READY, input_viop);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ccc549e9/plugins/experimental/metalink/test/pipeliningDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/pipeliningDisconnect b/plugins/experimental/metalink/test/pipeliningDisconnect
new file mode 100755
index 0000000..152e2cf
--- /dev/null
+++ b/plugins/experimental/metalink/test/pipeliningDisconnect
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+print '''1..1 pipeliningDisconnect
+# The proxy doesn't crash if INKVConnInternal::do_io_close() gets called after
+# a message is already complete'''
+
+from twisted.internet import error, protocol, reactor, tcp
+from twisted.web import http
+
+def callback():
+ print 'ok 1 - Did the connection close before the proxy made the second request?'
+
+ reactor.stop()
+
+reactor.callLater(2, callback)
+
+class factory(http.HTTPFactory):
+ class protocol(http.HTTPChannel):
+ class requestFactory(http.Request):
+ def requestReceived(ctx, method, target, version):
+ class requestFactory(http.Request):
+ def requestReceived(ctx, method, target, version):
+
+ ctx.client = None
+ ctx.clientproto = version
+
+ ctx.write('pipeliningDisconnect')
+ ctx.finish()
+
+ # Open another connection
+ class factory(protocol.ClientFactory):
+ def clientConnectionFailed(ctx, connector, reason):
+ print 'not ok 1 - Did the proxy crash? (Can\'t open another connection to it.)'
+
+ reactor.stop()
+
+ class protocol(protocol.Protocol):
+ def connectionMade(ctx):
+ print 'ok 1 - The proxy didn\'t crash (opened another connection to it)'
+
+ reactor.stop()
+
+ reactor.callLater(1, tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect)
+
+ ctx.channel.requestFactory = requestFactory
+
+ ctx.client = None
+ ctx.clientproto = version
+
+ ctx.write('pipeliningDisconnect')
+ ctx.finish()
+
+origin = tcp.Port(0, factory())
+origin.startListening()
+
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
+
+class factory(protocol.ClientFactory):
+ def clientConnectionFailed(ctx, connector, reason):
+
+ print 'Bail out!'
+ reason.printTraceback()
+
+ reactor.stop()
+
+ class protocol(protocol.Protocol):
+ def connectionMade(ctx):
+
+ # Somehow these magic words frequently cause
+ # INKVConnInternal::do_io_close() to get called after a message is
+ # already complete
+ ctx.transport.write('GET {0}:{1}/pipeliningDisconnect0 HTTP/1.1\r\n\r\nGET {0}:{1}/pipeliningDisconnect1 HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
+ ctx.transport.loseConnection()
+
+tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect()
+
+reactor.run()
[03/13] git commit: TS-2675: metalink: Simpler to drop
http.HTTPClient where not needed and minor edits
Posted by jp...@apache.org.
TS-2675: metalink: Simpler to drop http.HTTPClient where not needed and minor edits
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/54316fd3
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/54316fd3
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/54316fd3
Branch: refs/heads/master
Commit: 54316fd36451b15b209946e99f38cc6d74727280
Parents: d25edd9
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 13:43:10 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 2 +-
.../experimental/metalink/test/chunkedEncoding | 38 +++++++++---------
.../metalink/test/chunkedEncodingDisconnect | 40 +++++++++----------
.../experimental/metalink/test/clientDisconnect | 41 +++++++++----------
.../experimental/metalink/test/contentLength | 38 +++++++++---------
.../metalink/test/contentLengthDisconnect | 40 +++++++++----------
.../test/finalChunkedEncodingDisconnect | 42 ++++++++++----------
plugins/experimental/metalink/test/http09 | 38 +++++++++---------
plugins/experimental/metalink/test/longer | 40 +++++++++----------
plugins/experimental/metalink/test/notModified | 34 ++++++++--------
.../test/shortChunkedEncodingDisconnect | 38 +++++++++---------
.../metalink/test/shortClientDisconnect | 41 +++++++++----------
.../metalink/test/shortContentLengthDisconnect | 38 +++++++++---------
plugins/experimental/metalink/test/zero | 34 ++++++++--------
14 files changed, 247 insertions(+), 257 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index e604272..5def165 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -292,7 +292,7 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
}
/* Avoid failed assert "sdk_sanity_check_iocore_structure(readerp) ==
- * TS_SUCCESS" in TSIOBufferReaderAvail() if the client or server disconnects
+ * TS_SUCCESS" in TSIOBufferReaderAvail() if the client or origin disconnect
* or the content length is zero */
TSIOBufferReader readerp = TSVIOReaderGet(input_viop);
if (readerp) {
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/chunkedEncoding
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/chunkedEncoding b/plugins/experimental/metalink/test/chunkedEncoding
index ece4768..7a2ed37 100755
--- a/plugins/experimental/metalink/test/chunkedEncoding
+++ b/plugins/experimental/metalink/test/chunkedEncoding
@@ -1,20 +1,20 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 chunkedEncoding
# The proxy forwards the final chunk at the end of a chunked response'''
@@ -43,10 +43,10 @@ class factory(http.HTTPFactory):
# headers, it may send a Content-Length header vs. a chunked response
reactor.callLater(1, ctx.finish)
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -67,7 +67,7 @@ class factory(protocol.ClientFactory):
else:
print 'not ok 1 - Did the proxy crash? (The client connection closed.)'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleHeader(ctx, k, v):
if k.lower() == 'content-length':
@@ -76,11 +76,11 @@ class factory(protocol.ClientFactory):
# No hope of a final chunk now
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the content (if
+ # Avoid calling undefined handleResponse() at the end of the message (if
# the proxy sent a Content-Length header vs. a chunked response).
# (Override connectionLost() when the proxy crashes or stop the reactor.)
#
- # The data that was already received will be processed (the end of the
+ # Data that was already received will be processed (the end of the
# headers), then shutdown events will fire (connections will be closed),
# and then finally the reactor will grind to a halt.
def handleResponseEnd(ctx):
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/chunkedEncodingDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/chunkedEncodingDisconnect b/plugins/experimental/metalink/test/chunkedEncodingDisconnect
index 3c0210b..91593d0 100755
--- a/plugins/experimental/metalink/test/chunkedEncodingDisconnect
+++ b/plugins/experimental/metalink/test/chunkedEncodingDisconnect
@@ -1,24 +1,24 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 chunkedEncodingDisconnect
# The proxy closes the client connection and doesn't send a final chunk if the
-# server disconnects without sending one'''
+# origin disconnects without sending one'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -40,15 +40,15 @@ class factory(http.HTTPFactory):
ctx.write('chunkedEncodingDisconnect')
- # If the server disconnects before the proxy sends the response
+ # If the origin disconnects before the proxy sends the response
# headers, the proxy may send a Content-Length header vs. a chunked
# response
reactor.callLater(1, ctx.transport.loseConnection)
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -69,7 +69,7 @@ class factory(protocol.ClientFactory):
else:
print 'ok 1 - The client connection closed'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleHeader(ctx, k, v):
if k.lower() == 'content-length':
@@ -78,7 +78,7 @@ class factory(protocol.ClientFactory):
# Who cares what happens now?
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the content (if
+ # Avoid calling undefined handleResponse() at the end of the message (if
# the proxy sent a Content-Length header vs. a chunked response).
# (Override connectionLost() when the proxy closes the client connection or
# stop the reactor.)
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/clientDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/clientDisconnect b/plugins/experimental/metalink/test/clientDisconnect
index b8ee3da..b9ff984 100755
--- a/plugins/experimental/metalink/test/clientDisconnect
+++ b/plugins/experimental/metalink/test/clientDisconnect
@@ -1,20 +1,20 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 clientDissconnect
# The proxy doesn't crash if the client disconnects prematurely'''
@@ -64,10 +64,10 @@ class factory(http.HTTPFactory):
reactor.callLater(1, callback)
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -77,18 +77,13 @@ class factory(protocol.ClientFactory):
reactor.stop()
- class protocol(http.HTTPClient):
+ class protocol(protocol.Protocol):
def connectionMade(ctx):
- ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
# Disconnect after the proxy sends the response headers
reactor.callLater(1, ctx.transport.loseConnection)
- # Avoid calling undefined handleResponse() at the end of the content or
- # when the connection closes
- def handleResponseEnd(ctx):
- pass
-
tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect()
reactor.run()
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/contentLength
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/contentLength b/plugins/experimental/metalink/test/contentLength
index c3005ac..92708e7 100755
--- a/plugins/experimental/metalink/test/contentLength
+++ b/plugins/experimental/metalink/test/contentLength
@@ -1,20 +1,20 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 contentLength
# The proxy forwards the Content-Length header to the client'''
@@ -40,10 +40,10 @@ class factory(http.HTTPFactory):
ctx.setHeader('Content-Length', 13)
ctx.write('contentLength')
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -64,7 +64,7 @@ class factory(protocol.ClientFactory):
else:
print 'not ok 1 - Did the proxy crash? (The client connection closed.)'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleEndHeaders(ctx):
try:
@@ -85,10 +85,10 @@ class factory(protocol.ClientFactory):
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the content.
+ # Avoid calling undefined handleResponse() at the end of the message.
# (Override connectionLost() when the proxy crashes or stop the reactor.)
#
- # The data that was already received will be processed (the end of the
+ # Data that was already received will be processed (the end of the
# headers), then shutdown events will fire (connections will be closed),
# and then finally the reactor will grind to a halt.
def handleResponseEnd(ctx):
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/contentLengthDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/contentLengthDisconnect b/plugins/experimental/metalink/test/contentLengthDisconnect
index 2c98ae8..1627d0e 100755
--- a/plugins/experimental/metalink/test/contentLengthDisconnect
+++ b/plugins/experimental/metalink/test/contentLengthDisconnect
@@ -1,23 +1,23 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..2 contentLengthDisconnect
-# The proxy closes the client connection if the server disconnects prematurely'''
+# The proxy closes the client connection if the origin disconnects prematurely'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -40,14 +40,14 @@ class factory(http.HTTPFactory):
ctx.setHeader('Content-Length', 24)
ctx.write('contentLengthDisconnect')
- # If the server disconnects before the proxy sends the response
+ # If the origin disconnects before the proxy sends the response
# headers, the proxy may send the wrong Content-Length header
reactor.callLater(1, ctx.transport.loseConnection)
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -68,7 +68,7 @@ class factory(protocol.ClientFactory):
else:
print 'ok 2 - The client connection closed'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleHeader(ctx, k, v):
if k.lower() == 'content-length':
@@ -80,7 +80,7 @@ class factory(protocol.ClientFactory):
print 'ok 1 - Content-Length header'
- # Avoid calling undefined handleResponse() at the end of the content (if
+ # Avoid calling undefined handleResponse() at the end of the message (if
# the proxy sent the wrong Content-Length header). (Override
# connectionLost() when the proxy closes the client connection or stop the
# reactor.)
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect b/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect
index 9fa4093..32011bc 100755
--- a/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect
+++ b/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect
@@ -1,23 +1,23 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 finalChunkEncodingDisconnect
-# The proxy forwards the final chunk even if the server disconnects immediately
+# The proxy forwards the final chunk even if the origin disconnects immediately
# afterward'''
from twisted.internet import error, protocol, reactor, tcp
@@ -47,7 +47,7 @@ class factory(http.HTTPFactory):
ctx.finish()
except RuntimeError:
- print 'not ok 1 - Did the proxy crash? (The server connection closed.)'
+ print 'not ok 1 - Did the proxy crash? (The origin connection closed.)'
reactor.stop()
@@ -56,10 +56,10 @@ class factory(http.HTTPFactory):
reactor.callLater(1, callback)
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -80,7 +80,7 @@ class factory(protocol.ClientFactory):
else:
print 'not ok 1 - Did the proxy crash? (The client connection closed.)'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleHeader(ctx, k, v):
if k.lower() == 'content-length':
@@ -89,11 +89,11 @@ class factory(protocol.ClientFactory):
# No hope of a final chunk now
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the content (if
+ # Avoid calling undefined handleResponse() at the end of the message (if
# the proxy sent a Content-Length header vs. a chunked response).
# (Override connectionLost() when the proxy crashes or stop the reactor.)
#
- # The data that was already received will be processed (the end of the
+ # Data that was already received will be processed (the end of the
# headers), then shutdown events will fire (connections will be closed),
# and then finally the reactor will grind to a halt.
def handleResponseEnd(ctx):
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/http09
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/http09 b/plugins/experimental/metalink/test/http09
index 9103c8d..e9f7c77 100755
--- a/plugins/experimental/metalink/test/http09
+++ b/plugins/experimental/metalink/test/http09
@@ -1,20 +1,20 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 http09
# The proxy doesn't crash on an HTTP/0.9 response'''
@@ -23,7 +23,7 @@ print '''1..1 http09
#
# The proxy crashes only after the response is complete. It closes the client
# connection whether it crashes or not because an HTTP/0.9 response is complete
-# only after the server closes its connection, and then the proxy normally does
+# only after the origin closes its connection, and then the proxy normally does
# the same thing to the client connection (although it upgrades the response to
# HTTP/1.1). So the only way to check that the proxy didn't crash is to open
# another connection.
@@ -46,10 +46,10 @@ class factory(protocol.Factory):
# The proxy crashes only after the response is complete
ctx.transport.loseConnection()
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -59,7 +59,7 @@ class factory(protocol.ClientFactory):
reactor.stop()
- class protocol(http.HTTPClient):
+ class protocol(protocol.Protocol):
def connectionLost(ctx, reason):
# Open another connection
@@ -77,7 +77,7 @@ class factory(protocol.ClientFactory):
reactor.callLater(1, tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect)
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect()
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/longer
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/longer b/plugins/experimental/metalink/test/longer
index f08feae..259ad7d 100755
--- a/plugins/experimental/metalink/test/longer
+++ b/plugins/experimental/metalink/test/longer
@@ -1,23 +1,23 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 longer
-# The proxy doesn't choke if the server sends more content than it advertised'''
+# The proxy doesn't choke if the origin sends more content than it advertised'''
# Unlike the contentLength test, don't stop the reactor at the end of the
# headers. Give the proxy time to choke.
@@ -43,10 +43,10 @@ class factory(http.HTTPFactory):
ctx.setHeader('Content-Length', 1)
ctx.write('longer')
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -67,7 +67,7 @@ class factory(protocol.ClientFactory):
else:
print 'not ok 1 - Did the proxy crash? (The client connection closed.)'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleHeader(ctx, k, v):
if k.lower() == 'content-length':
@@ -78,10 +78,10 @@ class factory(protocol.ClientFactory):
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the content.
+ # Avoid calling undefined handleResponse() at the end of the message.
# (Override connectionLost() when the proxy crashes or stop the reactor.)
#
- # The data that was already received will be processed (the end of the
+ # Data that was already received will be processed (the end of the
# headers), then shutdown events will fire (connections will be closed),
# and then finally the reactor will grind to a halt.
def handleResponseEnd(ctx):
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/notModified
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/notModified b/plugins/experimental/metalink/test/notModified
index 2854189..90c3a87 100755
--- a/plugins/experimental/metalink/test/notModified
+++ b/plugins/experimental/metalink/test/notModified
@@ -1,20 +1,20 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..2 notModified
# The proxy doesn't crash on a 304 Not Modified response'''
@@ -40,10 +40,10 @@ class factory(http.HTTPFactory):
ctx.setResponseCode(304)
ctx.finish()
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -64,7 +64,7 @@ class factory(protocol.ClientFactory):
else:
print 'not ok 1 - Did the proxy crash? (The client connection closed.)'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleStatus(ctx, version, status, message):
if status != '304':
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect b/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect
index 526b233..3c52858 100755
--- a/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect
+++ b/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect
@@ -1,24 +1,24 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 shortChunkedEncodingDisconnect
# The proxy closes the client connection and doesn't send a final chunk if the
-# server disconnects without sending one, before the proxy sends the response
+# origin disconnects without sending one, before the proxy sends the response
# headers'''
from twisted.internet import error, protocol, reactor, tcp
@@ -44,10 +44,10 @@ class factory(http.HTTPFactory):
# Disconnect before the proxy sends the response headers
ctx.transport.loseConnection()
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -68,7 +68,7 @@ class factory(protocol.ClientFactory):
else:
print 'ok 1 - The client connection closed'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleHeader(ctx, k, v):
if k.lower() == 'content-length':
@@ -77,7 +77,7 @@ class factory(protocol.ClientFactory):
# Who cares what happens now?
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the content (if
+ # Avoid calling undefined handleResponse() at the end of the message (if
# the proxy sent a Content-Length header vs. a chunked response).
# (Override connectionLost() when the proxy closes the client connection or
# stop the reactor.)
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/shortClientDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/shortClientDisconnect b/plugins/experimental/metalink/test/shortClientDisconnect
index 4ab6c83..6956c78 100755
--- a/plugins/experimental/metalink/test/shortClientDisconnect
+++ b/plugins/experimental/metalink/test/shortClientDisconnect
@@ -1,20 +1,20 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 shortClientDisconnect
# The proxy doesn't crash if the client disconnects before the proxy sends the
@@ -60,10 +60,10 @@ class factory(http.HTTPFactory):
reactor.callLater(1, callback)
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -73,18 +73,13 @@ class factory(protocol.ClientFactory):
reactor.stop()
- class protocol(http.HTTPClient):
+ class protocol(protocol.Protocol):
def connectionMade(ctx):
- ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
# Disconnect before the proxy sends the response headers
ctx.transport.loseConnection()
- # Avoid calling undefined handleResponse() at the end of the content or
- # when the connection closes
- def handleResponseEnd(ctx):
- pass
-
tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect()
reactor.run()
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/shortContentLengthDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/shortContentLengthDisconnect b/plugins/experimental/metalink/test/shortContentLengthDisconnect
index 2e1c813..5662650 100755
--- a/plugins/experimental/metalink/test/shortContentLengthDisconnect
+++ b/plugins/experimental/metalink/test/shortContentLengthDisconnect
@@ -1,24 +1,24 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..2 shortContentLengthDisconnect
# The proxy sends the right Content-Length header and closes the client
-# connection if the server disconnects before the proxy sends the response
+# connection if the origin disconnects before the proxy sends the response
# headers'''
from twisted.internet import error, protocol, reactor, tcp
@@ -45,10 +45,10 @@ class factory(http.HTTPFactory):
# Disconnect before the proxy sends the response headers
ctx.transport.loseConnection()
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -69,7 +69,7 @@ class factory(protocol.ClientFactory):
else:
print 'ok 2 - The client connection closed'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleHeader(ctx, k, v):
if k.lower() == 'content-length':
@@ -81,7 +81,7 @@ class factory(protocol.ClientFactory):
print 'ok 1 - Content-Length header'
- # Avoid calling undefined handleResponse() at the end of the content (if
+ # Avoid calling undefined handleResponse() at the end of the message (if
# the proxy sent the wrong Content-Length header). (Override
# connectionLost() when the proxy closes the client connection or stop the
# reactor.)
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/54316fd3/plugins/experimental/metalink/test/zero
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/zero b/plugins/experimental/metalink/test/zero
index 6d42d56..3605a2b 100755
--- a/plugins/experimental/metalink/test/zero
+++ b/plugins/experimental/metalink/test/zero
@@ -1,20 +1,20 @@
#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
print '''1..1 zero
# The proxy doesn't crash if the Content-Length is zero'''
@@ -40,10 +40,10 @@ class factory(http.HTTPFactory):
ctx.setHeader('Content-Length', 0)
ctx.finish()
-server = tcp.Port(0, factory())
-server.startListening()
+origin = tcp.Port(0, factory())
+origin.startListening()
-print '# Listening on {0}:{1}'.format(*server.socket.getsockname())
+print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())
class factory(protocol.ClientFactory):
def clientConnectionFailed(ctx, connector, reason):
@@ -64,7 +64,7 @@ class factory(protocol.ClientFactory):
else:
print 'not ok 1 - Did the proxy crash? (The client connection closed.)'
- connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*server.socket.getsockname()))
+ connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleEndHeaders(ctx):
try:
[05/13] git commit: TS-2675: metalink: add missing TSCacheKeyDestroy
Posted by jp...@apache.org.
TS-2675: metalink: add missing TSCacheKeyDestroy
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/441c1c58
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/441c1c58
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/441c1c58
Branch: refs/heads/master
Commit: 441c1c58169b8ada22392adbf3f2ba63046125d4
Parents: 3ba8288
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 11:28:58 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/441c1c58/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index be48601..238bbee 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -345,6 +345,7 @@ transform_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
if (TSCacheKeyDigestSet(data->key, digest, sizeof(digest)) != TS_SUCCESS) {
TSContDestroy(contp);
+ TSCacheKeyDestroy(data->key);
TSfree(data);
return 0;
[11/13] git commit: TS-2675: metalink: Send our own
TS_EVENT_VCONN_WRITE_COMPLETE event upstream
Posted by jp...@apache.org.
TS-2675: metalink: Send our own TS_EVENT_VCONN_WRITE_COMPLETE event upstream
Send our own TS_EVENT_VCONN_WRITE_COMPLETE event upstream when the
input is complete otherwise HttpSM::update_stats() won't get called
and the transaction won't get logged. (If there are upstream
transformations they won't get a chance to clean up otherwise!)
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/f88a7260
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/f88a7260
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/f88a7260
Branch: refs/heads/master
Commit: f88a72606610ee79c458cee32b9ea34c16695c6b
Parents: ccc549e
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 14:02:19 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 4 ++++
1 file changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f88a7260/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index 8ebd2cc..c7fafcc 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -338,6 +338,10 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TSVIOReenable(transform_data->output_viop);
+ if (readerp) {
+ TSContCall(TSVIOContGet(input_viop), TS_EVENT_VCONN_WRITE_COMPLETE, input_viop);
+ }
+
/* Write the digest to the cache */
SHA256_Final((unsigned char *) digest, &transform_data->c);
[12/13] git commit: TS-2675: metalink: Reformat comments
Posted by jp...@apache.org.
TS-2675: metalink: Reformat comments
metalink: Clarify that we *must* check TSVConnClosedGet(), if only to clean up allocated data
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/a9a0b7cc
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/a9a0b7cc
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/a9a0b7cc
Branch: refs/heads/master
Commit: a9a0b7ccbbff448fd14ea2b22930ce6fc8b2c95f
Parents: f9d74b9
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Fri Mar 21 12:21:32 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
doc/reference/plugins/metalink.en.rst | 16 +-
plugins/experimental/metalink/metalink.cc | 298 +++++++++++--------
.../experimental/metalink/test/chunkedEncoding | 18 +-
.../metalink/test/chunkedEncodingDisconnect | 18 +-
.../experimental/metalink/test/contentLength | 11 +-
.../metalink/test/contentLengthDisconnect | 16 +-
.../test/finalChunkedEncodingDisconnect | 22 +-
plugins/experimental/metalink/test/http09 | 13 +-
plugins/experimental/metalink/test/location | 8 +-
plugins/experimental/metalink/test/longer | 18 +-
.../metalink/test/pipeliningDisconnect | 8 +-
.../test/shortChunkedEncodingDisconnect | 14 +-
.../metalink/test/shortClientDisconnect | 4 +-
.../metalink/test/shortContentLengthDisconnect | 14 +-
14 files changed, 273 insertions(+), 205 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/doc/reference/plugins/metalink.en.rst
----------------------------------------------------------------------
diff --git a/doc/reference/plugins/metalink.en.rst b/doc/reference/plugins/metalink.en.rst
index 50e1b32..ea71a87 100644
--- a/doc/reference/plugins/metalink.en.rst
+++ b/doc/reference/plugins/metalink.en.rst
@@ -6,7 +6,7 @@
except in compliance with the License. You may obtain a copy of
the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -70,13 +70,13 @@ Implementation Status
---------------------
The plugin implements the ``TS_HTTP_SEND_RESPONSE_HDR_HOOK`` hook to
-check and potentially rewrite the :mailheader:`Location: ...` and
-:mailheader:`Digest: SHA-256=...` headers after responses are cached.
-It doesn't do it before they're cached because the contents of the
-cache can change after responses are cached. It uses
-:c:func:`TSCacheRead` to check if the URL in the
-:mailheader:`Location: ...` header is already cached. In future, the
-plugin should also check if the URL is fresh or not.
+check and potentially rewrite the :mailheader:`Location` and
+:mailheader:`Digest` headers after responses are cached. It doesn't
+do it before they're cached because the contents of the cache can
+change after responses are cached. It uses :c:func:`TSCacheRead` to
+check if the URL in the :mailheader:`Location` header is already
+cached. In future, the plugin should also check if the URL is fresh
+or not.
The plugin implements the ``TS_HTTP_READ_RESPONSE_HDR_HOOK`` hook and
`a null transformation`_ to compute the SHA-256 digest for content as
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index ae8771c..207fdf1 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -27,21 +27,22 @@
#include "ts/ts.h"
-/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transformation.
- * Compute the SHA-256 digest of the content, write it to the cache and store
- * the request URL at that key.
+/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null
+ * transformation. Compute the SHA-256 digest of the content, write
+ * it to the cache and store the request URL at that key.
*
- * Implement TS_HTTP_SEND_RESPONSE_HDR_HOOK to check the "Location: ..." and
- * "Digest: SHA-256=..." headers. Use TSCacheRead() to check if the URL in the
- * "Location: ..." header is already cached. If not, potentially rewrite that
- * header. Do this after responses are cached because the cache will change.
+ * Implement TS_HTTP_SEND_RESPONSE_HDR_HOOK to check the Location and
+ * Digest headers. Use TSCacheRead() to check if the URL in the
+ * Location header is already cached. If not, potentially rewrite
+ * that header. Do this after responses are cached because the cache
+ * will change.
*
* More details are on the [wiki page] in the Traffic Server wiki.
*
* [wiki page] https://cwiki.apache.org/confluence/display/TS/Metalink */
-/* TSCacheWrite() and TSVConnWrite() data: Write the digest to the cache and
- * store the request URL at that key */
+/* TSCacheWrite() and TSVConnWrite() data: Write the digest to the
+ * cache and store the request URL at that key */
typedef struct {
TSHttpTxn txnp;
@@ -67,8 +68,8 @@ typedef struct {
} TransformData;
-/* TSCacheRead() and TSVConnRead() data: Check the "Location: ..." and
- * "Digest: SHA-256=..." headers */
+/* TSCacheRead() and TSVConnRead() data: Check the Location and Digest
+ * headers */
typedef struct {
TSHttpTxn txnp;
@@ -76,14 +77,14 @@ typedef struct {
TSMBuffer resp_bufp;
TSMLoc hdr_loc;
- /* "Location: ..." header */
+ /* Location header */
TSMLoc location_loc;
/* Cache key */
TSMLoc url_loc;
TSCacheKey key;
- /* "Digest: SHA-256=..." header */
+ /* Digest header */
TSMLoc digest_loc;
/* Digest header field value index */
@@ -96,7 +97,8 @@ typedef struct {
} SendData;
-/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transformation */
+/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null
+ * transformation */
/* Write the digest to the cache and store the request URL at that key */
@@ -187,9 +189,9 @@ write_vconn_write_complete(TSCont contp, void */* edata ATS_UNUSED */)
WriteData *data = (WriteData *) TSContDataGet(contp);
TSContDestroy(contp);
- /* The object is not committed to the cache until the vconnection is closed.
- * When all the data has been transferred, the user (contp) must do a
- * TSVConnClose() */
+ /* The object is not committed to the cache until the VConnection is
+ * closed. When all the data has been transferred, the user (contp)
+ * must do a TSVConnClose() */
TSVConnClose(data->connp);
TSIOBufferDestroy(data->cache_bufp);
@@ -198,8 +200,8 @@ write_vconn_write_complete(TSCont contp, void */* edata ATS_UNUSED */)
return 0;
}
-/* TSCacheWrite() and TSVConnWrite() handler: Write the digest to the cache and
- * store the request URL at that key */
+/* TSCacheWrite() and TSVConnWrite() handler: Write the digest to the
+ * cache and store the request URL at that key */
static int
write_handler(TSCont contp, TSEvent event, void *edata)
@@ -221,64 +223,113 @@ write_handler(TSCont contp, TSEvent event, void *edata)
return 0;
}
-/* Copy content from the input buffer to the output buffer without modification
- * and feed it through the message digest at the same time.
+/* Copy content from the input buffer to the output buffer without
+ * modification and feed it through the message digest at the same
+ * time.
*
- * 1. Check if we are "closed" before doing anything else to avoid errors.
+ * 1. Check if we are "closed" before doing anything else to avoid
+ * errors.
* 2. Then deal with any input that's available now.
- * 3. Check if the input is complete after dealing with any available input
- * in case it was the last of it. If it is complete, tell downstream,
- * thank upstream, and finish computing the digest. Otherwise either
- * wait for more input or abort if upstream is "closed".
+ * 3. Check if the input is complete after dealing with any
+ * available input in case it was the last of it. If it is
+ * complete, tell downstream, thank upstream, and finish
+ * computing the digest. Otherwise either wait for more input
+ * or abort if upstream is "closed".
*
- * The handler is guaranteed to get called at least once, even if the response
- * is 304 Not Modified, so we are guaranteed an opportunity to clean up e.g.
- * data that we allocated when we called TSTransformCreate().
+ * The handler is guaranteed to get called at least once, even if the
+ * response is 304 Not Modified, so we are guaranteed an opportunity
+ * to clean up e.g. data that we allocated when we called
+ * TSTransformCreate().
*
- * TS_EVENT_VCONN_WRITE_READY and TS_EVENT_VCONN_WRITE_COMPLETE events are sent
- * from downstream, e.g. by TransformTerminus::handle_event().
- * TS_EVENT_IMMEDIATE events are sent by INKVConnInternal::do_io_write(),
- * INKVConnInternal::do_io_close(), and INKVConnInternal::reenable() which are
- * called from upstream, e.g. by TransformVConnection::do_io_write(),
- * TransformVConnection::do_io_close(), and HttpTunnel::producer_handler().
+ * TS_EVENT_VCONN_WRITE_READY and TS_EVENT_VCONN_WRITE_COMPLETE events
+ * are sent from downstream, e.g. by
+ * TransformTerminus::handle_event(). TS_EVENT_IMMEDIATE events are
+ * sent by INKVConnInternal::do_io_write(),
+ * INKVConnInternal::do_io_close(), and INKVConnInternal::reenable()
+ * which are called from upstream, e.g. by
+ * TransformVConnection::do_io_write(),
+ * TransformVConnection::do_io_close(), and
+ * HttpTunnel::producer_handler().
*
- * Clean up the output buffer on TS_EVENT_VCONN_WRITE_COMPLETE and not before.
- * We are guaranteed a TS_EVENT_VCONN_WRITE_COMPLETE event *unless* we are
- * "closed". In that case we instead get a TS_EVENT_IMMEDIATE event where
- * TSVConnClosedGet() is one, so clean up the output buffer in that case as
- * well. We'll only ever get one event where TSVConnClosedGet() is one and it
- * will be our last, so there's no risk of a double free.
+ * Clean up the output buffer on TS_EVENT_VCONN_WRITE_COMPLETE and not
+ * before. We are guaranteed a TS_EVENT_VCONN_WRITE_COMPLETE event
+ * *unless* we are "closed". In that case we instead get a
+ * TS_EVENT_IMMEDIATE event where TSVConnClosedGet() is one. We'll
+ * only ever get one event where TSVConnClosedGet() is one and it will
+ * be our last, so we *must* check for this case and clean up then
+ * too. Because we'll only ever get one such event and it will be our
+ * last, there's no risk of double freeing.
*
- * The response headers get sent when TSVConnWrite() gets called and not
- * before. (We could potentially edit them until then.)
+ * The response headers get sent when TSVConnWrite() gets called and
+ * not before. (We could potentially edit them until then.)
*
- * The events say nothing about the state of the input. Gather this instead
- * from TSVConnClosedGet(), TSVIOReaderGet(), and TSVIONTodoGet() and handle
- * the end of the input independently from the TS_EVENT_VCONN_WRITE_COMPLETE
- * event from downstream.
+ * The events say nothing about the state of the input. Gather this
+ * instead from TSVConnClosedGet(), TSVIOReaderGet(), and
+ * TSVIONTodoGet() and handle the end of the input independently from
+ * the TS_EVENT_VCONN_WRITE_COMPLETE event from downstream.
*
- * When TSVConnClosedGet() is one, *we* are "closed". Some state is already
- * inconsistent and there's nothing to do except clean up. (This happens when
- * the response is 304 Not Modified or when the client or origin disconnect
- * before the message is complete.)
+ * When TSVConnClosedGet() is one, *we* are "closed". We *must* check
+ * for this case, if only to clean up allocated data. Some state is
+ * already inconsistent. (This happens when the response is 304 Not
+ * Modified or when the client or origin disconnect before the message
+ * is complete.)
*
- * When TSVIOReaderGet() is NULL, upstream is "closed". In that case it's
- * clearly an error to call TSIOBufferReaderAvail(), it's also an error at that
- * point to send any events upstream with TSContCall(). (This happens when the
- * content length is zero or when we get the final chunk of a
- * "Transfer-Encoding: chunked" response.)
+ * When TSVIOReaderGet() is NULL, upstream is "closed". In that case
+ * it's clearly an error to call TSIOBufferReaderAvail(), it's also an
+ * error at that point to send any events upstream with TSContCall().
+ * (This happens when the content length is zero or when we get the
+ * final chunk of a chunked response.)
*
- * The input is complete only when TSVIONTodoGet() is zero. (Don't update the
- * downstream nbytes otherwise!) Update the downstream nbytes when the input
- * is complete in case the response is "Transfer-Encoding: chunked" (in which
- * case nbytes is unknown until then). Downstream will (normally) send the
- * TS_EVENT_VCONN_WRITE_COMPLETE event (and the final chunk if the response is
- * "Transfer-Encoding: chunked") when ndone equals nbytes and not before.
+ * The input is complete only when TSVIONTodoGet() is zero. (Don't
+ * update the downstream nbytes otherwise!) Update the downstream
+ * nbytes when the input is complete in case the response is chunked
+ * (in which case nbytes is unknown until then). Downstream will
+ * (normally) send the TS_EVENT_VCONN_WRITE_COMPLETE event (and the
+ * final chunk if the response is chunked) when ndone equals nbytes
+ * and not before.
*
- * Send our own TS_EVENT_VCONN_WRITE_COMPLETE event upstream when the input is
- * complete otherwise HttpSM::update_stats() won't get called and the
- * transaction won't get logged. (If there are upstream transformations they
- * won't get a chance to clean up otherwise!) */
+ * Send our own TS_EVENT_VCONN_WRITE_COMPLETE event upstream when the
+ * input is complete otherwise HttpSM::update_stats() won't get called
+ * and the transaction won't get logged. (If there are upstream
+ * transformations they won't get a chance to clean up otherwise!)
+ *
+ * Summary of the cases into which each event can fall:
+ *
+ * Closed *We* are "closed". Clean up allocated data.
+ *
+ * Start First (and last) time the handler was called.
+ * (This happens when the response is 304 Not Modified.)
+ *
+ * Not start (This happens when the client or origin disconnect
+ * before the message is complete.)
+ *
+ * Start First time the handler was called. Initialize
+ * data here because we can't call TSVConnWrite()
+ * before TS_HTTP_RESPONSE_TRANSFORM_HOOK.
+ *
+ * Content length
+ *
+ * Chunked response
+ *
+ * Upstream closed
+ * (This happens when the content length is zero or
+ * when we get the final chunk of a chunked
+ * response.)
+ *
+ * Available input
+ *
+ * Input complete
+ *
+ * Deja vu There might be multiple TS_EVENT_IMMEDIATE events
+ * between the end of the input and the
+ * TS_EVENT_VCONN_WRITE_COMPLETE event from
+ * downstream.
+ *
+ * Not deja vu
+ * Tell downstream and thank upstream.
+ *
+ * Downstream complete
+ * Clean up the output buffer. */
static int
vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
@@ -290,16 +341,18 @@ vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
TransformData *transform_data = (TransformData *) TSContDataGet(contp);
- /* Check if we are "closed" before doing anything else to avoid errors. Some
- * state is already inconsistent and there's nothing to do except clean up.
- * (This happens if the response is 304 Not Modified or if the client or
+ /* Check if we are "closed" before doing anything else to avoid
+ * errors. We *must* check for this case, if only to clean up
+ * allocated data. Some state is already inconsistent. (This
+ * happens if the response is 304 Not Modified or if the client or
* origin disconnect before the message is complete.) */
int closed = TSVConnClosedGet(contp);
if (closed) {
TSContDestroy(contp);
/* Avoid failed assert "sdk_sanity_check_iocore_structure(bufp) ==
- * TS_SUCCESS" in TSIOBufferDestroy() if the response is 304 Not Modified */
+ * TS_SUCCESS" in TSIOBufferDestroy() if the response is 304 Not
+ * Modified */
if (transform_data->output_bufp) {
TSIOBufferDestroy(transform_data->output_bufp);
}
@@ -319,20 +372,19 @@ vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
transform_data->output_bufp = TSIOBufferCreate();
TSIOBufferReader readerp = TSIOBufferReaderAlloc(transform_data->output_bufp);
- /* Determines the "Content-Length: ..." header
- * (or "Transfer-Encoding: chunked") */
+ /* Determines the Content-Length header (or a chunked response) */
- /* Avoid failed assert "nbytes >= 0" if "Transfer-Encoding: chunked" */
+ /* Avoid failed assert "nbytes >= 0" if the response is chunked */
int nbytes = TSVIONBytesGet(input_viop);
transform_data->output_viop = TSVConnWrite(output_connp, contp, readerp, nbytes < 0 ? INT64_MAX : nbytes);
SHA256_Init(&transform_data->c);
}
- /* Then deal with any input that's available now. Avoid failed assert
- * "sdk_sanity_check_iocore_structure(readerp) == TS_SUCCESS" in
- * TSIOBufferReaderAvail() if the content length is zero or when we get the
- * final chunk of a "Transfer-Encoding: chunked" response. */
+ /* Then deal with any input that's available now. Avoid failed
+ * assert "sdk_sanity_check_iocore_structure(readerp) == TS_SUCCESS"
+ * in TSIOBufferReaderAvail() if the content length is zero or when
+ * we get the final chunk of a chunked response. */
TSIOBufferReader readerp = TSVIOReaderGet(input_viop);
if (readerp) {
@@ -359,18 +411,19 @@ vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
}
}
- /* Check if the input is complete after dealing with any available input in
- * case it was the last of it */
+ /* Check if the input is complete after dealing with any available
+ * input in case it was the last of it */
int ntodo = TSVIONTodoGet(input_viop);
if (ntodo) {
TSVIOReenable(transform_data->output_viop);
TSContCall(TSVIOContGet(input_viop), TS_EVENT_VCONN_WRITE_READY, input_viop);
- /* Don't finish computing the digest (and tell downstream and thank upstream)
- * more than once! There might be multiple TS_EVENT_IMMEDIATE events between
- * the end of the input and the TS_EVENT_VCONN_WRITE_COMPLETE event from
- * downstream, e.g. INKVConnInternal::reenable() is called by
+ /* Don't finish computing the digest (and tell downstream and thank
+ * upstream) more than once! There might be multiple
+ * TS_EVENT_IMMEDIATE events between the end of the input and the
+ * TS_EVENT_VCONN_WRITE_COMPLETE event from downstream, e.g.
+ * INKVConnInternal::reenable() is called by
* HttpTunnel::producer_handler() when more input is available and
* TransformVConnection::do_io_shutdown() is called by
* HttpSM::tunnel_handler_transform_write() when we send our own
@@ -382,9 +435,9 @@ vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
TSVIOReenable(transform_data->output_viop);
- /* Avoid failed assert "c->alive == true" in TSContCall() if the content
- * length is zero or when we get the final chunk of a
- * "Transfer-Encoding: chunked" response */
+ /* Avoid failed assert "c->alive == true" in TSContCall() if the
+ * content length is zero or when we get the final chunk of a
+ * chunked response */
if (readerp) {
TSContCall(TSVIOContGet(input_viop), TS_EVENT_VCONN_WRITE_COMPLETE, input_viop);
}
@@ -408,8 +461,9 @@ vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
return 0;
}
- /* Can't reuse the TSTransformCreate() continuation because we don't know
- * whether to destroy it in cache_open_write()/cache_open_write_failed() or
+ /* Can't reuse the TSTransformCreate() continuation because we
+ * don't know whether to destroy it in
+ * cache_open_write()/cache_open_write_failed() or
* transform_vconn_write_complete() */
contp = TSContCreate(write_handler, NULL);
TSContDataSet(contp, write_data);
@@ -432,7 +486,8 @@ transform_vconn_write_complete(TSCont contp, void */* edata ATS_UNUSED */)
return 0;
}
-/* TSTransformCreate() handler: Compute the SHA-256 digest of the content */
+/* TSTransformCreate() handler: Compute the SHA-256 digest of the
+ * content */
static int
transform_handler(TSCont contp, TSEvent event, void *edata)
@@ -452,8 +507,8 @@ transform_handler(TSCont contp, TSEvent event, void *edata)
return 0;
}
-/* Compute the SHA-256 digest of the content, write it to the cache and store
- * the request URL at that key */
+/* Compute the SHA-256 digest of the content, write it to the cache
+ * and store the request URL at that key */
static int
http_read_response_hdr(TSCont /* contp ATS_UNUSED */, void *edata)
@@ -461,8 +516,8 @@ http_read_response_hdr(TSCont /* contp ATS_UNUSED */, void *edata)
TransformData *data = (TransformData *) TSmalloc(sizeof(TransformData));
data->txnp = (TSHttpTxn) edata;
- /* Can't initialize data here because we can't call TSVConnWrite() before
- * TS_HTTP_RESPONSE_TRANSFORM_HOOK */
+ /* Can't initialize data here because we can't call TSVConnWrite()
+ * before TS_HTTP_RESPONSE_TRANSFORM_HOOK */
data->output_bufp = NULL;
TSVConn connp = TSTransformCreate(transform_handler, data->txnp);
@@ -475,8 +530,8 @@ http_read_response_hdr(TSCont /* contp ATS_UNUSED */, void *edata)
return 0;
}
-/* Implement TS_HTTP_SEND_RESPONSE_HDR_HOOK to check the "Location: ..." and
- * "Digest: SHA-256=..." headers */
+/* Implement TS_HTTP_SEND_RESPONSE_HDR_HOOK to check the Location and
+ * Digest headers */
/* Read the URL stored at the digest */
@@ -515,7 +570,8 @@ cache_open_read_failed(TSCont contp, void */* edata ATS_UNUSED */)
return 0;
}
-/* TSCacheRead() handler: Check if the URL stored at the digest is cached */
+/* TSCacheRead() handler: Check if the URL stored at the digest is
+ * cached */
static int
rewrite_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */)
@@ -525,7 +581,7 @@ rewrite_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */)
switch (event) {
- /* Yes: Rewrite the "Location: ..." header and reenable the response */
+ /* Yes: Rewrite the Location header and reenable the response */
case TS_EVENT_CACHE_OPEN_READ:
TSMimeHdrFieldValuesClear(data->resp_bufp, data->hdr_loc, data->location_loc);
@@ -569,8 +625,9 @@ vconn_read_ready(TSCont contp, void */* edata ATS_UNUSED */)
/* No allocation, freed with data->cache_bufp? */
const char *value = data->value = TSIOBufferBlockReadStart(blockp, readerp, &data->length);
- /* The start pointer is both an input and an output parameter. After a
- * successful parse the start pointer equals the end pointer. */
+ /* The start pointer is both an input and an output parameter.
+ * After a successful parse the start pointer equals the end
+ * pointer. */
if (TSUrlParse(data->resp_bufp, data->url_loc, &value, value + data->length) != TS_PARSE_DONE) {
TSIOBufferDestroy(data->cache_bufp);
@@ -613,8 +670,8 @@ vconn_read_ready(TSCont contp, void */* edata ATS_UNUSED */)
return 0;
}
-/* TSCacheRead() and TSVConnRead() handler: Check if the "Digest: SHA-256=..."
- * digest already exists in the cache */
+/* TSCacheRead() and TSVConnRead() handler: Check if the digest
+ * already exists in the cache */
static int
digest_handler(TSCont contp, TSEvent event, void *edata)
@@ -639,7 +696,7 @@ digest_handler(TSCont contp, TSEvent event, void *edata)
return 0;
}
-/* TSCacheRead() handler: Check if the "Location: ..." URL is already cached */
+/* TSCacheRead() handler: Check if the Location URL is already cached */
static int
location_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */)
@@ -658,7 +715,7 @@ location_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */)
case TS_EVENT_CACHE_OPEN_READ:
break;
- /* No: Check if the "Digest: SHA-256=..." digest already exists in the cache */
+ /* No: Check if the digest already exists in the cache */
case TS_EVENT_CACHE_OPEN_READ_FAILED:
/* No allocation, freed with data->resp_bufp? */
@@ -670,7 +727,7 @@ location_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */)
TSHandleMLocRelease(data->resp_bufp, data->hdr_loc, data->digest_loc);
- /* Check if the "Digest: SHA-256=..." digest already exists in the cache */
+ /* Check if the digest already exists in the cache */
contp = TSContCreate(digest_handler, NULL);
TSContDataSet(contp, data);
@@ -697,9 +754,9 @@ location_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */)
return 0;
}
-/* Use TSCacheRead() to check if the URL in the "Location: ..." header is
- * already cached. If not, potentially rewrite that header. Do this after
- * responses are cached because the cache will change. */
+/* Use TSCacheRead() to check if the URL in the Location header is
+ * already cached. If not, potentially rewrite that header. Do this
+ * after responses are cached because the cache will change. */
static int
http_send_response_hdr(TSCont contp, void *edata)
@@ -719,20 +776,21 @@ http_send_response_hdr(TSCont contp, void *edata)
return 0;
}
- /* If Instance Digests are not provided by the Metalink servers, the Link
- * header fields pertaining to this specification MUST be ignored */
+ /* If Instance Digests are not provided by the Metalink servers, the
+ * Link header fields pertaining to this specification MUST be
+ * ignored */
- /* Metalinks contain whole file hashes as described in Section 6, and MUST
- * include SHA-256, as specified in [FIPS-180-3] */
+ /* Metalinks contain whole file hashes as described in Section 6,
+ * and MUST include SHA-256, as specified in [FIPS-180-3] */
/* Assumption: We want to minimize cache reads, so check first that
*
- * 1. the response has a "Location: ..." header and
- * 2. the response has a "Digest: SHA-256=..." header.
+ * 1. the response has a Location header and
+ * 2. the response has a Digest header.
*
* Then scan if the URL or digest already exist in the cache. */
- /* If the response has a "Location: ..." header */
+ /* If the response has a Location header */
data->location_loc = TSMimeHdrFieldFind(data->resp_bufp, data->hdr_loc, TS_MIME_FIELD_LOCATION, TS_MIME_LEN_LOCATION);
if (!data->location_loc) {
TSHandleMLocRelease(data->resp_bufp, TS_NULL_MLOC, data->hdr_loc);
@@ -745,9 +803,9 @@ http_send_response_hdr(TSCont contp, void *edata)
TSUrlCreate(data->resp_bufp, &data->url_loc);
- /* If we can't parse or lookup the "Location: ..." URL, should we still check
- * if the response has a "Digest: SHA-256=..." header? No: Can't parse or
- * lookup the URL in the "Location: ..." header is an error. */
+ /* If we can't parse or lookup the Location URL, should we still
+ * check if the response has a Digest header? No: Can't parse or
+ * lookup the URL in the Location header is an error. */
/* No allocation, freed with data->resp_bufp? */
value = TSMimeHdrFieldValueStringGet(data->resp_bufp, data->hdr_loc, data->location_loc, -1, &length);
@@ -777,7 +835,7 @@ http_send_response_hdr(TSCont contp, void *edata)
return 0;
}
- /* ... and a "Digest: SHA-256=..." header */
+ /* ... and a Digest header */
data->digest_loc = TSMimeHdrFieldFind(data->resp_bufp, data->hdr_loc, "Digest", 6);
while (data->digest_loc) {
@@ -790,7 +848,7 @@ http_send_response_hdr(TSCont contp, void *edata)
continue;
}
- /* Check if the "Location: ..." URL is already cached */
+ /* Check if the Location URL is already cached */
contp = TSContCreate(location_handler, NULL);
TSContDataSet(contp, data);
@@ -807,7 +865,7 @@ http_send_response_hdr(TSCont contp, void *edata)
data->digest_loc = next_loc;
}
- /* Didn't find a "Digest: SHA-256=..." header, just reenable the response */
+ /* Didn't find a Digest header, just reenable the response */
TSCacheKeyDestroy(data->key);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/chunkedEncoding
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/chunkedEncoding b/plugins/experimental/metalink/test/chunkedEncoding
index 7a2ed37..66c8d9b 100755
--- a/plugins/experimental/metalink/test/chunkedEncoding
+++ b/plugins/experimental/metalink/test/chunkedEncoding
@@ -39,8 +39,9 @@ class factory(http.HTTPFactory):
ctx.write('chunkedEncoding')
- # If the proxy reads the final chunk before it sends the response
- # headers, it may send a Content-Length header vs. a chunked response
+ # If the proxy reads the final chunk before it sends the
+ # response headers, it may send a Content-Length header vs. a
+ # chunked response
reactor.callLater(1, ctx.finish)
origin = tcp.Port(0, factory())
@@ -76,13 +77,14 @@ class factory(protocol.ClientFactory):
# No hope of a final chunk now
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the message (if
- # the proxy sent a Content-Length header vs. a chunked response).
- # (Override connectionLost() when the proxy crashes or stop the reactor.)
+ # Avoid calling undefined handleResponse() at the end of the
+ # message (if the proxy sent a Content-Length header vs. a chunked
+ # response). (Override connectionLost() when the proxy crashes or
+ # we stop the reactor.)
#
- # Data that was already received will be processed (the end of the
- # headers), then shutdown events will fire (connections will be closed),
- # and then finally the reactor will grind to a halt.
+ # Data that was already received will get processed (the end of
+ # the headers), then shutdown events will fire (connections will
+ # get closed), and then finally the reactor will grind to a halt.
def handleResponseEnd(ctx):
pass
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/chunkedEncodingDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/chunkedEncodingDisconnect b/plugins/experimental/metalink/test/chunkedEncodingDisconnect
index 91593d0..e39549f 100755
--- a/plugins/experimental/metalink/test/chunkedEncodingDisconnect
+++ b/plugins/experimental/metalink/test/chunkedEncodingDisconnect
@@ -17,8 +17,8 @@
# permissions and limitations under the License.
print '''1..1 chunkedEncodingDisconnect
-# The proxy closes the client connection and doesn't send a final chunk if the
-# origin disconnects without sending one'''
+# The proxy closes the client connection and doesn't send a final
+# chunk if the origin disconnects without sending one'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -40,9 +40,9 @@ class factory(http.HTTPFactory):
ctx.write('chunkedEncodingDisconnect')
- # If the origin disconnects before the proxy sends the response
- # headers, the proxy may send a Content-Length header vs. a chunked
- # response
+ # If the origin disconnects before the proxy sends the
+ # response headers, the proxy may send a Content-Length header
+ # vs. a chunked response
reactor.callLater(1, ctx.transport.loseConnection)
origin = tcp.Port(0, factory())
@@ -78,10 +78,10 @@ class factory(protocol.ClientFactory):
# Who cares what happens now?
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the message (if
- # the proxy sent a Content-Length header vs. a chunked response).
- # (Override connectionLost() when the proxy closes the client connection or
- # stop the reactor.)
+ # Avoid calling undefined handleResponse() at the end of the
+ # message (if the proxy sent a Content-Length header vs. a chunked
+ # response). (Override connectionLost() when the proxy closes the
+ # client connection or we stop the reactor.)
def handleResponseEnd(ctx):
pass
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/contentLength
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/contentLength b/plugins/experimental/metalink/test/contentLength
index 92708e7..f53efe7 100755
--- a/plugins/experimental/metalink/test/contentLength
+++ b/plugins/experimental/metalink/test/contentLength
@@ -85,12 +85,13 @@ class factory(protocol.ClientFactory):
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the message.
- # (Override connectionLost() when the proxy crashes or stop the reactor.)
+ # Avoid calling undefined handleResponse() at the end of the
+ # message. (Override connectionLost() when the proxy crashes or
+ # we stop the reactor.)
#
- # Data that was already received will be processed (the end of the
- # headers), then shutdown events will fire (connections will be closed),
- # and then finally the reactor will grind to a halt.
+ # Data that was already received will get processed (the end of
+ # the headers), then shutdown events will fire (connections will
+ # get closed), and then finally the reactor will grind to a halt.
def handleResponseEnd(ctx):
pass
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/contentLengthDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/contentLengthDisconnect b/plugins/experimental/metalink/test/contentLengthDisconnect
index 1627d0e..17d927f 100755
--- a/plugins/experimental/metalink/test/contentLengthDisconnect
+++ b/plugins/experimental/metalink/test/contentLengthDisconnect
@@ -17,7 +17,8 @@
# permissions and limitations under the License.
print '''1..2 contentLengthDisconnect
-# The proxy closes the client connection if the origin disconnects prematurely'''
+# The proxy closes the client connection if the origin disconnects
+# prematurely'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -40,8 +41,9 @@ class factory(http.HTTPFactory):
ctx.setHeader('Content-Length', 24)
ctx.write('contentLengthDisconnect')
- # If the origin disconnects before the proxy sends the response
- # headers, the proxy may send the wrong Content-Length header
+ # If the origin disconnects before the proxy sends the
+ # response headers, the proxy may send the wrong
+ # Content-Length header
reactor.callLater(1, ctx.transport.loseConnection)
origin = tcp.Port(0, factory())
@@ -80,10 +82,10 @@ class factory(protocol.ClientFactory):
print 'ok 1 - Content-Length header'
- # Avoid calling undefined handleResponse() at the end of the message (if
- # the proxy sent the wrong Content-Length header). (Override
- # connectionLost() when the proxy closes the client connection or stop the
- # reactor.)
+ # Avoid calling undefined handleResponse() at the end of the
+ # message (if the proxy sent the wrong Content-Length header).
+ # (Override connectionLost() when the proxy closes the client
+ # connection or we stop the reactor.)
def handleResponseEnd(ctx):
pass
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect b/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect
index 32011bc..6185e9a 100755
--- a/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect
+++ b/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect
@@ -17,8 +17,8 @@
# permissions and limitations under the License.
print '''1..1 finalChunkEncodingDisconnect
-# The proxy forwards the final chunk even if the origin disconnects immediately
-# afterward'''
+# The proxy forwards the final chunk even if the origin disconnects
+# immediately afterward'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -40,8 +40,9 @@ class factory(http.HTTPFactory):
ctx.write('finalChunkedEncodingDisconnect')
- # If the proxy reads the final chunk before it sends the response
- # headers, it may send a Content-Length header vs. a chunked response
+ # If the proxy reads the final chunk before it sends the
+ # response headers, it may send a Content-Length header vs. a
+ # chunked response
def callback():
try:
ctx.finish()
@@ -89,13 +90,14 @@ class factory(protocol.ClientFactory):
# No hope of a final chunk now
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the message (if
- # the proxy sent a Content-Length header vs. a chunked response).
- # (Override connectionLost() when the proxy crashes or stop the reactor.)
+ # Avoid calling undefined handleResponse() at the end of the
+ # message (if the proxy sent a Content-Length header vs. a chunked
+ # response). (Override connectionLost() when the proxy crashes or
+ # we stop the reactor.)
#
- # Data that was already received will be processed (the end of the
- # headers), then shutdown events will fire (connections will be closed),
- # and then finally the reactor will grind to a halt.
+ # Data that was already received will get processed (the end of
+ # the headers), then shutdown events will fire (connections will
+ # get closed), and then finally the reactor will grind to a halt.
def handleResponseEnd(ctx):
pass
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/http09
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/http09 b/plugins/experimental/metalink/test/http09
index e9f7c77..b53d200 100755
--- a/plugins/experimental/metalink/test/http09
+++ b/plugins/experimental/metalink/test/http09
@@ -21,12 +21,13 @@ print '''1..1 http09
# http://www.w3.org/Protocols/HTTP/AsImplemented
#
-# The proxy crashes only after the response is complete. It closes the client
-# connection whether it crashes or not because an HTTP/0.9 response is complete
-# only after the origin closes its connection, and then the proxy normally does
-# the same thing to the client connection (although it upgrades the response to
-# HTTP/1.1). So the only way to check that the proxy didn't crash is to open
-# another connection.
+# The proxy crashes only after the response is complete. It closes
+# the client connection whether it crashes or not because an HTTP/0.9
+# response is complete only after the origin closes its connection,
+# and then the proxy normally does the same thing to the client
+# connection (although it upgrades the response to HTTP/1.1). So the
+# only way to check that the proxy didn't crash is to open another
+# connection.
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/location
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/location b/plugins/experimental/metalink/test/location
index 77b601e..97eb32a 100755
--- a/plugins/experimental/metalink/test/location
+++ b/plugins/experimental/metalink/test/location
@@ -72,10 +72,10 @@ class factory(protocol.ClientFactory):
else:
print 'not ok 1 - Did the proxy crash? (The client connection closed.)'
- # Get a response with a Location and a Digest header and check that the
- # Location header is not rewritten. Then get the same response after
- # caching a matching file from a different URL and check that this time the
- # header is rewritten.
+ # Get a response with a Location and a Digest header and check
+ # that the Location header is not rewritten. Then get the same
+ # response after caching a matching file from a different URL and
+ # check that this time the header is rewritten.
connectionMade = lambda ctx: ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\nGET {0}:{1}/location HTTP/1.1\r\n\r\nGET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
def handleResponsePart(ctx, data):
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/longer
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/longer b/plugins/experimental/metalink/test/longer
index 259ad7d..d298451 100755
--- a/plugins/experimental/metalink/test/longer
+++ b/plugins/experimental/metalink/test/longer
@@ -17,10 +17,11 @@
# permissions and limitations under the License.
print '''1..1 longer
-# The proxy doesn't choke if the origin sends more content than it advertised'''
+# The proxy doesn't choke if the origin sends more content than it
+# advertised'''
-# Unlike the contentLength test, don't stop the reactor at the end of the
-# headers. Give the proxy time to choke.
+# Unlike the contentLength test, don't stop the reactor at the end of
+# the headers. Give the proxy time to choke.
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -78,12 +79,13 @@ class factory(protocol.ClientFactory):
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the message.
- # (Override connectionLost() when the proxy crashes or stop the reactor.)
+ # Avoid calling undefined handleResponse() at the end of the
+ # message. (Override connectionLost() when the proxy crashes or
+ # we stop the reactor.)
#
- # Data that was already received will be processed (the end of the
- # headers), then shutdown events will fire (connections will be closed),
- # and then finally the reactor will grind to a halt.
+ # Data that was already received will get processed (the end of
+ # the headers), then shutdown events will fire (connections will
+ # get closed), and then finally the reactor will grind to a halt.
def handleResponseEnd(ctx):
pass
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/pipeliningDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/pipeliningDisconnect b/plugins/experimental/metalink/test/pipeliningDisconnect
index 152e2cf..2d97dc1 100755
--- a/plugins/experimental/metalink/test/pipeliningDisconnect
+++ b/plugins/experimental/metalink/test/pipeliningDisconnect
@@ -17,8 +17,8 @@
# permissions and limitations under the License.
print '''1..1 pipeliningDisconnect
-# The proxy doesn't crash if INKVConnInternal::do_io_close() gets called after
-# a message is already complete'''
+# The proxy doesn't crash if INKVConnInternal::do_io_close() gets
+# called after a message is already complete'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -83,8 +83,8 @@ class factory(protocol.ClientFactory):
def connectionMade(ctx):
# Somehow these magic words frequently cause
- # INKVConnInternal::do_io_close() to get called after a message is
- # already complete
+ # INKVConnInternal::do_io_close() to get called after a message
+ # is already complete
ctx.transport.write('GET {0}:{1}/pipeliningDisconnect0 HTTP/1.1\r\n\r\nGET {0}:{1}/pipeliningDisconnect1 HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))
ctx.transport.loseConnection()
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect b/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect
index 3c52858..14e5a6f 100755
--- a/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect
+++ b/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect
@@ -17,9 +17,9 @@
# permissions and limitations under the License.
print '''1..1 shortChunkedEncodingDisconnect
-# The proxy closes the client connection and doesn't send a final chunk if the
-# origin disconnects without sending one, before the proxy sends the response
-# headers'''
+# The proxy closes the client connection and doesn't send a final
+# chunk if the origin disconnects without sending one, before the
+# proxy sends the response headers'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -77,10 +77,10 @@ class factory(protocol.ClientFactory):
# Who cares what happens now?
reactor.stop()
- # Avoid calling undefined handleResponse() at the end of the message (if
- # the proxy sent a Content-Length header vs. a chunked response).
- # (Override connectionLost() when the proxy closes the client connection or
- # stop the reactor.)
+ # Avoid calling undefined handleResponse() at the end of the
+ # message (if the proxy sent a Content-Length header vs. a chunked
+ # response). (Override connectionLost() when the proxy closes the
+ # client connection or we stop the reactor.)
def handleResponseEnd(ctx):
pass
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/shortClientDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/shortClientDisconnect b/plugins/experimental/metalink/test/shortClientDisconnect
index 6956c78..a36169e 100755
--- a/plugins/experimental/metalink/test/shortClientDisconnect
+++ b/plugins/experimental/metalink/test/shortClientDisconnect
@@ -17,8 +17,8 @@
# permissions and limitations under the License.
print '''1..1 shortClientDisconnect
-# The proxy doesn't crash if the client disconnects before the proxy sends the
-# response headers'''
+# The proxy doesn't crash if the client disconnects before the proxy
+# sends the response headers'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/a9a0b7cc/plugins/experimental/metalink/test/shortContentLengthDisconnect
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/test/shortContentLengthDisconnect b/plugins/experimental/metalink/test/shortContentLengthDisconnect
index 5662650..b2a74fa 100755
--- a/plugins/experimental/metalink/test/shortContentLengthDisconnect
+++ b/plugins/experimental/metalink/test/shortContentLengthDisconnect
@@ -17,9 +17,9 @@
# permissions and limitations under the License.
print '''1..2 shortContentLengthDisconnect
-# The proxy sends the right Content-Length header and closes the client
-# connection if the origin disconnects before the proxy sends the response
-# headers'''
+# The proxy sends the right Content-Length header and closes the
+# client connection if the origin disconnects before the proxy sends
+# the response headers'''
from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http
@@ -81,10 +81,10 @@ class factory(protocol.ClientFactory):
print 'ok 1 - Content-Length header'
- # Avoid calling undefined handleResponse() at the end of the message (if
- # the proxy sent the wrong Content-Length header). (Override
- # connectionLost() when the proxy closes the client connection or stop the
- # reactor.)
+ # Avoid calling undefined handleResponse() at the end of the
+ # message (if the proxy sent the wrong Content-Length header).
+ # (Override connectionLost() when the proxy closes the client
+ # connection or we stop the reactor.)
def handleResponseEnd(ctx):
pass
[06/13] git commit: TS-2675: metalink: Reuse TSCacheWrite() vs.
TSTransformCreate() continuation
Posted by jp...@apache.org.
TS-2675: metalink: Reuse TSCacheWrite() vs. TSTransformCreate() continuation
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/d25b00c2
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/d25b00c2
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/d25b00c2
Branch: refs/heads/master
Commit: d25b00c2f82701f8de51cc96d941049c2f63b739
Parents: 441c1c5
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 11:57:17 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
plugins/experimental/metalink/metalink.cc | 166 +++++++++++++------------
1 file changed, 87 insertions(+), 79 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d25b00c2/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index 238bbee..77f62dc 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -49,16 +49,20 @@
*
* [wiki page] https://cwiki.apache.org/confluence/display/TS/Metalink */
-/* TSVConnWrite() data: Store the request URL */
+/* TSCacheWrite() and TSVConnWrite() data: Write the digest to the cache and
+ * store the request URL at that key */
typedef struct {
+ TSHttpTxn txnp;
+
+ TSCacheKey key;
+
TSVConn connp;
TSIOBuffer cache_bufp;
} WriteData;
-/* TSTransformCreate() and TSCacheWrite() data: Compute the SHA-256 digest of
- * the content and write it to the cache */
+/* TSTransformCreate() data: Compute the SHA-256 digest of the content */
typedef struct {
TSHttpTxn txnp;
@@ -70,8 +74,6 @@ typedef struct {
/* Message digest handle */
SHA256_CTX c;
- TSCacheKey key;
-
} TransformData;
/* TSCacheRead() and TSVConnRead() data: Check the "Location: ..." and
@@ -102,43 +104,7 @@ typedef struct {
/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transform */
-/* Store the request URL */
-
-static int
-write_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
-{
- WriteData *data = (WriteData *) TSContDataGet(contp);
- TSContDestroy(contp);
-
- /* The object is not committed to the cache until the vconnection is closed.
- * When all the data has been transferred, the user (contp) must do a
- * TSVConnClose() */
- TSVConnClose(data->connp);
-
- TSIOBufferDestroy(data->cache_bufp);
- TSfree(data);
-
- return 0;
-}
-
-/* TSVConnWrite() handler: Store the request URL */
-
-static int
-write_handler(TSCont contp, TSEvent event, void *edata)
-{
- switch (event) {
- case TS_EVENT_VCONN_WRITE_COMPLETE:
- return write_vconn_write_complete(contp, edata);
-
- default:
- TSAssert(!"Unexpected event");
- }
-
- return 0;
-}
-
-/* Compute the SHA-256 digest of the content, write it to the cache and store
- * the request URL at that key */
+/* Write the digest to the cache and store the request URL at that key */
static int
cache_open_write(TSCont contp, void *edata)
@@ -151,22 +117,26 @@ cache_open_write(TSCont contp, void *edata)
const char *value;
int length;
- TransformData *transform_data = (TransformData *) TSContDataGet(contp);
- TSContDestroy(contp);
+ WriteData *data = (WriteData *) TSContDataGet(contp);
+ data->connp = (TSVConn) edata;
- TSCacheKeyDestroy(transform_data->key);
+ TSCacheKeyDestroy(data->key);
- if (TSHttpTxnClientReqGet(transform_data->txnp, &req_bufp, &hdr_loc) != TS_SUCCESS) {
+ if (TSHttpTxnClientReqGet(data->txnp, &req_bufp, &hdr_loc) != TS_SUCCESS) {
TSError("Couldn't retrieve client request header");
- TSfree(transform_data);
+ TSContDestroy(contp);
+
+ TSfree(data);
return 0;
}
- TSfree(transform_data);
-
if (TSHttpHdrUrlGet(req_bufp, hdr_loc, &url_loc) != TS_SUCCESS) {
+ TSContDestroy(contp);
+
+ TSfree(data);
+
TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, hdr_loc);
return 0;
@@ -174,6 +144,10 @@ cache_open_write(TSCont contp, void *edata)
value = TSUrlStringGet(req_bufp, url_loc, &length);
if (!value) {
+ TSContDestroy(contp);
+
+ TSfree(data);
+
TSHandleMLocRelease(req_bufp, hdr_loc, url_loc);
TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, hdr_loc);
@@ -185,20 +159,13 @@ cache_open_write(TSCont contp, void *edata)
/* Store the request URL */
- WriteData *write_data = (WriteData *) TSmalloc(sizeof(WriteData));
- write_data->connp = (TSVConn) edata;
-
- /* Can't reuse TSTransformCreate() continuation because it already implements
- * TS_EVENT_VCONN_WRITE_COMPLETE */
- contp = TSContCreate(write_handler, NULL);
- TSContDataSet(contp, write_data);
-
- write_data->cache_bufp = TSIOBufferCreate();
- TSIOBufferReader readerp = TSIOBufferReaderAlloc(write_data->cache_bufp);
+ data->cache_bufp = TSIOBufferCreate();
+ TSIOBufferReader readerp = TSIOBufferReaderAlloc(data->cache_bufp);
- int nbytes = TSIOBufferWrite(write_data->cache_bufp, value, length);
+ int nbytes = TSIOBufferWrite(data->cache_bufp, value, length);
- TSVConnWrite(write_data->connp, contp, readerp, nbytes);
+ /* Reuse the TSCacheWrite() continuation */
+ TSVConnWrite(data->connp, contp, readerp, nbytes);
return 0;
}
@@ -208,7 +175,7 @@ cache_open_write(TSCont contp, void *edata)
static int
cache_open_write_failed(TSCont contp, void * /* edata ATS_UNUSED */)
{
- TransformData *data = (TransformData *) TSContDataGet(contp);
+ WriteData *data = (WriteData *) TSContDataGet(contp);
TSContDestroy(contp);
TSCacheKeyDestroy(data->key);
@@ -217,6 +184,46 @@ cache_open_write_failed(TSCont contp, void * /* edata ATS_UNUSED */)
return 0;
}
+static int
+write_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
+{
+ WriteData *data = (WriteData *) TSContDataGet(contp);
+ TSContDestroy(contp);
+
+ /* The object is not committed to the cache until the vconnection is closed.
+ * When all the data has been transferred, the user (contp) must do a
+ * TSVConnClose() */
+ TSVConnClose(data->connp);
+
+ TSIOBufferDestroy(data->cache_bufp);
+ TSfree(data);
+
+ return 0;
+}
+
+/* TSCacheWrite() and TSVConnWrite() handler: Write the digest to the cache and
+ * store the request URL at that key */
+
+static int
+write_handler(TSCont contp, TSEvent event, void *edata)
+{
+ switch (event) {
+ case TS_EVENT_CACHE_OPEN_WRITE:
+ return cache_open_write(contp, edata);
+
+ case TS_EVENT_CACHE_OPEN_WRITE_FAILED:
+ return cache_open_write_failed(contp, edata);
+
+ case TS_EVENT_VCONN_WRITE_COMPLETE:
+ return write_vconn_write_complete(contp, edata);
+
+ default:
+ TSAssert(!"Unexpected event");
+ }
+
+ return 0;
+}
+
/* Copy content from the input buffer to the output buffer without modification
* while at the same time feeding it to the message digest */
@@ -335,40 +342,41 @@ transform_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
{
char digest[32];
- TransformData *data = (TransformData *) TSContDataGet(contp);
+ TransformData *transform_data = (TransformData *) TSContDataGet(contp);
+ TSContDestroy(contp);
- TSIOBufferDestroy(data->output_bufp);
+ TSIOBufferDestroy(transform_data->output_bufp);
- SHA256_Final((unsigned char *) digest, &data->c);
+ SHA256_Final((unsigned char *) digest, &transform_data->c);
- data->key = TSCacheKeyCreate();
- if (TSCacheKeyDigestSet(data->key, digest, sizeof(digest)) != TS_SUCCESS) {
- TSContDestroy(contp);
+ WriteData *write_data = (WriteData *) TSmalloc(sizeof(WriteData));
+ write_data->txnp = transform_data->txnp;
- TSCacheKeyDestroy(data->key);
- TSfree(data);
+ TSfree(transform_data);
+
+ write_data->key = TSCacheKeyCreate();
+ if (TSCacheKeyDigestSet(write_data->key, digest, sizeof(digest)) != TS_SUCCESS) {
+
+ TSCacheKeyDestroy(write_data->key);
+ TSfree(write_data);
return 0;
}
- /* Reuse the TSTransformCreate() continuation */
- TSCacheWrite(contp, data->key);
+ contp = TSContCreate(write_handler, NULL);
+ TSContDataSet(contp, write_data);
+
+ TSCacheWrite(contp, write_data->key);
return 0;
}
-/* TSTransformCreate() and TSCacheWrite() handler */
+/* TSTransformCreate() handler: Compute the SHA-256 digest of the content */
static int
transform_handler(TSCont contp, TSEvent event, void *edata)
{
switch (event) {
- case TS_EVENT_CACHE_OPEN_WRITE:
- return cache_open_write(contp, edata);
-
- case TS_EVENT_CACHE_OPEN_WRITE_FAILED:
- return cache_open_write_failed(contp, edata);
-
case TS_EVENT_IMMEDIATE:
case TS_EVENT_VCONN_WRITE_READY:
return vconn_write_ready(contp, edata);
[02/13] git commit: Update CHANGES for TS-2675
Posted by jp...@apache.org.
Update CHANGES for TS-2675
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ad6806ea
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ad6806ea
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ad6806ea
Branch: refs/heads/master
Commit: ad6806ea71218e760e64e658909bd202177e65de
Parents: a9a0b7c
Author: James Peach <jp...@apache.org>
Authored: Fri Mar 28 16:22:07 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
CHANGES | 3 +++
1 file changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ad6806ea/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 3523452..f3b6149 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with Apache Traffic Server 5.0.0
+ *) [TS-2675] metalink: Fix crash and plug memory leaks.
+ Author: Jack Bates <ja...@nottheoilrig.com>
+
*) [TS-2674] Remove debug printf() from traffic_top.
*) [TS-2652] atscppapi: Providing a cancel() in asyncproviders
[13/13] git commit: TS-2675: metalink: Improve comments and whitespace
Posted by jp...@apache.org.
TS-2675: metalink: Improve comments and whitespace
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ea2f6f38
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ea2f6f38
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ea2f6f38
Branch: refs/heads/master
Commit: ea2f6f3836221727c43be2257028a2c2ad5c2966
Parents: f88a726
Author: Jack Bates <ja...@nottheoilrig.com>
Authored: Thu Mar 13 14:48:28 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Fri Mar 28 16:23:54 2014 -0700
----------------------------------------------------------------------
doc/reference/plugins/metalink.en.rst | 6 +-
plugins/experimental/metalink/metalink.cc | 183 +++++++++++++++----------
2 files changed, 115 insertions(+), 74 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ea2f6f38/doc/reference/plugins/metalink.en.rst
----------------------------------------------------------------------
diff --git a/doc/reference/plugins/metalink.en.rst b/doc/reference/plugins/metalink.en.rst
index 8ba10dc..50e1b32 100644
--- a/doc/reference/plugins/metalink.en.rst
+++ b/doc/reference/plugins/metalink.en.rst
@@ -79,8 +79,8 @@ cache can change after responses are cached. It uses
plugin should also check if the URL is fresh or not.
The plugin implements the ``TS_HTTP_READ_RESPONSE_HDR_HOOK`` hook and
-`a null transform`_ to compute the SHA-256 digest for content as it's
-added to the cache. It uses SHA256_Init(), SHA256_Update(), and
+`a null transformation`_ to compute the SHA-256 digest for content as
+it's added to the cache. It uses SHA256_Init(), SHA256_Update(), and
SHA256_Final() from OpenSSL to compute the digest, then it uses
:c:func:`TSCacheWrite` to associate the digest with the request URL.
This adds a new cache object where the key is the digest and the
@@ -121,5 +121,5 @@ rel=duplicate` headers MUST be ignored:
.. _Metalink: http://en.wikipedia.org/wiki/Metalink
-.. _a null transform:
+.. _a null transformation:
/sdk/http-transformation-plugin/sample-null-transformation-plugin
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ea2f6f38/plugins/experimental/metalink/metalink.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc
index c7fafcc..3ad589d 100644
--- a/plugins/experimental/metalink/metalink.cc
+++ b/plugins/experimental/metalink/metalink.cc
@@ -1,34 +1,25 @@
/** @file
-
- Implement the Metalink protocol to "dedup" cache entries for
- equivalent content. This can for example improve the cache hit
- ratio for content with many different (unique) URLs.
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-
-/*
- This plugin was originally developed by Jack Bates during his Google
- Summer of Code 2012 project for Metalinker.
-*/
-
+ *
+ * Try not to download the same file twice. Improve cache efficiency
+ * and speed up downloads.
+ *
+ * @section license License
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License. */
#include <strings.h>
@@ -36,7 +27,7 @@
#include "ts/ts.h"
-/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transform.
+/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transformation.
* Compute the SHA-256 digest of the content, write it to the cache and store
* the request URL at that key.
*
@@ -47,7 +38,7 @@
*
* More details are on the [wiki page] in the Traffic Server wiki.
*
- * [wiki page] https://cwiki.apache.org/confluence/display/TS/Metalink */
+ * [wiki page] https://cwiki.apache.org/confluence/display/TS/Metalink */
/* TSCacheWrite() and TSVConnWrite() data: Write the digest to the cache and
* store the request URL at that key */
@@ -67,7 +58,7 @@ typedef struct {
typedef struct {
TSHttpTxn txnp;
- /* Null transform */
+ /* Null transformation */
TSIOBuffer output_bufp;
TSVIO output_viop;
@@ -105,7 +96,7 @@ typedef struct {
} SendData;
-/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transform */
+/* Implement TS_HTTP_READ_RESPONSE_HDR_HOOK to implement a null transformation */
/* Write the digest to the cache and store the request URL at that key */
@@ -179,7 +170,7 @@ cache_open_write(TSCont contp, void *edata)
/* Do nothing */
static int
-cache_open_write_failed(TSCont contp, void * /* edata ATS_UNUSED */)
+cache_open_write_failed(TSCont contp, void */* edata ATS_UNUSED */)
{
WriteData *data = (WriteData *) TSContDataGet(contp);
TSContDestroy(contp);
@@ -191,7 +182,7 @@ cache_open_write_failed(TSCont contp, void * /* edata ATS_UNUSED */)
}
static int
-write_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
+write_vconn_write_complete(TSCont contp, void */* edata ATS_UNUSED */)
{
WriteData *data = (WriteData *) TSContDataGet(contp);
TSContDestroy(contp);
@@ -233,26 +224,64 @@ write_handler(TSCont contp, TSEvent event, void *edata)
/* Copy content from the input buffer to the output buffer without modification
* and feed it through the message digest at the same time.
*
- * 1. Check if any more input is possible before doing anything else to avoid
- * failed asserts.
- * 2. Then deal with any input that's available now.
- * 3. Check if the input is complete after dealing with any available input
- * in case it was the last of it. If it is complete, do any bookkeeping
- * that downstream needs and finish computing the digest. Otherwise
- * either wait for more input or abort if no more input is possible.
+ * 1. Check if we are "closed" before doing anything else to avoid errors.
+ * 2. Then deal with any input that's available now.
+ * 3. Check if the input is complete after dealing with any available input
+ * in case it was the last of it. If it is complete, tell downstream,
+ * thank upstream, and finish computing the digest. Otherwise either
+ * wait for more input or abort if upstream is "closed".
*
- * Events are sent from downstream and don't communicate the state of the input
- * (TS_EVENT_VCONN_WRITE_READY, TS_EVENT_VCONN_WRITE_COMPLETE, and
- * TS_EVENT_IMMEDIATE?) Clean up the output buffer on
- * TS_EVENT_VCONN_WRITE_COMPLETE and not before.
+ * The handler is guaranteed to get called at least once, even if the response
+ * is 304 Not Modified, so we are guaranteed an opportunity to clean up e.g.
+ * data that we allocated when we called TSTransformCreate().
*
- * Gather the state of the input from TSVIONTodoGet() and TSVIOReaderGet().
- * TSVIOReaderGet() is NULL when no more input is possible and the input is
- * complete only when TSVIONTodoGet() is zero. Handle the end of the input
- * independently from the TS_EVENT_VCONN_WRITE_COMPLETE event from downstream. */
+ * TS_EVENT_VCONN_WRITE_READY and TS_EVENT_VCONN_WRITE_COMPLETE events are sent
+ * from downstream, e.g. by TransformTerminus::handle_event().
+ * TS_EVENT_IMMEDIATE events are sent by INKVConnInternal::do_io_write(),
+ * INKVConnInternal::do_io_close(), and INKVConnInternal::reenable() which are
+ * called from upstream, e.g. by TransformVConnection::do_io_write(),
+ * TransformVConnection::do_io_close(), and HttpTunnel::producer_handler().
+ *
+ * Clean up the output buffer on TS_EVENT_VCONN_WRITE_COMPLETE and not before.
+ * We are guaranteed a TS_EVENT_VCONN_WRITE_COMPLETE event *unless* we are
+ * "closed". In that case we instead get a TS_EVENT_IMMEDIATE event where
+ * TSVConnClosedGet() is one, so clean up the output buffer in that case as
+ * well. We'll only ever get one event where TSVConnClosedGet() is one and it
+ * will be our last, so there's no risk of a double free.
+ *
+ * The response headers get sent when TSVConnWrite() gets called and not
+ * before. (We could potentially edit them until then.)
+ *
+ * The events say nothing about the state of the input. Gather this instead
+ * from TSVConnClosedGet(), TSVIOReaderGet(), and TSVIONTodoGet() and handle
+ * the end of the input independently from the TS_EVENT_VCONN_WRITE_COMPLETE
+ * event from downstream.
+ *
+ * When TSVConnClosedGet() is one, *we* are "closed". Some state is already
+ * inconsistent and there's nothing to do except clean up. (This happens when
+ * the response is 304 Not Modified or when the client or origin disconnect
+ * before the message is complete.)
+ *
+ * When TSVIOReaderGet() is NULL, upstream is "closed". In that case it's
+ * clearly an error to call TSIOBufferReaderAvail(), it's also an error at that
+ * point to send any events upstream with TSContCall(). (This happens when the
+ * content length is zero or when we get the final chunk of a
+ * "Transfer-Encoding: chunked" response.)
+ *
+ * The input is complete only when TSVIONTodoGet() is zero. (Don't update the
+ * downstream nbytes otherwise!) Update the downstream nbytes when the input
+ * is complete in case the response is "Transfer-Encoding: chunked" (in which
+ * case nbytes is unknown until then). Downstream will (normally) send the
+ * TS_EVENT_VCONN_WRITE_COMPLETE event (and the final chunk if the response is
+ * "Transfer-Encoding: chunked") when ndone equals nbytes and not before.
+ *
+ * Send our own TS_EVENT_VCONN_WRITE_COMPLETE event upstream when the input is
+ * complete otherwise HttpSM::update_stats() won't get called and the
+ * transaction won't get logged. (If there are upstream transformations they
+ * won't get a chance to clean up otherwise!) */
static int
-vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
+vconn_write_ready(TSCont contp, void */* edata ATS_UNUSED */)
{
const char *value;
int64_t length;
@@ -261,6 +290,10 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TransformData *transform_data = (TransformData *) TSContDataGet(contp);
+ /* Check if we are "closed" before doing anything else to avoid errors. Some
+ * state is already inconsistent and there's nothing to do except clean up.
+ * (This happens if the response is 304 Not Modified or if the client or
+ * origin disconnect before the message is complete.) */
int closed = TSVConnClosedGet(contp);
if (closed) {
TSContDestroy(contp);
@@ -278,7 +311,7 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TSVIO input_viop = TSVConnWriteVIOGet(contp);
- /* Initialize data here because can't call TSVConnWrite() before
+ /* Initialize data here because we can't call TSVConnWrite() before
* TS_HTTP_RESPONSE_TRANSFORM_HOOK */
if (!transform_data->output_bufp) {
TSVConn output_connp = TSTransformOutputVConnGet(contp);
@@ -296,9 +329,10 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
SHA256_Init(&transform_data->c);
}
- /* Avoid failed assert "sdk_sanity_check_iocore_structure(readerp) ==
- * TS_SUCCESS" in TSIOBufferReaderAvail() if the client or origin disconnect
- * or the content length is zero */
+ /* Then deal with any input that's available now. Avoid failed assert
+ * "sdk_sanity_check_iocore_structure(readerp) == TS_SUCCESS" in
+ * TSIOBufferReaderAvail() if the content length is zero or when we get the
+ * final chunk of a "Transfer-Encoding: chunked" response. */
TSIOBufferReader readerp = TSVIOReaderGet(input_viop);
if (readerp) {
@@ -325,6 +359,8 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
}
}
+ /* Check if the input is complete after dealing with any available input in
+ * case it was the last of it */
int ntodo = TSVIONTodoGet(input_viop);
if (ntodo) {
TSVIOReenable(transform_data->output_viop);
@@ -338,6 +374,9 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
TSVIOReenable(transform_data->output_viop);
+ /* Avoid failed assert "c->alive == true" in TSContCall() if the content
+ * length is zero or when we get the final chunk of a
+ * "Transfer-Encoding: chunked" response */
if (readerp) {
TSContCall(TSVIOContGet(input_viop), TS_EVENT_VCONN_WRITE_COMPLETE, input_viop);
}
@@ -358,7 +397,7 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
return 0;
}
- /* Can't reuse the TSTransformCreate() continuation because don't know
+ /* Can't reuse the TSTransformCreate() continuation because we don't know
* whether to destroy it in cache_open_write()/cache_open_write_failed() or
* transform_vconn_write_complete() */
contp = TSContCreate(write_handler, NULL);
@@ -371,7 +410,7 @@ vconn_write_ready(TSCont contp, void * /* edata ATS_UNUSED */)
}
static int
-transform_vconn_write_complete(TSCont contp, void * /* edata ATS_UNUSED */)
+transform_vconn_write_complete(TSCont contp, void */* edata ATS_UNUSED */)
{
TransformData *data = (TransformData *) TSContDataGet(contp);
TSContDestroy(contp);
@@ -411,7 +450,7 @@ http_read_response_hdr(TSCont /* contp ATS_UNUSED */, void *edata)
TransformData *data = (TransformData *) TSmalloc(sizeof(TransformData));
data->txnp = (TSHttpTxn) edata;
- /* Can't initialize data here because can't call TSVConnWrite() before
+ /* Can't initialize data here because we can't call TSVConnWrite() before
* TS_HTTP_RESPONSE_TRANSFORM_HOOK */
data->output_bufp = NULL;
@@ -434,6 +473,7 @@ static int
cache_open_read(TSCont contp, void *edata)
{
SendData *data = (SendData *) TSContDataGet(contp);
+
TSVConn connp = (TSVConn) edata;
data->cache_bufp = TSIOBufferCreate();
@@ -447,7 +487,7 @@ cache_open_read(TSCont contp, void *edata)
/* Do nothing, just reenable the response */
static int
-cache_open_read_failed(TSCont contp, void * /* edata ATS_UNUSED */)
+cache_open_read_failed(TSCont contp, void */* edata ATS_UNUSED */)
{
SendData *data = (SendData *) TSContDataGet(contp);
TSContDestroy(contp);
@@ -467,7 +507,7 @@ cache_open_read_failed(TSCont contp, void * /* edata ATS_UNUSED */)
/* TSCacheRead() handler: Check if the URL stored at the digest is cached */
static int
-rewrite_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
+rewrite_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */)
{
SendData *data = (SendData *) TSContDataGet(contp);
TSContDestroy(contp);
@@ -506,13 +546,13 @@ rewrite_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
/* Read the URL stored at the digest */
static int
-vconn_read_ready(TSCont contp, void * /* edata ATS_UNUSED */)
+vconn_read_ready(TSCont contp, void */* edata ATS_UNUSED */)
{
SendData *data = (SendData *) TSContDataGet(contp);
-
TSContDestroy(contp);
TSIOBufferReader readerp = TSIOBufferReaderAlloc(data->cache_bufp);
+
TSIOBufferBlock blockp = TSIOBufferReaderStart(readerp);
/* No allocation, freed with data->cache_bufp? */
@@ -591,7 +631,7 @@ digest_handler(TSCont contp, TSEvent event, void *edata)
/* TSCacheRead() handler: Check if the "Location: ..." URL is already cached */
static int
-location_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
+location_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */)
{
const char *value;
int length;
@@ -602,6 +642,7 @@ location_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
TSContDestroy(contp);
switch (event) {
+
/* Yes: Do nothing, just reenable the response */
case TS_EVENT_CACHE_OPEN_READ:
break;
@@ -656,8 +697,8 @@ http_send_response_hdr(TSCont contp, void *edata)
int length;
SendData *data = (SendData *) TSmalloc(sizeof(SendData));
-
data->txnp = (TSHttpTxn) edata;
+
if (TSHttpTxnClientRespGet(data->txnp, &data->resp_bufp, &data->hdr_loc) != TS_SUCCESS) {
TSError("Couldn't retrieve client response header");
@@ -673,12 +714,12 @@ http_send_response_hdr(TSCont contp, void *edata)
/* Metalinks contain whole file hashes as described in Section 6, and MUST
* include SHA-256, as specified in [FIPS-180-3] */
- /* Assumption: Want to minimize cache read, so check first that:
+ /* Assumption: We want to minimize cache reads, so check first that
*
- * 1. response has a "Location: ..." header
- * 2. response has a "Digest: SHA-256=..." header
+ * 1. the response has a "Location: ..." header and
+ * 2. the response has a "Digest: SHA-256=..." header.
*
- * Then scan if the URL or digest already exist in the cache */
+ * Then scan if the URL or digest already exist in the cache. */
/* If the response has a "Location: ..." header */
data->location_loc = TSMimeHdrFieldFind(data->resp_bufp, data->hdr_loc, TS_MIME_FIELD_LOCATION, TS_MIME_LEN_LOCATION);
@@ -693,8 +734,8 @@ http_send_response_hdr(TSCont contp, void *edata)
TSUrlCreate(data->resp_bufp, &data->url_loc);
- /* If can't parse or lookup the "Location: ..." URL, should still check if
- * the response has a "Digest: SHA-256=..." header? No: Can't parse or
+ /* If we can't parse or lookup the "Location: ..." URL, should we still check
+ * if the response has a "Digest: SHA-256=..." header? No: Can't parse or
* lookup the URL in the "Location: ..." header is an error. */
/* No allocation, freed with data->resp_bufp? */