Piping mitmdump output to another program and quitting the latter early results in BrokenPipeErrors
See original GitHub issueProblem Description
Piping mitmdump output to another program and exiting that latter program before it has read all of mitmdump’s output produces a lot of BrokenPipeError: [Errno 32] Broken pipe
errors.
Steps to reproduce the behavior:
- Capture a non-trivial amount of traffic:
mitmdump -w outfile
; the nature of the traffic (HTTP/HTTPS/WebSocket) does not seem to matter. The outfile has to be large enough for the next command to produce enough output that the pipe buffer gets backlogged. - Print the contents of the dump file and pipe it to something like
less
:mitmdump -nr outfile | less
- Quit
less
with theq
key. - mitmdump produces a traceback similar to the following for every record in the outfile that has not been consumed by
less
prior to quitting:
Addon error: Traceback (most recent call last):
File ".../lib/python3.8/site-packages/mitmproxy/addons/termlog.py", line 31, in log
click.secho(
File ".../lib/python3.8/site-packages/click/termui.py", line 548, in secho
return echo(message, file=file, nl=nl, err=err, color=color)
File ".../lib/python3.8/site-packages/click/utils.py", line 273, in echo
file.flush()
BrokenPipeError: [Errno 32] Broken pipe
Addon error: Traceback (most recent call last):
File ".../lib/python3.8/site-packages/mitmproxy/addons/dumper.py", line 263, in websocket_message
self.echo(f.message_info(message))
File ".../lib/python3.8/site-packages/mitmproxy/addons/dumper.py", line 70, in echo
click.secho(text, file=self.outfp, **style)
File ".../lib/python3.8/site-packages/click/termui.py", line 548, in secho
return echo(message, file=file, nl=nl, err=err, color=color)
File ".../lib/python3.8/site-packages/click/utils.py", line 273, in echo
file.flush()
BrokenPipeError: [Errno 32] Broken pipe
Attempted workarounds and possible solution
The obvious workaround is to first make the second program consume everything and only then quit. For example, with less
, pressing G
to scroll to the bottom of the output before quitting. However, since less
keeps everything in memory, this may not be feasible for large dump files.
Killing metadump with ^C
after quitting less
does not seem to help.
For this particular use case of displaying file information, the ideal solution would be to simply exit on a BrokenPipeError
. This would also mean that the rest of the dump file would not be processed, needlessly wasting CPU time. But the general case is probably rather to disable all further output to stdout but keep processing (e.g. if a dump file is being filtered into another file).
System Information
$ mitmproxy --version
Mitmproxy: 5.1.1 (+2, commit a8ca63f)
Python: 3.8.2
OpenSSL: OpenSSL 1.1.1g 21 Apr 2020
Platform: Linux-5.6.0-1-amd64-x86_64-with-glibc2.29
This is a current Debian sid system. The (+2, commit a8ca63f)
info on the mitmproxy version is a bug (#3987) and can be disregarded; this is a clean 5.1.1 installation.
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (5 by maintainers)
Top GitHub Comments
@myfingerhurt I’m not sure about the other things you mentioned, but about this:
You may want to try setting the
PYTHONUNBUFFERED
environment variable to a non-empty value.This is funny though. Pipe is the most fundamental and most wanted and should work flawlessly as we all expected.
mitmweb -s mitm_anatomy.py | tee /tmp/mitm.log
this didn’t work, came out the following error when terminated,mitm.log
is emptymitmweb mitmweb -s mitm_anatomy.py 2>&1 | tee /tmp/mitm.log
only the stderr could be saved tomitm.log
mitmweb mitmweb -s mitm_anatomy.py 2>&1 > /tmp/mitm.log
did save both stderr and stdout tomitm.log
but only flushed to the file after terminated. I needed the real-time log for tail -F to work with another program.Had to do these to get what I wanted