Repository: mitmproxy/mitmproxy

Issue:
pathoc -n seems broken
##### Steps to reproduce the problem:

> pathoc -n 2 google.com get:/
> 07-06-16 12:22:24: >> 'GET':/
> << 302 Found: 261 bytes
##### What is the expected behavior?

Two requests printed.
##### What went wrong?

Only one request is printed.

---

Mitmproxy Version: -master
Operating System: osx

<!-- Please use the mitmproxy forums (https://discourse.mitmproxy.org/) for support/how-to questions. Thanks! :) -->

pathoc -n seems broken
##### Steps to reproduce the problem:

> pathoc -n 2 google.com get:/
> 07-06-16 12:22:24: >> 'GET':/
> << 302 Found: 261 bytes
##### What is the expected behavior?

Two requests printed.
##### What went wrong?

Only one request is printed.

---

Mitmproxy Version: -master
Operating System: osx

<!-- Please use the mitmproxy forums (https://discourse.mitmproxy.org/) for support/how-to questions. Thanks! :) -->



Discussion:
This is caused by [this line](https://github.com/mitmproxy/mitmproxy/blob/20bcfbb5d03fd463449412dc3a626b2958a862ca/pathod/pathoc.py#L493), where 0da3e51e1c08eed2c8054d4a71bc591268b19af1 made `args.requests[0]` a generator that is exhausted after the first pass. While looking into this, I realized that `pathoc get:/:x10` is similar to `pathoc -n 10 get:/`, with the major difference being that the former does everything on the same connection. We probably want to document that somehow.

This is caused by [this line](https://github.com/mitmproxy/mitmproxy/blob/20bcfbb5d03fd463449412dc3a626b2958a862ca/pathod/pathoc.py#L493), where 0da3e51e1c08eed2c8054d4a71bc591268b19af1 made `args.requests[0]` a generator that is exhausted after the first pass. While looking into this, I realized that `pathoc get:/:x10` is similar to `pathoc -n 10 get:/`, with the major difference being that the former does everything on the same connection. We probably want to document that somehow.


Resolving patch:
diff --git a/pathod/pathoc.py b/pathod/pathoc.py
--- a/pathod/pathoc.py
+++ b/pathod/pathoc.py
@@ -478,21 +478,31 @@ def request(self, r):
 
 
 def main(args):  # pragma: no cover
-    memo = set([])
-    trycount = 0
+    memo = set()
     p = None
+
+    if args.repeat == 1:
+        requests = args.requests
+    else:
+        # If we are replaying more than once, we must convert the request generators to lists
+        # or they will be exhausted after the first run.
+        # This is bad for the edge-case where get:/:x10000000 (see 0da3e51) is combined with -n 2,
+        # but does not matter otherwise.
+        requests = [list(x) for x in args.requests]
+
     try:
-        cnt = 0
+        requests_done = 0
         while True:
-            if cnt == args.repeat and args.repeat != 0:
+            if requests_done == args.repeat:
                 break
-            if args.wait and cnt != 0:
+            if args.wait and requests_done > 0:
                 time.sleep(args.wait)
 
-            cnt += 1
-            playlist = itertools.chain(*args.requests)
+            requests_done += 1
             if args.random:
-                playlist = random.choice(args.requests)
+                playlist = random.choice(requests)
+            else:
+                playlist = itertools.chain.from_iterable(requests)
             p = Pathoc(
                 (args.host, args.port),
                 ssl=args.ssl,
diff --git a/pathod/pathoc_cmdline.py b/pathod/pathoc_cmdline.py
--- a/pathod/pathoc_cmdline.py
+++ b/pathod/pathoc_cmdline.py
@@ -50,7 +50,7 @@ def args_pathoc(argv, stdout=sys.stdout, stderr=sys.stderr):
     )
     parser.add_argument(
         "-n", dest='repeat', default=1, type=int, metavar="N",
-        help='Repeat N times. If 0 repeat for ever.'
+        help='Repeat N times. Pass -1 to repeat infinitely.'
     )
     parser.add_argument(
         "-w", dest='wait', default=0, type=float, metavar="N",


Test patch: