From 444f294beae5f6d2dc25762ff02a45200d38a679 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Sun, 6 May 2012 03:14:33 +0200 Subject: [PATCH] Added Tahoe-LAFS gateway script --- gateway.py | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 gateway.py diff --git a/gateway.py b/gateway.py new file mode 100644 index 0000000..246d099 --- /dev/null +++ b/gateway.py @@ -0,0 +1,118 @@ +from twisted.internet import protocol, reactor +from twisted.web import static, server, proxy +from twisted.web.resource import Resource +import base64, urllib +from os import fork, setsid, umask, dup2 +from sys import stdin, stdout, stderr +from os import getpid +from urllib import quote as urlquote + +pid_file = "/home/tahoe/gateway/gateway.pid" + +modHeaders = { + 'Cache-Control': 'max-age=31536000', + 'Server': 'Cryto-Tahoe-Gateway 1.1', + 'Expires': 'Fri, 12 Dec 2012 05:00:00 GMT' +} + + +outfile = open(pid_file, 'w') +outfile.write('%i' % getpid()) +outfile.close() +if fork(): exit(0) +umask(0) +setsid() +if fork(): exit(0) + +stdout.flush() +stderr.flush() +si = file('/dev/null', 'r') +so = file('/dev/null', 'a+') +se = file('/dev/null', 'a+', 0) +dup2(si.fileno(), stdin.fileno()) +dup2(so.fileno(), stdout.fileno()) +dup2(se.fileno(), stderr.fileno()) + +error_index = ("""\ + + + + Cryto-Tahoe-Gateway: Index + + +

This gateway does not provide an index page.

+ Please use a direct URL to download a file hosted on this storage grid.

+ Alternatively, learn more about the Cryto Coding Collective. +



+
Cryto-Tahoe-Gateway v1.1
+ + """) + +error_404 = ("""\ + + + + Cryto-Tahoe-Gateway: 404 + + +

The specified resource was not found.

+ The file may have expired, or the hyperlink you followed may have been broken.

+ Learn more about the Cryto Coding Collective. +



+
Cryto-Tahoe-Gateway v1.1
+ + """) + + +class ProxyClient(proxy.ProxyClient): + """A proxy class that injects headers to the response.""" + def handleEndHeaders(self): + for key, value in modHeaders.iteritems(): + self.father.responseHeaders.setRawHeaders(key, [value]) + + +class ProxyClientFactory(proxy.ProxyClientFactory): + protocol = ProxyClient + + +class ReverseProxyResource(proxy.ReverseProxyResource): + proxyClientFactoryClass = ProxyClientFactory + + def getChild(self, path, request): + return ReverseProxyResource( + self.host, self.port, self.path + '/' + urlquote(path, safe="")) + + + +class GatewayResource(Resource): + isLeaf = False + allowedMethods = ("GET") + + def getChild(self, name, request): + if name == "download": + try: + uri = request.path + uriParts = uri.split('/') + uriIdentifier = base64.urlsafe_b64decode(uriParts[2]) + fileName = uriParts[3] + localUri = "/file/" + urllib.quote(uriIdentifier) + "/@@named=/" + urllib.quote(fileName) + return ReverseProxyResource('localhost', 3456, localUri) + except: + return self + else: + return self + + def render_GET(self, request): + path = request.path + if path == "/": + return error_index + else: + return error_404 + +resource = GatewayResource() + +site = server.Site(resource) +reactor.listenTCP(3719, site) +reactor.run() + +