Added 2 (commented) failed attempts to throttle the web server.
[quix0rs-apt-p2p.git] / apt_dht / HTTPServer.py
1
2 from urllib import unquote_plus
3
4 from twisted.python import log
5 from twisted.internet import defer
6 #from twisted.protocols import htb
7 #from twisted.protocols.policies import ThrottlingFactory
8 from twisted.web2 import server, http, resource, channel
9 from twisted.web2 import static, http_headers, responsecode
10
11 class FileDownloader(static.File):
12     
13     def __init__(self, path, manager, defaultType="text/plain", ignoredExts=(), processors=None, indexNames=None):
14         self.manager = manager
15         super(FileDownloader, self).__init__(path, defaultType, ignoredExts, processors, indexNames)
16         
17     def renderHTTP(self, req):
18         log.msg('Got request for %s from %s' % (req.uri, req.remoteAddr))
19         resp = super(FileDownloader, self).renderHTTP(req)
20         if isinstance(resp, defer.Deferred):
21             resp.addCallback(self._renderHTTP_done, req)
22         else:
23             resp = self._renderHTTP_done(resp, req)
24         return resp
25         
26     def _renderHTTP_done(self, resp, req):
27         log.msg('Initial response to %s: %r' % (req.uri, resp))
28         
29         if self.manager:
30             path = 'http:/' + req.uri
31             if resp.code >= 200 and resp.code < 400:
32                 return self.manager.check_freshness(req, path, resp.headers.getHeader('Last-Modified'), resp)
33             
34             log.msg('Not found, trying other methods for %s' % req.uri)
35             return self.manager.get_resp(req, path)
36         
37         return resp
38
39     def createSimilarFile(self, path):
40         return self.__class__(path, self.manager, self.defaultType, self.ignoredExts,
41                               self.processors, self.indexNames[:])
42         
43         
44 class TopLevel(resource.Resource):
45     addSlash = True
46     
47     def __init__(self, directory, db, manager):
48         self.directory = directory
49         self.db = db
50         self.manager = manager
51         self.factory = None
52
53     def getHTTPFactory(self):
54         if self.factory is None:
55             self.factory = channel.HTTPFactory(server.Site(self),
56                                                **{'maxPipeline': 10, 
57                                                   'betweenRequestsTimeOut': 60})
58 #            serverFilter = htb.HierarchicalBucketFilter()
59 #            serverBucket = htb.Bucket()
60 #
61 #            # Cap total server traffic at 20 kB/s
62 #            serverBucket.maxburst = 20000
63 #            serverBucket.rate = 20000
64 #
65 #            serverFilter.buckets[None] = serverBucket
66 #
67 #            self.factory.protocol = htb.ShapedProtocolFactory(self.factory.protocol, serverFilter)
68 #            self.factory = ThrottlingFactory(self.factory, writeLimit = 300*1024)
69         return self.factory
70
71     def render(self, ctx):
72         return http.Response(
73             200,
74             {'content-type': http_headers.MimeType('text', 'html')},
75             """<html><body>
76             <h2>Statistics</h2>
77             <p>TODO: eventually some stats will be shown here.</body></html>""")
78
79     def locateChild(self, request, segments):
80         log.msg('Got HTTP request for %s from %s' % (request.uri, request.remoteAddr))
81         name = segments[0]
82         if name == '~':
83             if len(segments) != 2:
84                 log.msg('Got a malformed request from %s' % request.remoteAddr)
85                 return None, ()
86             hash = unquote_plus(segments[1])
87             files = self.db.lookupHash(hash)
88             if files:
89                 log.msg('Sharing %s with %s' % (files[0]['path'].path, request.remoteAddr))
90                 return static.File(files[0]['path'].path), ()
91             else:
92                 log.msg('Hash could not be found in database: %s' % hash)
93         
94         if request.remoteAddr.host != "127.0.0.1":
95             log.msg('Blocked illegal access to %s from %s' % (request.uri, request.remoteAddr))
96             return None, ()
97             
98         if len(name) > 1:
99             return FileDownloader(self.directory.path, self.manager), segments[0:]
100         else:
101             return self, ()
102         
103         log.msg('Got a malformed request for "%s" from %s' % (request.uri, request.remoteAddr))
104         return None, ()
105
106 if __name__ == '__builtin__':
107     # Running from twistd -y
108     t = TopLevel('/home', None)
109     t.setDirectories({'~1': '/tmp', '~2': '/var/log'})
110     factory = t.getHTTPFactory()
111     
112     # Standard twisted application Boilerplate
113     from twisted.application import service, strports
114     application = service.Application("demoserver")
115     s = strports.service('tcp:18080', factory)
116     s.setServiceParent(application)