Repository: mitmproxy/mitmproxy

Issue:
Crash when the PAGER is `less -R`
```
> echo $PAGER
less -R
```

Then if I use < or > to navigate, I will get the following exception. 

```
› mitmproxy -nr game_subway-bmx

Traceback (most recent call last):
  File "/usr/local/bin/mitmproxy", line 67, in <module>
    m.run()
  File "/Library/Python/2.7/site-packages/libmproxy/console/__init__.py", line 583, in run
    self.ui.run_wrapper(self.loop)
  File "/Library/Python/2.7/site-packages/urwid/raw_display.py", line 242, in run_wrapper
    return fn()
  File "/Library/Python/2.7/site-packages/libmproxy/console/__init__.py", line 812, in loop
    k = self.view.keypress(size, k)
  File "/Library/Python/2.7/site-packages/urwid/container.py", line 1103, in keypress
    return self.body.keypress( (maxcol, remaining), key )
  File "/Library/Python/2.7/site-packages/libmproxy/console/flowview.py", line 546, in keypress
    self.master.spawn_external_viewer(conn.content, t)
  File "/Library/Python/2.7/site-packages/libmproxy/console/__init__.py", line 546, in spawn_external_viewer
    subprocess.call(cmd, shell=shell)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1228, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
```



Discussion:
I bet this is because it's trying to call "less -R" instead of "less".


Resolving patch:
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import mailcap, mimetypes, tempfile, os, subprocess, glob, time, shlex
+import mailcap, mimetypes, tempfile, os, subprocess, glob, time, shlex, stat
 import os.path, sys, weakref
 import urwid
 from .. import controller, utils, flow
@@ -504,7 +504,7 @@ def spawn_editor(self, data):
         os.write(fd, data)
         os.close(fd)
         c = os.environ.get("EDITOR")
-        #If no EDITOR is set, assume 'vi'
+        # if no EDITOR is set, assume 'vi'
         if not c:
             c = "vi"
         cmd = shlex.split(c)
@@ -513,12 +513,10 @@ def spawn_editor(self, data):
         try:
             subprocess.call(cmd)
         except:
-            self.statusbar.message("Can't start editor: %s" % c)
-            self.ui.start()
-            os.unlink(name)
-            return data
+            self.statusbar.message("Can't start editor: %s" % " ".join(c))
+        else:
+            data = open(name).read()
         self.ui.start()
-        data = open(name).read()
         os.unlink(name)
         return data
 
@@ -531,6 +529,9 @@ def spawn_external_viewer(self, data, contenttype):
         os.write(fd, data)
         os.close(fd)
 
+        # read-only to remind the user that this is a view function
+        os.chmod(name, stat.S_IREAD)
+
         cmd = None
         shell = False
 
@@ -540,10 +541,17 @@ def spawn_external_viewer(self, data, contenttype):
             if cmd:
                 shell = True
         if not cmd:
+            # hm which one should get priority?
             c = os.environ.get("PAGER") or os.environ.get("EDITOR")
-            cmd = [c, name]
+            if not c:
+                c = "less"
+            cmd = shlex.split(c)
+            cmd.append(name)
         self.ui.stop()
-        subprocess.call(cmd, shell=shell)
+        try:
+            subprocess.call(cmd, shell=shell)
+        except:
+            self.statusbar.message("Can't start external viewer: %s" % " ".join(c))
         self.ui.start()
         os.unlink(name)
 
diff --git a/libmproxy/console/flowview.py b/libmproxy/console/flowview.py
--- a/libmproxy/console/flowview.py
+++ b/libmproxy/console/flowview.py
@@ -343,7 +343,7 @@ def edit(self, part):
         self.flow.backup()
         if part == "r":
             c = self.master.spawn_editor(conn.content or "")
-            conn.content = c.rstrip("\n")
+            conn.content = c.rstrip("\n") # what?
         elif part == "f":
             if not conn.get_form_urlencoded() and conn.content:
                 self.master.prompt_onekey(


Test patch: