commit 8620869e03e3f0eff1008d5a4671cd78ead04795 Author: Sebastian Lohff Date: Mon Mar 12 15:41:55 2012 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3400509 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +MANIFEST +dist/ diff --git a/README b/README new file mode 100644 index 0000000..2518d27 --- /dev/null +++ b/README @@ -0,0 +1 @@ +This is a STUB. diff --git a/servefile b/servefile new file mode 100755 index 0000000..4f3b6dc --- /dev/null +++ b/servefile @@ -0,0 +1,129 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# written by seba (seba-geek.de) :) +# v0.3 + +import BaseHTTPServer +import sys +import os +import urllib +from stat import ST_SIZE +import SocketServer +import socket +import commands + +class FileHandler(BaseHTTPServer.BaseHTTPRequestHandler): + fileName = "Undefined" + filePath = "/dev/null" + fileLength = 0 + blockSize = 1024 * 1024 + + def do_GET(self): + if urllib.unquote(self.path) != "/" + self.fileName: + self.send_response(302) + self.send_header('Location', '/' + self.fileName) + self.end_headers() + return + + myfile = open(self.filePath, 'rb') + + # find out if this is a continuing download + fromto = None + cont = self.headers.get("Range") + if cont != None: + cont = cont.split("=") + if len(cont) > 1 and cont[0] == 'bytes': + fromto = cont[1].split('-') + if len(fromto) > 1: + if fromto[1] == '': + fromto[1] = self.fileLength-1 + fromto[0] = int(fromto[0]) + fromto[1] = int(fromto[1]) + if fromto[0] >= self.fileLength or fromto[0] < 0 or fromto[1] >= self.fileLength or fromto[1]-fromto[0] < 0: + # oops, already done! + self.send_response(416) + self.send_header('Content-Range', 'bytes */%s' % self.fileLength) + self.end_headers() + return + # now we can wind the file *brrrrrr* + myfile.seek(fromto[0]) + + if fromto != None: + self.send_response(216) + self.send_header('Content-Range', 'bytes %s-%s/%s' % (fromto[0], fromto[1], self.fileLength)) + self.send_header('Content-Length', fromto[1]-fromto[0]+1) + else: + self.send_response(200) + self.send_header('Content-Length', self.fileLength) + self.send_header('Content-Disposition', 'attachment; filename="%s"' % self.fileName) + self.send_header('Content-type', 'application/octet-stream') + self.send_header('Content-Transfer-Encoding', ' binary') + self.end_headers() + block = self.getChunk(myfile, fromto) + while block: + try: + self.wfile.write(block) + except socket.error, e: + print "%s ABORTED transmission (Reason %s: %s)" % (self.client_address[0], e[0], e[1]) + return + block = self.getChunk(myfile, fromto) + myfile.close() + print "%s finished downloading" % (self.client_address[0]) + return + + def getChunk(self, myfile, fromto): + if fromto != None and myfile.tell()+self.blockSize >= fromto[1]: + readsize = fromto[1]-myfile.tell()+1 + else: + readsize = self.blockSize + return myfile.read(readsize) + +class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): + pass + +def main(): + if len(sys.argv) < 2 or len(sys.argv) > 3 or sys.argv[1] in ('-h', '--help'): + print "Usage: [path to file] " + return + + port = 8080 + if len(sys.argv) == 3: + try: + port = int(sys.argv[2]) + except ValueError: + print "Error: Port should be an int!" + return + + try: + testit = open(sys.argv[1], 'r') + testit.close() + FileHandler.filePath = sys.argv[1] + FileHandler.fileName = os.path.basename(sys.argv[1]) + FileHandler.fileLength = os.stat(sys.argv[1])[ST_SIZE] + except IOError: + print "Error: Could not open file!" + return + + server = ThreadedHTTPServer(('', port), FileHandler) + print "Serving:", sys.argv[1] + print "Port: ", port + print "Ready..." + server.address_family = 10 + # print urls with local network adresses + print "Some addresses this file will be available under:" + ips = commands.getoutput(r"/sbin/ifconfig |grep 'inet6\?'|grep -v 127.0.0.1|grep -v ' fe80'|grep -v ::1|sed -n 's/.*inet6\?[a-zA-Z: -]\+\([0-9a-fA-F.:]*\).*/\1/p'") + for ip in ips.split("\n"): + if ip.find(":") >= 0: + ip = "[%s]" % ip # must be v6... + continue # FIXME: When BaseHTTP supports ipv6 properly, delete this line + print "http://%s:%d" % (ip, port) + + try: + server.serve_forever() + except KeyboardInterrupt: + server.socket.close() + print "Good bye.." + +if __name__ == '__main__': + main() diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..3f3df85 --- /dev/null +++ b/setup.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +from distutils.core import setup + +setup( + name='servefile', + description='Script to serve files via a small HTTP server', + long_description='Script to serve files via a small HTTP server. The server redirects all http requests to the file, so only IP and port must be given to another user to access the file.', + platforms='posix', + version='0.3', + license='GPLv3 or later', + url='http://seba-geek.de/stuff/servefile/', + author='Sebastian Lohff', + author_email='seba@someserver.de', + scripts=['servefile'], +) +