Repository: trafficserver Updated Branches: refs/heads/master 3bd11e9b9 -> fd7365db2
Metalink: Cosmetic Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/74a9a6b3 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/74a9a6b3 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/74a9a6b3 Branch: refs/heads/master Commit: 74a9a6b37739c41af17edbe308e41549394e5100 Parents: 3bd11e9 Author: Jack Bates <[email protected]> Authored: Wed Jul 16 13:00:29 2014 -0700 Committer: Jack Bates <[email protected]> Committed: Tue Jul 22 08:36:10 2014 -0700 ---------------------------------------------------------------------- doc/reference/plugins/metalink.en.rst | 26 +++++------ plugins/experimental/metalink/README | 16 +++---- plugins/experimental/metalink/metalink.cc | 46 +++++++++++--------- .../experimental/metalink/test/chunkedEncoding | 3 +- .../metalink/test/chunkedEncodingDisconnect | 3 +- .../experimental/metalink/test/contentLength | 3 +- .../metalink/test/contentLengthDisconnect | 3 +- .../test/finalChunkedEncodingDisconnect | 3 +- plugins/experimental/metalink/test/headers | 39 +++++++++-------- plugins/experimental/metalink/test/http09 | 3 +- plugins/experimental/metalink/test/location | 3 +- plugins/experimental/metalink/test/longer | 3 +- plugins/experimental/metalink/test/notModified | 3 +- .../test/shortChunkedEncodingDisconnect | 3 +- .../metalink/test/shortContentLengthDisconnect | 3 +- plugins/experimental/metalink/test/zero | 3 +- 16 files changed, 90 insertions(+), 73 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/doc/reference/plugins/metalink.en.rst ---------------------------------------------------------------------- diff --git a/doc/reference/plugins/metalink.en.rst b/doc/reference/plugins/metalink.en.rst index ea71a87..20a53fd 100644 --- a/doc/reference/plugins/metalink.en.rst +++ b/doc/reference/plugins/metalink.en.rst @@ -17,10 +17,10 @@ .. _metalink-plugin: -Metalink plugin +Metalink Plugin =============== -The `metalink` plugin implements the `Metalink`_ download description +The `Metalink` plugin implements the Metalink_ download description format in order to try not to download the same file twice. This improves cache efficiency and speeds up users' downloads. @@ -61,7 +61,7 @@ won't download the file again. Installation ------------ -The `metalink` plugin is a global plugin. Enable it by adding +The `Metalink` plugin is a :term:`global plugin`. Enable it by adding ``metalink.so`` to your :file:`plugin.config` file. There are no options. @@ -69,8 +69,8 @@ options. Implementation Status --------------------- -The plugin implements the ``TS_HTTP_SEND_RESPONSE_HDR_HOOK`` hook to -check and potentially rewrite the :mailheader:`Location` and +The plugin implements the :c:data:`TS_HTTP_SEND_RESPONSE_HDR_HOOK` +hook to 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 @@ -78,13 +78,13 @@ 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 -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 -object is the request URL. +The plugin implements the :c:data:`TS_HTTP_READ_RESPONSE_HDR_HOOK` +hook 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 object is the request URL. To check if the cache already contains content that matches a digest, the plugin must call :c:func:`TSCacheRead` with the digest as the key, @@ -107,7 +107,7 @@ headers. The :mailheader:`Digest: SHA-256=...` header is also more efficient than :mailheader:`Link: <...>; rel=duplicate` headers because it -involves a constant number of cache lookups. RFC 6249 requires a +involves a constant number of cache lookups. :rfc:`6249` requires a :mailheader:`Digest: SHA-256=...` header or :mailheader:`Link: <...>; rel=duplicate` headers MUST be ignored: http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/README ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/README b/plugins/experimental/metalink/README index 46fdd7c..ecd8d00 100644 --- a/plugins/experimental/metalink/README +++ b/plugins/experimental/metalink/README @@ -1,5 +1,5 @@ - Metalink + MMeettaalliinnkk Try not to download the same file twice. Improve cache efficiency and speed up downloads. @@ -12,7 +12,7 @@ download redirectors or content distribution networks. -1. Who Cares? +11.. WWhhoo CCaarreess?? More important than saving a little bandwidth, this saves users from frustration. @@ -34,7 +34,7 @@ cached is valuable. -2. What it Does +22.. WWhhaatt iitt DDooeess When it sees a response with a "Location: ..." header and a "Digest: SHA-256=..." header, it checks if the URL in the Location @@ -48,14 +48,14 @@ and won't download the file again. -3. How to Use it +33.. HHooww ttoo UUssee iitt Just build the plugin and add it to your plugin.config file. The code is distributed along with recent versions of Traffic - Server, in the "plugins/experimental/metalink" directory. To build - it, pass the "--enable-experimental-plugins" option to the - configure script when you build Traffic Server: + Server, in the plugins/experimental/metalink directory. To build + it, pass the --enable-experimental-plugins option to the configure + script when you build Traffic Server: <pre>$ ./configure --enable-experimental-plugins</pre> @@ -63,7 +63,7 @@ plugin.config file to start using the plugin. -4. Read More +44.. RReeaadd MMoorree More details are on the [wiki page] in the Traffic Server wiki. http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/metalink.cc ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/metalink.cc b/plugins/experimental/metalink/metalink.cc index 207fdf1..6461121 100644 --- a/plugins/experimental/metalink/metalink.cc +++ b/plugins/experimental/metalink/metalink.cc @@ -229,7 +229,9 @@ write_handler(TSCont contp, TSEvent event, void *edata) * * 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 @@ -293,23 +295,24 @@ write_handler(TSCont contp, TSEvent event, void *edata) * 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: + * Summary of the cases each event can fall into: * * 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 + * â + * â 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 + * â 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 @@ -319,13 +322,13 @@ write_handler(TSCont contp, TSEvent event, void *edata) * 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 + * â + * â 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 @@ -579,6 +582,8 @@ rewrite_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */) SendData *data = (SendData *) TSContDataGet(contp); TSContDestroy(contp); + TSCacheKeyDestroy(data->key); + switch (event) { /* Yes: Rewrite the Location header and reenable the response */ @@ -599,8 +604,6 @@ rewrite_handler(TSCont contp, TSEvent event, void */* edata ATS_UNUSED */) TSIOBufferDestroy(data->cache_bufp); - TSCacheKeyDestroy(data->key); - TSHandleMLocRelease(data->resp_bufp, data->hdr_loc, data->location_loc); TSHandleMLocRelease(data->resp_bufp, TS_NULL_MLOC, data->hdr_loc); @@ -786,6 +789,7 @@ http_send_response_hdr(TSCont contp, void *edata) /* 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 header. * * Then scan if the URL or digest already exist in the cache. */ http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/chunkedEncoding ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/chunkedEncoding b/plugins/experimental/metalink/test/chunkedEncoding index 66c8d9b..9d97901 100755 --- a/plugins/experimental/metalink/test/chunkedEncoding +++ b/plugins/experimental/metalink/test/chunkedEncoding @@ -68,7 +68,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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': http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/chunkedEncodingDisconnect ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/chunkedEncodingDisconnect b/plugins/experimental/metalink/test/chunkedEncodingDisconnect index e39549f..8a6309d 100755 --- a/plugins/experimental/metalink/test/chunkedEncodingDisconnect +++ b/plugins/experimental/metalink/test/chunkedEncodingDisconnect @@ -69,7 +69,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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': http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/contentLength ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/contentLength b/plugins/experimental/metalink/test/contentLength index f53efe7..4d1a904 100755 --- a/plugins/experimental/metalink/test/contentLength +++ b/plugins/experimental/metalink/test/contentLength @@ -64,7 +64,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(ctx): + ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname())) def handleEndHeaders(ctx): try: http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/contentLengthDisconnect ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/contentLengthDisconnect b/plugins/experimental/metalink/test/contentLengthDisconnect index 17d927f..ee12a45 100755 --- a/plugins/experimental/metalink/test/contentLengthDisconnect +++ b/plugins/experimental/metalink/test/contentLengthDisconnect @@ -70,7 +70,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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': http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect b/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect index 6185e9a..6c60f4e 100755 --- a/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect +++ b/plugins/experimental/metalink/test/finalChunkedEncodingDisconnect @@ -81,7 +81,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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': http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/headers ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/headers b/plugins/experimental/metalink/test/headers index 717c0c3..9e3e193 100755 --- a/plugins/experimental/metalink/test/headers +++ b/plugins/experimental/metalink/test/headers @@ -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 headers -# The response isn't held up until the server starts sending content''' +# The response isn't held up until the origin starts sending content''' from twisted.internet import error, protocol, reactor, tcp from twisted.web import http @@ -39,10 +39,10 @@ class factory(http.HTTPFactory): ctx.write('') -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): @@ -63,7 +63,8 @@ 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())) + def connectionMade(ctx): + ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname())) def handleStatus(ctx, version, status, message): print 'ok 1 - Got the response status' http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/http09 ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/http09 b/plugins/experimental/metalink/test/http09 index b53d200..5667c13 100755 --- a/plugins/experimental/metalink/test/http09 +++ b/plugins/experimental/metalink/test/http09 @@ -78,7 +78,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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/74a9a6b3/plugins/experimental/metalink/test/location ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/location b/plugins/experimental/metalink/test/location index 97eb32a..b1f4710 100755 --- a/plugins/experimental/metalink/test/location +++ b/plugins/experimental/metalink/test/location @@ -76,7 +76,8 @@ class factory(protocol.ClientFactory): # 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 connectionMade(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: http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/longer ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/longer b/plugins/experimental/metalink/test/longer index d298451..e087e1c 100755 --- a/plugins/experimental/metalink/test/longer +++ b/plugins/experimental/metalink/test/longer @@ -68,7 +68,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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': http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/notModified ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/notModified b/plugins/experimental/metalink/test/notModified index 90c3a87..2719458 100755 --- a/plugins/experimental/metalink/test/notModified +++ b/plugins/experimental/metalink/test/notModified @@ -64,7 +64,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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/74a9a6b3/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect b/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect index 14e5a6f..fa2ae59 100755 --- a/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect +++ b/plugins/experimental/metalink/test/shortChunkedEncodingDisconnect @@ -68,7 +68,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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': http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/shortContentLengthDisconnect ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/shortContentLengthDisconnect b/plugins/experimental/metalink/test/shortContentLengthDisconnect index b2a74fa..4ff28cc 100755 --- a/plugins/experimental/metalink/test/shortContentLengthDisconnect +++ b/plugins/experimental/metalink/test/shortContentLengthDisconnect @@ -69,7 +69,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(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': http://git-wip-us.apache.org/repos/asf/trafficserver/blob/74a9a6b3/plugins/experimental/metalink/test/zero ---------------------------------------------------------------------- diff --git a/plugins/experimental/metalink/test/zero b/plugins/experimental/metalink/test/zero index 3605a2b..4be1e5c 100755 --- a/plugins/experimental/metalink/test/zero +++ b/plugins/experimental/metalink/test/zero @@ -64,7 +64,8 @@ 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(*origin.socket.getsockname())) + def connectionMade(ctx): + ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname())) def handleEndHeaders(ctx): try:
