python实例32[简单的HttpServer]
?
通常地我們要在不同平臺(tái)間共享文件,samba,ftp,cifs,ntfs的設(shè)置都是有點(diǎn)復(fù)雜的, 我們可以使用python提供的httpserver來(lái)提供基于http方式跨平臺(tái)的文件共享。
?
一 命令行啟動(dòng)簡(jiǎn)單的httpserver
進(jìn)入到web或要共享文件的根目錄,然后執(zhí)行(貌似在python32中此module不存在了):
python -m SimpleHTTPServer 8000
然后你就可以使用http://你的IP地址:8000/來(lái)訪問web頁(yè)面或共享文件了。
?
二 ?代碼啟動(dòng)httpserver
simplehttpservertest.py??
import?sysimport?locale
import?http.server
import?socketserver
addr?=?len(sys.argv)?<?2?and?"localhost"?or?sys.argv[1]
port?=?len(sys.argv)?<?3?and?80?or?locale.atoi(sys.argv[2])
handler?=?http.server.SimpleHTTPRequestHandler
httpd?=?socketserver.TCPServer((addr,?port),?handler)
print?("HTTP?server?is?at:?http://%s:%d/"?%?(addr,?port))
httpd.serve_forever()
??
需要進(jìn)入web或要共享的目錄,執(zhí)行下列:?
simplehttpservertest.py localhost 8008?
?
三 第三方的python庫(kù)Droopy
且支持可以上傳文件到共享服務(wù)器
http://www.home.unix-ag.org/simon/woofhttp://stackp.online.fr/?p=28
?
四 支持上傳的httpserver
#!/usr/bin/env?python#coding=utf-8
#?modifyDate:?20120808?~?20120810
#?原作者為:bones7456,?http://li2z.cn/
#?修改者為:decli@qq.com
#?v1.2,changeLog:
#?+:?文件日期/時(shí)間/顏色顯示、多線程支持、主頁(yè)跳轉(zhuǎn)
#?-:?解決不同瀏覽器下上傳文件名亂碼問題:僅IE,其它瀏覽器暫時(shí)沒處理。
#?-:?一些路徑顯示的bug,主要是?cgi.escape()?轉(zhuǎn)義問題
#??:?notepad++?下直接編譯的server路徑問題
?
"""
????簡(jiǎn)介:這是一個(gè)?python?寫的輕量級(jí)的文件共享服務(wù)器(基于內(nèi)置的SimpleHTTPServer模塊),
????支持文件上傳下載,只要你安裝了python(建議版本2.6~2.7,不支持3.x),
????然后去到想要共享的目錄下,執(zhí)行:
????????python?SimpleHTTPServerWithUpload.py?1234???????
????其中1234為你指定的端口號(hào),如不寫,默認(rèn)為?8080
????然后訪問?http://localhost:1234?即可,localhost?或者?1234?請(qǐng)酌情替換。
"""
?
"""Simple?HTTP?Server?With?Upload.
?
This?module?builds?on?BaseHTTPServer?by?implementing?the?standard?GET
and?HEAD?requests?in?a?fairly?straightforward?manner.
?
"""
?
?
__version__?=?"0.1"
__all__?=?["SimpleHTTPRequestHandler"]
__author__?=?"bones7456"
__home_page__?=?""
?
import?os,?sys,?platform
import?posixpath
import?BaseHTTPServer
from?SocketServer?import?ThreadingMixIn
import?threading
import?urllib
import?cgi
import?shutil
import?mimetypes
import?re
import?time
?
?
try:
????from?cStringIO?import?StringIO
except?ImportError:
????from?StringIO?import?StringIO
?????
?
print?""
print?'----------------------------------------------------------------------->>?'
try:
???port?=?int(sys.argv[1])
except?Exception,?e:
???print?'-------->>?Warning:?Port?is?not?given,?will?use?deafult?port:?8080?'
???print?'-------->>?if?you?want?to?use?other?port,?please?execute:?'
???print?'-------->>?python?SimpleHTTPServerWithUpload.py?port?'
???print?"-------->>?port?is?a?integer?and?it's?range:?1024?<?port?<?65535?"
???port?=?8080
????
if?not?1024?<?port?<?65535:??port?=?8080
serveraddr?=?('',?port)
print?'-------->>?Now,?listening?at?port?'?+?str(port)?+?'?...'
print?'-------->>?You?can?visit?the?URL:???http://localhost:'?+?str(port)
print?'----------------------------------------------------------------------->>?'
print?""
?????
?
def?sizeof_fmt(num):
????for?x?in?['bytes','KB','MB','GB']:
????????if?num?<?1024.0:
????????????return?"%3.1f%s"?%?(num,?x)
????????num?/=?1024.0
????return?"%3.1f%s"?%?(num,?'TB')
?
def?modification_date(filename):
????#?t?=?os.path.getmtime(filename)
????#?return?datetime.datetime.fromtimestamp(t)
????return?time.strftime("%Y-%m-%d?%H:%M:%S",time.localtime(os.path.getmtime(filename)))
?
class?SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
?
????"""Simple?HTTP?request?handler?with?GET/HEAD/POST?commands.
?
????This?serves?files?from?the?current?directory?and?any?of?its
????subdirectories.??The?MIME?type?for?files?is?determined?by
????calling?the?.guess_type()?method.?And?can?reveive?file?uploaded
????by?client.
?
????The?GET/HEAD/POST?requests?are?identical?except?that?the?HEAD
????request?omits?the?actual?contents?of?the?file.
?
????"""
?
????server_version?=?"SimpleHTTPWithUpload/"?+?__version__
?
????def?do_GET(self):
????????"""Serve?a?GET?request."""
????????#?print?"....................",?threading.currentThread().getName()
????????f?=?self.send_head()
????????if?f:
????????????self.copyfile(f,?self.wfile)
????????????f.close()
?
????def?do_HEAD(self):
????????"""Serve?a?HEAD?request."""
????????f?=?self.send_head()
????????if?f:
????????????f.close()
?
????def?do_POST(self):
????????"""Serve?a?POST?request."""
????????r,?info?=?self.deal_post_data()
????????print?r,?info,?"by:?",?self.client_address
????????f?=?StringIO()
????????f.write('<!DOCTYPE?html?PUBLIC?"-//W3C//DTD?HTML?3.2?Final//EN">')
????????f.write("<html>\n<title>Upload?Result?Page</title>\n")
????????f.write("<body>\n<h2>Upload?Result?Page</h2>\n")
????????f.write("<hr>\n")
????????if?r:
????????????f.write("<strong>Success:</strong>")
????????else:
????????????f.write("<strong>Failed:</strong>")
????????f.write(info)
????????f.write("<br><a?href=\"%s\">back</a>"?%?self.headers['referer'])
????????f.write("<hr><small>Powered?By:?bones7456,?check?new?version?at?")
????????f.write("<a?href=\"http://li2z.cn/?s=SimpleHTTPServerWithUpload\">")
????????f.write("here</a>.</small></body>\n</html>\n")
????????length?=?f.tell()
????????f.seek(0)
????????self.send_response(200)
????????self.send_header("Content-type",?"text/html")
????????self.send_header("Content-Length",?str(length))
????????self.end_headers()
????????if?f:
????????????self.copyfile(f,?self.wfile)
????????????f.close()
?????????
????def?deal_post_data(self):
????????boundary?=?self.headers.plisttext.split("=")[1]
????????remainbytes?=?int(self.headers['content-length'])
????????line?=?self.rfile.readline()
????????remainbytes?-=?len(line)
????????if?not?boundary?in?line:
????????????return?(False,?"Content?NOT?begin?with?boundary")
????????line?=?self.rfile.readline()
????????remainbytes?-=?len(line)
????????fn?=?re.findall(r'Content-Disposition.*name="file";?filename="(.*)"',?line)
????????if?not?fn:
????????????return?(False,?"Can't?find?out?file?name...")
????????path?=?self.translate_path(self.path)
????????osType?=?platform.system()
????????try:
????????????if?osType?==?"Linux":
????????????????fn?=?os.path.join(path,?fn[0].decode('gbk').encode('utf-8'))
????????????else:
????????????????fn?=?os.path.join(path,?fn[0])
????????except?Exception,?e:
????????????return?(False,?"文件名請(qǐng)不要用中文,或者使用IE上傳中文名的文件。")
????????while?os.path.exists(fn):
????????????fn?+=?"_"
????????line?=?self.rfile.readline()
????????remainbytes?-=?len(line)
????????line?=?self.rfile.readline()
????????remainbytes?-=?len(line)
????????try:
????????????out?=?open(fn,?'wb')
????????except?IOError:
????????????return?(False,?"Can't?create?file?to?write,?do?you?have?permission?to?write?")
?????????????????
????????preline?=?self.rfile.readline()
????????remainbytes?-=?len(preline)
????????while?remainbytes?>?0:
????????????line?=?self.rfile.readline()
????????????remainbytes?-=?len(line)
????????????if?boundary?in?line:
????????????????preline?=?preline[0:-1]
????????????????if?preline.endswith('\r'):
????????????????????preline?=?preline[0:-1]
????????????????out.write(preline)
????????????????out.close()
????????????????return?(True,?"File?'%s'?upload?success!"?%?fn)
????????????else:
????????????????out.write(preline)
????????????????preline?=?line
????????return?(False,?"Unexpect?Ends?of?data.")
?
????def?send_head(self):
????????"""Common?code?for?GET?and?HEAD?commands.
?
????????This?sends?the?response?code?and?MIME?headers.
?
????????Return?value?is?either?a?file?object?(which?has?to?be?copied
????????to?the?outputfile?by?the?caller?unless?the?command?was?HEAD,
????????and?must?be?closed?by?the?caller?under?all?circumstances),?or
????????None,?in?which?case?the?caller?has?nothing?further?to?do.
?
????????"""
????????path?=?self.translate_path(self.path)
????????f?=?None
????????if?os.path.isdir(path):
????????????if?not?self.path.endswith('/'):
????????????????#?redirect?browser?-?doing?basically?what?apache?does
????????????????self.send_response(301)
????????????????self.send_header("Location",?self.path?+?"/")
????????????????self.end_headers()
????????????????return?None
????????????for?index?in?"index.html",?"index.htm":
????????????????index?=?os.path.join(path,?index)
????????????????if?os.path.exists(index):
????????????????????path?=?index
????????????????????break
????????????else:
????????????????return?self.list_directory(path)
????????ctype?=?self.guess_type(path)
????????try:
????????????#?Always?read?in?binary?mode.?Opening?files?in?text?mode?may?cause
????????????#?newline?translations,?making?the?actual?size?of?the?content
????????????#?transmitted?*less*?than?the?content-length!
????????????f?=?open(path,?'rb')
????????except?IOError:
????????????self.send_error(404,?"File?not?found")
????????????return?None
????????self.send_response(200)
????????self.send_header("Content-type",?ctype)
????????fs?=?os.fstat(f.fileno())
????????self.send_header("Content-Length",?str(fs[6]))
????????self.send_header("Last-Modified",?self.date_time_string(fs.st_mtime))
????????self.end_headers()
????????return?f
?
????def?list_directory(self,?path):
????????"""Helper?to?produce?a?directory?listing?(absent?index.html).
?
????????Return?value?is?either?a?file?object,?or?None?(indicating?an
????????error).??In?either?case,?the?headers?are?sent,?making?the
????????interface?the?same?as?for?send_head().
?
????????"""
????????try:
????????????list?=?os.listdir(path)
????????except?os.error:
????????????self.send_error(404,?"No?permission?to?list?directory")
????????????return?None
????????list.sort(key=lambda?a:?a.lower())
????????f?=?StringIO()
????????displaypath?=?cgi.escape(urllib.unquote(self.path))
????????f.write('<!DOCTYPE?html?PUBLIC?"-//W3C//DTD?HTML?3.2?Final//EN">')
????????f.write("<html>\n<title>Directory?listing?for?%s</title>\n"?%?displaypath)
????????f.write("<body>\n<h2>Directory?listing?for?%s</h2>\n"?%?displaypath)
????????f.write("<hr>\n")
????????f.write("<form?ENCTYPE=\"multipart/form-data\"?method=\"post\">")
????????f.write("<input?name=\"file\"?type=\"file\"/>")
????????f.write("<input?type=\"submit\"?value=\"upload\"/>")
????????f.write("              ")
????????f.write("<input?type=\"button\"?value=\"HomePage\"?onClick=\"location='/'\">")
????????f.write("</form>\n")
????????f.write("<hr>\n<ul>\n")
????????for?name?in?list:
????????????fullname?=?os.path.join(path,?name)
????????????colorName?=?displayname?=?linkname?=?name
????????????#?Append?/?for?directories?or?@?for?symbolic?links
????????????if?os.path.isdir(fullname):
????????????????colorName?=?'<span?style="background-color:?#CEFFCE;">'?+?name?+?'/</span>'
????????????????displayname?=?name
????????????????linkname?=?name?+?"/"
????????????if?os.path.islink(fullname):
????????????????colorName?=?'<span?style="background-color:?#FFBFFF;">'?+?name?+?'@</span>'
????????????????displayname?=?name
????????????????#?Note:?a?link?to?a?directory?displays?with?@?and?links?with?/
????????????filename?=?os.getcwd()?+?'/'?+?displaypath?+?displayname
????????????f.write('<table><tr><td?width="60%%"><a?href="%s">%s</a></td><td?width="20%%">%s</td><td?width="20%%">%s</td></tr>\n'
????????????????????%?(urllib.quote(linkname),?colorName,
????????????????????????sizeof_fmt(os.path.getsize(filename)),?modification_date(filename)))
????????f.write("</table>\n<hr>\n</body>\n</html>\n")
????????length?=?f.tell()
????????f.seek(0)
????????self.send_response(200)
????????self.send_header("Content-type",?"text/html")
????????self.send_header("Content-Length",?str(length))
????????self.end_headers()
????????return?f
?
????def?translate_path(self,?path):
????????"""Translate?a?/-separated?PATH?to?the?local?filename?syntax.
?
????????Components?that?mean?special?things?to?the?local?file?system
????????(e.g.?drive?or?directory?names)?are?ignored.??(XXX?They?should
????????probably?be?diagnosed.)
?
????????"""
????????#?abandon?query?parameters
????????path?=?path.split('?',1)[0]
????????path?=?path.split('#',1)[0]
????????path?=?posixpath.normpath(urllib.unquote(path))
????????words?=?path.split('/')
????????words?=?filter(None,?words)
????????path?=?os.getcwd()
????????for?word?in?words:
????????????drive,?word?=?os.path.splitdrive(word)
????????????head,?word?=?os.path.split(word)
????????????if?word?in?(os.curdir,?os.pardir):?continue
????????????path?=?os.path.join(path,?word)
????????return?path
?
????def?copyfile(self,?source,?outputfile):
????????"""Copy?all?data?between?two?file?objects.
?
????????The?SOURCE?argument?is?a?file?object?open?for?reading
????????(or?anything?with?a?read()?method)?and?the?DESTINATION
????????argument?is?a?file?object?open?for?writing?(or
????????anything?with?a?write()?method).
?
????????The?only?reason?for?overriding?this?would?be?to?change
????????the?block?size?or?perhaps?to?replace?newlines?by?CRLF
????????--?note?however?that?this?the?default?server?uses?this
????????to?copy?binary?data?as?well.
?
????????"""
????????shutil.copyfileobj(source,?outputfile)
?
????def?guess_type(self,?path):
????????"""Guess?the?type?of?a?file.
?
????????Argument?is?a?PATH?(a?filename).
?
????????Return?value?is?a?string?of?the?form?type/subtype,
????????usable?for?a?MIME?Content-type?header.
?
????????The?default?implementation?looks?the?file's?extension
????????up?in?the?table?self.extensions_map,?using?application/octet-stream
????????as?a?default;?however?it?would?be?permissible?(if
????????slow)?to?look?inside?the?data?to?make?a?better?guess.
?
????????"""
?
????????base,?ext?=?posixpath.splitext(path)
????????if?ext?in?self.extensions_map:
????????????return?self.extensions_map[ext]
????????ext?=?ext.lower()
????????if?ext?in?self.extensions_map:
????????????return?self.extensions_map[ext]
????????else:
????????????return?self.extensions_map['']
?
????if?not?mimetypes.inited:
????????mimetypes.init()?#?try?to?read?system?mime.types
????extensions_map?=?mimetypes.types_map.copy()
????extensions_map.update({
????????'':?'application/octet-stream',?#?Default
????????'.py':?'text/plain',
????????'.c':?'text/plain',
????????'.h':?'text/plain',
????????})
?
class?ThreadingServer(ThreadingMixIn,?BaseHTTPServer.HTTPServer):
????pass
?????
def?test(HandlerClass?=?SimpleHTTPRequestHandler,
???????ServerClass?=?BaseHTTPServer.HTTPServer):
????BaseHTTPServer.test(HandlerClass,?ServerClass)
?
if?__name__?==?'__main__':
????#?test()
?????
????#單線程
????#?srvr?=?BaseHTTPServer.HTTPServer(serveraddr,?SimpleHTTPRequestHandler)
?????
????#多線程
????srvr?=?ThreadingServer(serveraddr,?SimpleHTTPRequestHandler)
? ? ? ?srvr.serve_forever()??
? ? ?
?
五 本地的httpserver
在本地機(jī)器沒有聯(lián)網(wǎng)的時(shí)候,需要使用如下:來(lái)自http://coolshell.cn/articles/1480.html
?如果你只想讓這個(gè)HTTP服務(wù)器服務(wù)于本地環(huán)境,那么,你需要定制一下你的Python的程序,下面是一個(gè)示例:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import sys import BaseHTTPServer from SimpleHTTPServer import SimpleHTTPRequestHandler HandlerClass = SimpleHTTPRequestHandler ServerClass? = BaseHTTPServer.HTTPServer Protocol???? = "HTTP/1.0" if sys.argv[1:]: ????port = int(sys.argv[1]) else: ????port = 8000 server_address = ('127.0.0.1', port) HandlerClass.protocol_version = Protocol httpd = ServerClass(server_address, HandlerClass) sa = httpd.socket.getsockname() print "Serving HTTP on", sa[0], "port", sa[1], "..." httpd.serve_forever() |
?
來(lái)自:http://my.oschina.net/leejun2005/blog/71444?
?
?
完!?
?
?
總結(jié)
以上是生活随笔為你收集整理的python实例32[简单的HttpServer]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Perl的第二纪
- 下一篇: C语言解释器的实现--语法解析(五)