Added modification time tracking to the MirrorManager cache.
[quix0rs-apt-p2p.git] / apt_dht / HTTPServer.py
1 import os.path, time
2
3 from twisted.python import log
4 from twisted.internet import defer
5 from twisted.web2 import server, http, resource, channel
6 from twisted.web2 import static, http_headers, responsecode
7
8 class FileDownloader(static.File):
9     
10     def __init__(self, path, manager, defaultType="text/plain", ignoredExts=(), processors=None, indexNames=None):
11         self.manager = manager
12         super(FileDownloader, self).__init__(path, defaultType, ignoredExts, processors, indexNames)
13         
14     def renderHTTP(self, req):
15         log.msg('Got request for %s from %s' % (req.uri, req.remoteAddr))
16         resp = super(FileDownloader, self).renderHTTP(req)
17         if isinstance(resp, defer.Deferred):
18             resp.addCallback(self._renderHTTP_done, req)
19         else:
20             resp = self._renderHTTP_done(resp, req)
21         return resp
22         
23     def _renderHTTP_done(self, resp, req):
24         log.msg('Initial response to %s: %r' % (req.uri, resp))
25         
26         if self.manager:
27             path = 'http:/' + req.uri
28             if resp.code >= 200 and resp.code < 400:
29                 return self.manager.check_freshness(path, resp.headers.getHeader('Last-Modified'), resp)
30             
31             log.msg('Not found, trying other methods for %s' % req.uri)
32             return self.manager.get_resp(path)
33         
34         return resp
35
36     def createSimilarFile(self, path):
37         return self.__class__(path, self.manager, self.defaultType, self.ignoredExts,
38                               self.processors, self.indexNames[:])
39         
40         
41 class TopLevel(resource.Resource):
42     addSlash = True
43     
44     def __init__(self, directory, manager):
45         self.directory = directory
46         self.manager = manager
47         self.subdirs = []
48
49     def addDirectory(self, directory):
50         path = "~" + str(len(self.subdirs))
51         self.subdirs.append(directory)
52         return path
53     
54     def removeDirectory(self, directory):
55         loc = self.subdirs.index(directory)
56         self.subdirs[loc] = ''
57         
58     def render(self, ctx):
59         return http.Response(
60             200,
61             {'content-type': http_headers.MimeType('text', 'html')},
62             """<html><body>
63             <h2>Statistics</h2>
64             <p>TODO: eventually some stats will be shown here.</body></html>""")
65
66     def locateChild(self, request, segments):
67         name = segments[0]
68         if len(name) > 1 and name[0] == '~':
69             try:
70                 loc = int(name[1:])
71             except:
72                 log.msg('Not found: %s from %s' % (request.uri, request.remoteAddr))
73                 return None, ()
74             
75             if loc >= 0 and loc < len(self.subdirs) and self.subdirs[loc]:
76                 log.msg('Sharing %s with %s' % (request.uri, request.remoteAddr))
77                 return static.File(self.subdirs[loc]), segments[1:]
78             else:
79                 log.msg('Not found: %s from %s' % (request.uri, request.remoteAddr))
80                 return None, ()
81         
82         if request.remoteAddr.host != "127.0.0.1":
83             log.msg('Blocked illegal access to %s from %s' % (request.uri, request.remoteAddr))
84             return None, ()
85             
86         if len(name) > 1:
87             return FileDownloader(self.directory, self.manager), segments[0:]
88         else:
89             return self, ()
90         
91 if __name__ == '__builtin__':
92     # Running from twistd -y
93     t = TopLevel('/home', None)
94     t.addDirectory('/tmp')
95     t.addDirectory('/var/log')
96     site = server.Site(t)
97     
98     # Standard twisted application Boilerplate
99     from twisted.application import service, strports
100     application = service.Application("demoserver")
101     s = strports.service('tcp:18080', channel.HTTPFactory(site))
102     s.setServiceParent(application)