![仅转储 POST 请求的通用 HTTP 服务器?](https://linux22.com/image/27903/%E4%BB%85%E8%BD%AC%E5%82%A8%20POST%20%E8%AF%B7%E6%B1%82%E7%9A%84%E9%80%9A%E7%94%A8%20HTTP%20%E6%9C%8D%E5%8A%A1%E5%99%A8%EF%BC%9F.png)
我正在寻找一个命令行工具,它可以监听给定的部分,很高兴地排除每个 HTTP POST 请求并转储它。
我想将它用于测试目的,即测试发出 HTTP POST 请求的客户端。
这意味着我正在搜索对应的内容curl -F
(我可以使用它来将测试 HTTP POST 发送到 HTTP 服务器)。
也许类似socat TCP4-LISTEN:80,fork,bind=127.0.0.1 ...
- 但 socat 还不够,因为它不支持 HTTP。
答案1
我自己也在寻找这个遇到 Node.js http-echo-server:
npm install http-echo-server -g
PORT=8081 http-echo-server
它接受所有请求并将完整请求(包括标头)回显到命令行。
答案2
简单的核心命令行工具(如nc
)socat
似乎无法处理正在发生的特定 HTTP 内容(块、传输编码等)。因此,与与真实的 Web 服务器通信相比,这可能会产生意外的行为。因此,我的第一个想法是分享我所知道的设置小型网络服务器并使其执行您想要的操作的最快方法:转储所有输出。
我能想到的最短的使用蟒蛇龙卷风:
#!/usr/bin/env python
import tornado.ioloop
import tornado.web
import pprint
class MyDumpHandler(tornado.web.RequestHandler):
def post(self):
pprint.pprint(self.request)
pprint.pprint(self.request.body)
if __name__ == "__main__":
tornado.web.Application([(r"/.*", MyDumpHandler),]).listen(8080)
tornado.ioloop.IOLoop.instance().start()
替换该pprint
行以仅输出您需要的特定字段,例如self.request.body
或self.request.headers
。在上面的示例中,它在所有接口上侦听端口 8080。
(我非常面向Python,抱歉)
如果您不喜欢它的输出方式,请运行它并尝试tcpdump
如下:
tcpdump -i lo 'tcp[32:4] = 0x484f535420'
查看所有 HTTP-POST 请求的真实原始转储。或者,只需运行 Wireshark。
答案3
使用nc
(发音为“网猫”)。
你告诉它监听哪个端口
nc -kl 8888
然后在单独的终端窗口中向其发送请求
curl localhost:8888 -d hello=world
它会打印您发送给它的数据,在本例中是 HTTP 请求:
POST / HTTP/1.1
Host: localhost:8888
User-Agent: curl/7.84.0
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
hello=world
该-k
选项意味着它将监听请求并无限期地打印它们。如果没有该选项(即nc -l 8888
),它将在第一个请求后退出。
答案4
Python 标准库附带了电池,即它甚至包括一个 HTTP 服务器包,可用于编写一个简单的 HTTP 请求转储器:
#!/usr/bin/env python3
import argparse
import http.server
import json
import sys
class Dumper(http.server.BaseHTTPRequestHandler):
def do_GET(self, method='GET'):
print(f'\n{method} {self.path}\n{self.headers}')
self.send_response(200)
self.end_headers()
def do_DELETE(self):
return self.do_GET('DELETE')
def do_POST(self, method='POST'):
n = int(self.headers.get('content-length', 0))
body = self.rfile.read(n)
print(f'\n{method} {self.path}\n{self.headers}{body}\n')
if self.headers.get('content-type') == 'application/json':
d = json.loads(body)
print(json.dumps(d, indent=4, sort_keys=True))
print()
self.send_response(200)
self.end_headers()
def do_PUT(self):
return self.do_POST('PUT')
def log_message(self, format, *args):
pass
一些样板:
def main():
p = argparse.ArgumentParser(description='Dump HTTP requests to stdout')
p.add_argument('address', help='bind address')
p.add_argument('port', type=int, help='bind port')
xs = p.parse_args();
s = http.server.HTTPServer((xs.address, xs.port), Dumper)
s.serve_forever()
if __name__ == '__main__':
sys.exit(main())
也可以看看:我的要点