X-Git-Url: https://git.mxchange.org/?p=quix0rs-apt-p2p.git;a=blobdiff_plain;f=apt_dht%2FHTTPServer.py;h=82a9babb2ca551f95d71056616661f38b9c4e186;hp=b81282cf2c1865f1884115486e19c1efceca33ea;hb=08292f21e1a718a814bb2c17a00f78c51d0f96ac;hpb=222c430337a9fe573aba00223d6322ff7e0b3fb2 diff --git a/apt_dht/HTTPServer.py b/apt_dht/HTTPServer.py index b81282c..82a9bab 100644 --- a/apt_dht/HTTPServer.py +++ b/apt_dht/HTTPServer.py @@ -1,4 +1,6 @@ +"""Serve local requests from apt and remote requests from peers.""" + from urllib import unquote_plus from binascii import b2a_hex @@ -11,6 +13,15 @@ from policies import ThrottlingFactory from apt_dht_Khashmir.bencode import bencode class FileDownloader(static.File): + """Modified to make it suitable for apt requests. + + Tries to find requests in the cache. Found files are first checked for + freshness before being sent. Requests for unfound and stale files are + forwarded to the main program for downloading. + + @type manager: L{apt_dht.AptDHT} + @ivar manager: the main program to query + """ def __init__(self, path, manager, defaultType="text/plain", ignoredExts=(), processors=None, indexNames=None): self.manager = manager @@ -43,6 +54,13 @@ class FileDownloader(static.File): self.processors, self.indexNames[:]) class FileUploaderStream(stream.FileStream): + """Modified to make it suitable for streaming to peers. + + Streams the file is small chunks to make it easier to throttle the + streaming to peers. + + @ivar CHUNK_SIZE: the size of chunks of data to send at a time + """ CHUNK_SIZE = 4*1024 @@ -54,6 +72,8 @@ class FileUploaderStream(stream.FileStream): if length == 0: self.f = None return None + + # Remove the SendFileBuffer and mmap use, just use string reads and writes readSize = min(length, self.CHUNK_SIZE) @@ -69,12 +89,18 @@ class FileUploaderStream(stream.FileStream): class FileUploader(static.File): + """Modified to make it suitable for peer requests. + + Uses the modified L{FileUploaderStream} to stream the file for throttling, + and doesn't do any listing of directory contents. + """ def render(self, req): if not self.fp.exists(): return responsecode.NOT_FOUND if self.fp.isdir(): + # Don't try to render a directory listing return responsecode.NOT_FOUND try: @@ -89,6 +115,7 @@ class FileUploader(static.File): raise response = http.Response() + # Use the modified FileStream response.stream = FileUploaderStream(f, 0, self.fp.getsize()) for (header, value) in ( @@ -101,15 +128,38 @@ class FileUploader(static.File): return response class TopLevel(resource.Resource): + """The HTTP server for all requests, both from peers and apt. + + @type directory: L{twisted.python.filepath.FilePath} + @ivar directory: the directory to check for cached files + @type db: L{db.DB} + @ivar db: the database to use for looking up files and hashes + @type manager: L{apt_dht.AptDHT} + @ivar manager: the main program object to send requests to + @type factory: L{twisted.web2.channel.HTTPFactory} or L{policies.ThrottlingFactory} + @ivar factory: the factory to use to server HTTP requests + + """ + addSlash = True def __init__(self, directory, db, manager): + """Initialize the instance. + + @type directory: L{twisted.python.filepath.FilePath} + @param directory: the directory to check for cached files + @type db: L{db.DB} + @param db: the database to use for looking up files and hashes + @type manager: L{apt_dht.AptDHT} + @param manager: the main program object to send requests to + """ self.directory = directory self.db = db self.manager = manager self.factory = None def getHTTPFactory(self): + """Initialize and get the factory for this HTTP server.""" if self.factory is None: self.factory = channel.HTTPFactory(server.Site(self), **{'maxPipeline': 10, @@ -118,6 +168,7 @@ class TopLevel(resource.Resource): return self.factory def render(self, ctx): + """Render a web page with descriptive statistics.""" return http.Response( 200, {'content-type': http_headers.MimeType('text', 'html')}, @@ -126,31 +177,41 @@ class TopLevel(resource.Resource):
TODO: eventually some stats will be shown here.