Repository: mitmproxy/mitmproxy

Issue:
HAR file does not appears when I try to use har_dump.py script
HAR file does not appears when I try to use har_dump.py script calling from command line

Steps to reproduce the behavior:
1. Type **mitmdump -s har_dump.py --set hardump=dump.har**
2. Press Enter
3. Do something in browser via proxy
4. Press Ctr+C

File dump.har doesn't present in my hard disc at all

System Information:

Mitmproxy: 5.0.1
Python:    3.6.3
OpenSSL:   OpenSSL 1.1.0j  20 Nov 2018
Platform:  Windows-10-10.0.18362-SP0




Discussion:
I'm having the same problem.
Mitmproxy:6.0.0.dev
python3.7.7
Platform:win10

I suspect it's the Windows console, ctrl+c causes def done not to execute

Duplicate of #3377.

Resolving patch:
diff --git a/examples/contrib/har_dump.py b/examples/contrib/har_dump.py
--- a/examples/contrib/har_dump.py
+++ b/examples/contrib/har_dump.py
@@ -20,7 +20,7 @@
 
 import mitmproxy
 
-from mitmproxy import connections  # noqa
+from mitmproxy import connection
 from mitmproxy import version
 from mitmproxy import ctx
 from mitmproxy.utils import strutils
@@ -30,7 +30,7 @@
 
 # A list of server seen till now is maintained so we can avoid
 # using 'connect' time for entries that use an existing connection.
-SERVERS_SEEN: typing.Set[connections.ServerConnection] = set()
+SERVERS_SEEN: typing.Set[connection.Server] = set()
 
 
 def load(l):
@@ -53,7 +53,7 @@ def configure(updated):
     })
 
 
-def response(flow):
+def response(flow: mitmproxy.http.HTTPFlow):
     """
        Called when a server response has been received.
     """
@@ -153,7 +153,7 @@ def response(flow):
             "params": params
         }
 
-    if flow.server_conn.connected():
+    if flow.server_conn.connected:
         entry["serverIPAddress"] = str(flow.server_conn.ip_address[0])
 
     HAR["log"]["entries"].append(entry)


Test patch:
diff --git a/examples/contrib/test_har_dump.py b/examples/contrib/test_har_dump.py
--- a/examples/contrib/test_har_dump.py
+++ b/examples/contrib/test_har_dump.py
@@ -20,12 +20,18 @@ def flow(self, resp_content=b'message'):
         )
 
     def test_simple(self, tmpdir, tdata):
+        # context is needed to provide ctx.log function that
+        # is invoked if there are exceptions
         with taddons.context() as tctx:
             a = tctx.script(tdata.path("../examples/contrib/har_dump.py"))
+            # check script is read without errors
+            assert tctx.master.logs == []
+            assert a.name_value   # last function in har_dump.py
+
             path = str(tmpdir.join("somefile"))
             tctx.configure(a, hardump=path)
-            tctx.invoke(a, "response", self.flow())
-            tctx.invoke(a, "done")
+            a.response(self.flow())
+            a.done()
             with open(path) as inp:
                 har = json.load(inp)
             assert len(har["log"]["entries"]) == 1
@@ -36,10 +42,8 @@ def test_base64(self, tmpdir, tdata):
             path = str(tmpdir.join("somefile"))
             tctx.configure(a, hardump=path)
 
-            tctx.invoke(
-                a, "response", self.flow(resp_content=b"foo" + b"\xFF" * 10)
-            )
-            tctx.invoke(a, "done")
+            a.response(self.flow(resp_content=b"foo" + b"\xFF" * 10))
+            a.done()
             with open(path) as inp:
                 har = json.load(inp)
             assert har["log"]["entries"][0]["response"]["content"]["encoding"] == "base64"
@@ -76,8 +80,8 @@ def test_binary(self, tmpdir, tdata):
             f.response.headers["random-junk"] = bytes(range(256))
             f.response.content = bytes(range(256))
 
-            tctx.invoke(a, "response", f)
-            tctx.invoke(a, "done")
+            a.response(f)
+            a.done()
 
             with open(path) as inp:
                 har = json.load(inp)