No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

servefile 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # written by seba (seba-geek.de) :)
  4. # v0.3
  5. import argparse
  6. import BaseHTTPServer
  7. import commands
  8. import urllib
  9. import os
  10. import SocketServer
  11. import socket
  12. from stat import ST_SIZE
  13. import sys
  14. class FileHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  15. fileName = "Undefined"
  16. filePath = "/dev/null"
  17. fileLength = 0
  18. blockSize = 1024 * 1024
  19. def do_GET(self):
  20. if urllib.unquote(self.path) != "/" + self.fileName:
  21. self.send_response(302)
  22. self.send_header('Location', '/' + self.fileName)
  23. self.end_headers()
  24. return
  25. myfile = open(self.filePath, 'rb')
  26. # find out if this is a continuing download
  27. fromto = None
  28. if "Range" in self.headers:
  29. cont = self.headers.get("Range").split("=")
  30. if len(cont) > 1 and cont[0] == 'bytes':
  31. fromto = cont[1].split('-')
  32. if len(fromto) > 1:
  33. if fromto[1] == '':
  34. fromto[1] = self.fileLength-1
  35. fromto[0] = int(fromto[0])
  36. fromto[1] = int(fromto[1])
  37. if fromto[0] >= self.fileLength or fromto[0] < 0 or fromto[1] >= self.fileLength or fromto[1]-fromto[0] < 0:
  38. # oops, already done!
  39. self.send_response(416)
  40. self.send_header('Content-Range', 'bytes */%s' % self.fileLength)
  41. self.end_headers()
  42. return
  43. # now we can wind the file *brrrrrr*
  44. myfile.seek(fromto[0])
  45. if fromto != None:
  46. self.send_response(216)
  47. self.send_header('Content-Range', 'bytes %s-%s/%s' % (fromto[0], fromto[1], self.fileLength))
  48. self.send_header('Content-Length', fromto[1]-fromto[0]+1)
  49. else:
  50. self.send_response(200)
  51. self.send_header('Content-Length', self.fileLength)
  52. self.send_header('Content-Disposition', 'attachment; filename="%s"' % self.fileName)
  53. self.send_header('Content-type', 'application/octet-stream')
  54. self.send_header('Content-Transfer-Encoding', ' binary')
  55. self.end_headers()
  56. block = self.getChunk(myfile, fromto)
  57. while block:
  58. try:
  59. self.wfile.write(block)
  60. except socket.error, e:
  61. print "%s ABORTED transmission (Reason %s: %s)" % (self.client_address[0], e[0], e[1])
  62. return
  63. block = self.getChunk(myfile, fromto)
  64. myfile.close()
  65. print "%s finished downloading" % (self.client_address[0])
  66. return
  67. def getChunk(self, myfile, fromto):
  68. if fromto and myfile.tell()+self.blockSize >= fromto[1]:
  69. readsize = fromto[1]-myfile.tell()+1
  70. else:
  71. readsize = self.blockSize
  72. return myfile.read(readsize)
  73. class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
  74. pass
  75. def main():
  76. parser = argparse.ArgumentParser()
  77. parser.add_argument('filename', metavar='file/directory', type=str)
  78. parser.add_argument('-p', '--port', type=int, default=8080, \
  79. help='port to listen on')
  80. args = parser.parse_args()
  81. try:
  82. testit = open(args.filename, 'r')
  83. testit.close()
  84. FileHandler.filePath = sys.argv[1]
  85. FileHandler.fileName = os.path.basename(args.filename)
  86. FileHandler.fileLength = os.stat(args.filename)[ST_SIZE]
  87. except IOError:
  88. print "Error: Could not open file!"
  89. sys.exit(3)
  90. server = ThreadedHTTPServer(('', args.port), FileHandler)
  91. print "Serving \"%s\" under port %d" % (args.filename, args.port)
  92. # print urls with local network adresses
  93. print "\nSome addresses this file will be available under:"
  94. ips = commands.getoutput(r"/bin/ip addr|" + \
  95. "sed -n -e 's/.*inet6\? \([0-9.a-fA-F:]\+\)\/.*/\\1/ p'|" + \
  96. "grep -v '^fe80\|^127.0.0.1\|^::1'")
  97. for ip in ips.split("\n"):
  98. if ip.find(":") >= 0:
  99. # ipv6
  100. ip = "[%s]" % ip
  101. # FIXME: When BaseHTTP supports ipv6 properly, delete this line
  102. continue
  103. print "http://%s:%d/" % (ip, args.port)
  104. try:
  105. server.serve_forever()
  106. except KeyboardInterrupt:
  107. server.socket.close()
  108. print "Good bye.."
  109. if __name__ == '__main__':
  110. main()