dumpheaders_http_threading_server.py脚本的Python 3.5迁移版

该脚本的主要用处是作为http服务器使用,并且可以输出请求/响应的http头部。

import http.server
import time
import socketserver
import os
import threading
import socket

PORT = 8000

class MyThreadingHTTPServer(socketserver.ThreadingTCPServer):

    allow_reuse_address = 1    # Seems to make sense in testing environment

    def server_bind(self):
        """Override server_bind to store the server name."""
        socketserver.TCPServer.server_bind(self)
        host, port = self.socket.getsockname()[:2]
        self.server_name = socket.getfqdn(host)
        self.server_port = port

#Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
class MyThreadingHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
    def dumpRequestHeaders(self):
        print( '[%s]raw_requestline=%s self.path=%s headers=\n%s\n' % (threading.current_thread(),self.raw_requestline, self.path, self.headers) )
    
    def do_GET(self):
        #if self.path.endswith(".htm") or self.path.endswith(".html") or self.path.endswith("/"):
        self.dumpRequestHeaders() #Add to see WebKit version;
        #
        if self.path.endswith(".mp4"):
            http.server.SimpleHTTPRequestHandler.do_GET(self)
            return
        
        if self.path.startswith("/ajax/"):
            self.send_response(200)
            self.send_header("Content-Type", "text/html") #maybe use json?
            self.send_header("Cache-control", "no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, no-transform")
            self.end_headers()
            self.wfile.write(b"Ajax response data by python script...")
            #self.wfile.close()
            return
        
        """Serve a GET request."""
        f = self.send_head()
        if f:
            #Get file size:
            f.seek(0, os.SEEK_END)
            filesize = f.tell()
            f.seek(0, os.SEEK_SET)

            #self.copyfile(f, self.wfile)
            #print "do_GET: sending body for %s, filesize=%d" % (self.path, filesize)
            bytes_sent = 0
            if( self.path.endswith(".html") or self.path=="/" ):
                print( "Make a manual broken response for html" )
                READ_BUFFER_SIZE = 32;
                buf = f.read(READ_BUFFER_SIZE)
                while buf:
                    #time.sleep(1)
                    self.wfile.write(buf)
                    bytes_sent = bytes_sent + len(buf)
                    print( "%d bytes sent, %d left to send" % (bytes_sent, filesize - bytes_sent) )
                    if bytes_sent>80:
                        pass
                        #raise Exception("io error!")
                    buf = f.read(READ_BUFFER_SIZE)
            else:
                self.copyfile(f, self.wfile)
            f.close()
            #'''
            #self.copyfile(f, self.wfile)

    def is_image_request(self, path):
        return path.lower().endswith( (".png",".jpg",".gif") )

    def send_head(self):
        """
            overwrite send_head to set Last-Modified & Expires to disable browser cache;
        """
        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)
        response_headers = {}
        response_headers["Content-Type"]=ctype
        fs = os.fstat(f.fileno())
        response_headers["Content-Length"]=str(fs[6])
        response_headers["Last-Modified"]=self.date_time_string(time.time())
        response_headers["Expires"]=self.date_time_string(time.time()+5)
        response_headers["Cache-control"]="no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, no-transform"
            #simple_offline_cache needs to override this;
        response_headers["Pragma"]="no-cache"
        response_headers["Connection"]="close" #HTTP/1.1 assume connection reuse
        
        response_headers_list=[]
        for k, v in response_headers.items():
            response_headers_list.append('%s: %s' % (k, v)) #multiple print's is not thread-safe;
            self.send_header(k, v)
        print( '[%s][%s]response headers=\n%s\n' % (threading.current_thread(),self.path, '\n'.join(response_headers_list)) )
        
        self.end_headers()
        return f


s = MyThreadingHTTPServer(("", PORT), MyThreadingHTTPRequestHandler)
sa = s.socket.getsockname()
print("Serving Dump-Request-Headers Test Server on", sa[0], "port", sa[1], "...")
s.serve_forever()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值