适用范围
静态网站
静态网站可以浏览静态网页,也可以用于文件下载。
http.server
python3 -m http.server 5678
Twisted
pip install Twisted
twistd web --help
# 不同版本命令有所不同
# 以下命令适用于 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