用 Python 搭建最简单的 http 服务器

适用范围

  • 本文内容对 Python 3.6.9 适用

静态网站

静态网站可以浏览静态网页,也可以用于文件下载。

http.server

python3 -m http.server 5678

Twisted

pip install Twisted
  • 帮助
twistd web --help
  • Web Server 示例
# 不同版本命令有所不同
# 以下命令适用于 Twisted 19.x.x
twistd web --listen=tcp:5678 --path=.

WSGI

示例

from wsgiref.simple_server import make_server

def hello_world_app(environ, start_response):
    status = '200 OK'  # HTTP Status
    headers = [('Content-type', 'text/plain; charset=utf-8')]  # HTTP Headers
    start_response(status, headers)
    msg = 'Hello %s\n' % environ["REMOTE_ADDR"]
    return [msg.encode('utf8')]

with make_server('', 5678, hello_world_app) as httpd:
    print("Serving on port 5678...")
    httpd.serve_forever()

运行

  • 命令行前台运行
python3 t.py
  • 后台运行
nohup python3 -u t.py > t.log 2>&1 &
# 日志滚动,只保留最新的 1 M
nohup python3 -u t.py 2>&1 | rotatelogs -n 1 t.log 1M &

测试

$ curl 127.0.0.1:5678
Hello 127.0.0.1

http 请求头回显

示例

#encoding: utf-8
#author: qbit
#date: 2020-01-22
#summary: 回显 http 头,可用于匿名度检测
#sys.version: '3.6.7 (v3.6.7:6ec5cf24b7, Oct 20 2018) [MSC v.1900 64 bit (AMD64)]'

import argparse
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class EchoHTTPHandler(BaseHTTPRequestHandler):    
    def text_to_html(self, req_head):
        r""" 将请求头包装成 html,便于返回给 http 客户端 """
        html = 'Echo HTTP Header' 
        html += '
' html += '%s - %s - %s

' html = html % (self.client_address, self.request_version, self.path) for line in req_head.split('\n'): line = line.strip() if line.startswith('Via:') or line.startswith('X-Forwarded-For:'): line = '%s
' % line else: line = '%s
' % line html += line html += '
' return html def do_GET(self): r""" 响应 get 请求,打印 http 头,并返回给 http 客户端 """ print('%s - %s - %s' % (self.client_address, self.request_version, self.path)) print(type(self.client_address)) print('### request headers ###') req_head = str(self.headers) print('req_head: %s' % req_head) for line in req_head.split('\n'): line = line.strip() if line.startswith('Via:') or line.startswith('X-Forwarded-For:'): line = '%s%s%s' % (fg('red'), line, attr('reset')) print(line) self.send_response(200) self.end_headers() ''' 可选返回 text,html ''' text = '%s - %s - %s\n---\n%s' % (self.client_address, self.request_version, self.path, req_head) text = text.encode('utf8') html = self.text_to_html(req_head).encode('utf8') self.wfile.write(text)
    def do_POST(self):
        r""" 响应 post 请求,返回 json """
        # POST 有 Content-Length,GET 无 Content-Length
        #content_len = int(self.headers.getheader('content-length'))
        content_len = int(self.headers['Content-Length'])   
        post_body = self.rfile.read(content_len)
        data = json.loads(post_body)

        parsed_path = urlparse(self.path)
        self.send_response(200)
        self.end_headers()
        self.wfile.write(json.dumps({
            'method': self.command,
            'path': self.path,
            'real_path': parsed_path.query,
            'query': parsed_path.query,
            'request_version': self.request_version,
            'protocol_version': self.protocol_version,
            'body': data
        }).encode())
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Echo HTTP server.')
    parser.add_argument('-a', '--address', help='default: 0.0.0.0')
    parser.add_argument('-p', '--port', help='default: 5678', type=int)
    args = parser.parse_args()
    ip = args.address or '0.0.0.0'
    port = args.port or 8080
    print('Listening %s:%d' % (ip, port))
    server = HTTPServer((ip, port), EchoHTTPHandler)
    server.serve_forever()

运行

  • 命令行前台运行
python3 t.py
  • 后台运行
nohup python3 -u t.py > t.log 2>&1 &
# 日志滚动,只保留最新的 1 M
nohup python3 -u t.py 2>&1 | rotatelogs -n 1 t.log 1M &

测试

('127.0.0.1', 58561) - HTTP/1.1 - /
---
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,\*/\*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
本文出自 qbit snap

你可能感兴趣的:(python,http,server,twisted)