[Solved] How can I create a streaming artificial response object?


#1

Hi. Does anyone know how to generate synthetic streamed responses to requests?
I’ve managed to generate a non-streamed response with:

flow.response = mitmproxy.http.HTTPResponse.make(
    200,
    "Some content.",
    {},
)

I can also completely replace the response content in a real response with:

flow.response.stream = some_generator_that_streams_my_content

I’ve attempted to combine these two techniques by generating a response with some simple dummy content and then using the flow.response.stream generator to replace it with my actual stream of content but I just get this exception when I try that:

172.22.0.3:59494: Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/proxy/server.py", line 121, in handle
    root_layer()
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/proxy/modes/transparent_proxy.py", line 19, in __call__
    layer()
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/proxy/protocol/tls.py", line 286, in __call__
    layer()
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/proxy/protocol/http1.py", line 83, in __call__
    layer()
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/proxy/protocol/http.py", line 188, in __call__
    if not self._process_flow(flow):
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/proxy/protocol/http.py", line 422, in _process_flow
    self.send_response_body(f.response, chunks)
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/proxy/protocol/http1.py", line 58, in send_response_body
    for chunk in http1.assemble_body(response.headers, chunks):
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/net/http/http1/assemble.py", line 40, in assemble_body
    for chunk in body_chunks:
  File "/usr/local/lib/python3.6/site-packages/mitmproxy/net/http/http1/read.py", line 138, in read_body
    content = rfile.read(chunk_size)
AttributeError: 'NoneType' object has no attribute 'read'

Is there a way to make a response object directly from a file-like object or a generator that reads such an object?


#2

In case anyone else stumbles across this thread, I’m happy to report I’ve found the solution.

I generate the placeholder response as described in my original post, then I set flow.server_conn.rfile to my file-like object. The content is then read from this file-like object rather than the placeholder string.