我正在调试一个由我构建的微控制器,它逐行编写原始的HTTP请求。 我正在使用 Flask 作为后端,并希望以此格式查看整个请求:
GET / HTTP/1.1
Content-length: 123
User-agent: blah
...
我知道Flask基于WSGI。有没有办法让它与Flask一起工作?
是的,Flask是一个WSGI应用程序,因此将您的应用程序包装在额外的层中记录请求非常容易:
import pprint
class LoggingMiddleware(object):
def __init__(self, app):
self._app = app
def __call__(self, env, resp):
errorlog = env['wsgi.errors']
pprint.pprint(('REQUEST', env), stream=errorlog)
def log_response(status, headers, *args):
pprint.pprint(('RESPONSE', status, headers), stream=errorlog)
return resp(status, headers, *args)
return self._app(env, log_response)
这定义了一个中间件来包装您的Flask应用程序。其优点是它完全独立于Flask,让您可以对输入输出进行无过滤的洞察。
如何应用中间件取决于您使用的确切WSGI服务器;请参阅您的WSGI服务器文档。
当使用内置服务器运行Flask(app.run()
)时,请执行以下操作:
if __name__ == '__main__':
app.wsgi_app = LoggingMiddleware(app.wsgi_app)
app.run()
小小的app.wsgi_app
包装操作是将LoggingMiddleware
放置在Flask WSGI应用程序周围。
输出结果会被发送到wsgi.error
流中;具体将其发送到哪里取决于您的WSGI服务器:mod_wsgi
将其放置在Apache错误日志中,而捆绑的Flask服务器则将其打印到stderr
中。
使用Flask,您可以访问请求对象,其中包含所有HTTP细节:
from flask import request
@app.route('/')
def index():
print(request.headers)
HTTP详细信息
打印。使用请求的其他属性也无法帮助(例如数据,表单,值等)。要完整地打印HTTP请求,建议使用WSGI包装,这是@martinpieters答案中提到的方法。 - snowbound假设您想要完整的细节信息,
@app.route('/')
def index():
print request.__dict__
#this prints all variables in `dict` format including `headers`
headers
根本不是一个键; 有包含不同信息的environ
键,其中包括标题,但肯定不是完整的原始请求。 - maxpprint
后,当我执行pprint.pformat(request.__dict__, depth=5))
时,我看到environ
作为第一个键被打印出来。 - watsonic为什么不呢?
from flask import Flask, request
app = Flask(__name__)
@app.before_request
def log_request():
app.logger.debug("Request Headers %s", request.headers)
return None
# The remaining application code.
我已经使用了标题,但您可以使用相同的方法来打印任何请求属性。文档在这里:http://flask.pocoo.org/docs/0.12/api/#flask.Request。
另外,您需要设置FLASK_DEBUG = 1才能使Flask.logger.debug起作用,这很好,因为您可以在生产中禁用它。
此致敬意,
你可能想要类似这样的东西
print(request.headers)
print(request.cookies)
print(request.data)
print(request.args)
print(request.form)
print(request.endpoint)
print(request.method)
print(request.remote_addr)
这不使用flask,但是设置一个套接字回声服务器相当简单。
import socket
host = ''
port = 8888
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
client, address = s.accept()
data = client.recv(size)
if data:
client.send(data)
client.close()
https://docs.python.org/3/library/pprint.html#pprint.pformat
from pprint import pformat
import requests
log.debug(pformat(request.headers))
env['wsgi.input']
是流,您可以将数据复制到tempfile.SpooledTemporaryFile()
对象,对该文件进行操作,然后返回到开头并将env['input.stream']
设置为指向它。 - Martijn Pieters