HTTPS代理,支持分块编码请求

pAk*_*Y88 5 apache proxy squid

我正在开发一个简单的HTTPS代理(用Python编写),它接收POST/GET请求/响应,应用一些转换,最后将结果转发给收件人.我需要以"流"方式处理分块编码的请求/响应,这意味着只要接收到一个块,代理就会转换它并将其转发给接收者.

在决定支持分块编码请求之前,我一直在使用mitmproxy http://mitmproxy.org/并且它工作得很好.不幸的是,我注意到在让我处理响应/请求之前它一直等到收到整个主体.

如何实现支持分块编码请求/响应的代理?你有没有人做过这样的事情?

谢谢

编辑:更多信息我的使用案例

我需要处理POST请求和GET响应.

POST请求中,我收到一个JSON对象,我必须加密它的一些值.

GET响应中,我收到一个JSON对象,我必须解密它的一些值.

到目前为止,以下代码完美地运行:

 def handle_request(self, r):
    if(r.method=='POST'):
       // encryption of r.get_form_urlencoded()

 def handle_response(self, r):
    if(r.request.method=='GET'):
       // decryption of r.content
Run Code Online (Sandbox Code Playgroud)

如何用单个块做同样的事情?

编辑:更新

在评估了不同的解决方案之后,我决定选择Squid(代理)+ ICAP(内容改编).

我已经成功配置了Squid,性能非常好.不幸的是,我找不到合适的ICAP服务器(如果可能的话,用Python)来进行内容改编(修改).我认为这一个https://github.com/netom/pyicap可以完成这项工作,但看起来它没有读取myPOST请求的正文.

你们知道我可以和Squid一起使用的Python ICAP服务器吗?

谢谢

Max*_*ils 1

下面的答案已经过时了。您现在可以传递--stream给 mitmproxy,其行为在mitmproxy 文档中进行了解释中进行了解释。

mitmproxy 开发人员在这里。这绝对是我们想要 mitmproxy 提供的功能,但它并不是那么微不足道,而且可能不会很快实现。如果你真的想自己实现,我可以推荐两件事:

  1. 如果您有一个非常具体的用例,您可以使用libmproxy.protocol.http.HTTPRequest.from_stream来解析标头并自行进行正文处理。
  2. 如果您不想修改请求/响应正文,您可能会发现修改 mitmproxy 本身就足够了。简而言之,您需要读取不带内容的请求/响应(请参阅 1.),根据您的需要对其进行修改,将其传递给服务器,然后将控制权委托给 libmproxy.protocol.tcp(请参阅https://github .com/mitmproxy/mitmproxy/blob/master/libmproxy/proxy/server.py#L169

如果您还有其他问题,请随时在此处或 mitmproxy 的 IRC 频道提问。


回复评论#1:

您不能从 mitmproxy 中获取太多内容,但至少您可以委托标头解析和处理。

# ...accept request, socket.makefile() etc...
req = HTTPRequest.from_stream(client_conn.rfile, include_content=False)
# manually forward to the server (req._assemble_head())
# manually receive response body chunk by chunk and forward it to the server, see
# https://github.com/mitmproxy/netlib/blob/master/netlib/http.py#L98
resp = HTTPResponse.from_stream(server_conn.rfile, include_content=False)
# manually forward headers
# manually process body and forward
Run Code Online (Sandbox Code Playgroud)

话虽这么说,这是一个相当复杂的话题。最终,您最好直接将其破解到 libmproxy.protocol.http.HTTPHandler 中。

另一种选择,再次取决于您的用例:使用 mitmproxy,将 conntype 设置为 tcp 并按原样转发流量,并对 libmproxy.protocol.tcp 中的内容使用正则表达式替换。可能是最简单的方法,但也是最hacky的方法。如果您可以提供一些背景信息,我可以进一步引导您朝正确的方向前进。


回复评论#2:

在我们进入主要部分之前:只要您不想加密完整的 JSON 对象并将其视为单个字符串,JSON 对于流/分块来说是一个非常糟糕的选择。如果您只想加密部分内容,那么您绝对应该考虑像 tnetstrings 这样的东西。

除此之外,挂钩到 read_chunk 是可行的,但首先您需要达到可以实际通过线路接收块的程度。然后,就像读取单个块、加密它们并转发它们一样简单。