Repository: mitmproxy/mitmproxy

Issue:
Mitmproxy crashes, when trying to create a new flow with incorrect url
##### Steps to reproduce the problem:

1. Create a new flow by pressing `n`.
2. For getting `ValueError: Invalid Host` input `https://google.com\` as url.
3. For getting `ValueError: No hostname given` input `https://` as url.

I am getting:
```
Traceback (most recent call last):
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/master.py", line 216, in run
    self.loop.run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 278, in run
    self._run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 376, in _run
    self.event_loop.run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 682, in run
    self._loop()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 719, in _loop
    self._watch_files[fd]()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/raw_display.py", line 393, in <lambda>
    event_loop, callback, self.get_available_raw_input())
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/raw_display.py", line 493, in parse_input
    callback(processed, processed_codes)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 403, in _update
    self.process_input(keys)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 503, in process_input
    k = self._topmost_widget.keypress(self.screen_size, k)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/window.py", line 293, in keypress
    k = super().keypress(size, k)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1116, in keypress
    return self.footer.keypress((maxcol,),key)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 149, in keypress
    return self.ab.keypress(*args, **kwargs)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 104, in keypress
    self.prompt_execute(self._w.get_value())
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/statusbar.py", line 124, in prompt_execute
    msg = p(txt)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/commandexecutor.py", line 17, in __call__
    ret = self.master.commands.call(cmd)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 221, in call
    return self.call_args(parts[0], parts[1:])
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 212, in call_args
    return self.commands[path].call(args)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 101, in call
    ret = self.func(*pargs)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/command.py", line 251, in wrapper
    return function(*args, **kwargs)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/addons/view.py", line 444, in create
    req = http.HTTPRequest.make(method.upper(), url)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/net/http/request.py", line 103, in make
    req.url = url
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/net/http/request.py", line 291, in url
    self.scheme, self.host, self.port, self.path = mitmproxy.net.http.url.parse(url)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/net/http/url.py", line 27, in parse
    raise ValueError("No hostname given")
ValueError: No hostname given
```

##### Any other comments? What have you tried so far?
Raised by unhandled: 
https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/net/http/url.py#L50
https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/net/http/url.py#L27

##### System information
Mitmproxy: 3.0.0.dev1101 (commit d9d4d15) binary
Python:    3.5.2
OpenSSL:   OpenSSL 1.1.0g  2 Nov 2017
Platform:  Linux-4.4.0-104-generic-x86_64-with-debian-stretch-sid


Discussion:
This needs to be caught and handled in the `view.create` command.
  

Resolving patch:
diff --git a/mitmproxy/addons/view.py b/mitmproxy/addons/view.py
--- a/mitmproxy/addons/view.py
+++ b/mitmproxy/addons/view.py
@@ -441,7 +441,10 @@ def resolve(self, spec: str) -> typing.Sequence[mitmproxy.flow.Flow]:
 
     @command.command("view.create")
     def create(self, method: str, url: str) -> None:
-        req = http.HTTPRequest.make(method.upper(), url)
+        try:
+            req = http.HTTPRequest.make(method.upper(), url)
+        except ValueError as e:
+            raise exceptions.CommandError("Invalid URL: %s" % e)
         c = connections.ClientConnection.make_dummy(("", 0))
         s = connections.ServerConnection.make_dummy((req.host, req.port))
         f = http.HTTPFlow(c, s)


Test patch:
diff --git a/test/mitmproxy/addons/test_view.py b/test/mitmproxy/addons/test_view.py
--- a/test/mitmproxy/addons/test_view.py
+++ b/test/mitmproxy/addons/test_view.py
@@ -147,6 +147,10 @@ def test_create():
         assert v[0].request.url == "http://foo.com/"
         v.create("get", "http://foo.com")
         assert len(v) == 2
+        with pytest.raises(exceptions.CommandError, match="Invalid URL"):
+            v.create("get", "http://foo.com\\")
+        with pytest.raises(exceptions.CommandError, match="Invalid URL"):
+            v.create("get", "http://")
 
 
 def test_orders():