make shorthand parsing more robust, add unit tests and documentation

This commit is contained in:
Nathan LaFreniere 2013-10-09 11:32:41 -07:00
parent 711168a899
commit 8a52bef559
3 changed files with 65 additions and 3 deletions

View File

@ -121,7 +121,6 @@ See also ``http --help``.
Examples Examples
-------- --------
Custom `HTTP method`_, `HTTP headers`_ and `JSON`_ data: Custom `HTTP method`_, `HTTP headers`_ and `JSON`_ data:
.. code-block:: bash .. code-block:: bash
@ -226,6 +225,15 @@ The only information HTTPie needs to perform a request is a URL.
The default scheme is, somewhat unsurprisingly, ``http://``, The default scheme is, somewhat unsurprisingly, ``http://``,
and can be omitted from the argument ``http example.org`` works just fine. and can be omitted from the argument ``http example.org`` works just fine.
Additionally, curl-like shorthand for localhost is supported.
This means that, for example ``:3000`` would expand to ``http://localhost:3000``
If the port is omitted, then port 80 is assumed.
.. code-block:: bash
$ http :/foo
$ http :3000/bar
If find yourself manually constructing URLs with **querystring parameters** If find yourself manually constructing URLs with **querystring parameters**
on the terminal, you may appreciate the ``param==value`` syntax for appending on the terminal, you may appreciate the ``param==value`` syntax for appending
URL parameters so that you don't have to worry about escaping the ``&`` URL parameters so that you don't have to worry about escaping the ``&``

View File

@ -138,8 +138,15 @@ class Parser(ArgumentParser):
if not (self.args.url.startswith((HTTP, HTTPS))): if not (self.args.url.startswith((HTTP, HTTPS))):
# Default to 'https://' if invoked as `https args`. # Default to 'https://' if invoked as `https args`.
scheme = HTTPS if self.env.progname == 'https' else HTTP scheme = HTTPS if self.env.progname == 'https' else HTTP
if self.args.url.startswith(':'): # See if we're using curl style shorthand for localhost (:3000/foo)
self.args.url = scheme + 'localhost' + self.args.url shorthand = re.match(r'^:(?!:)(\d*)(\/?.*)$', self.args.url)
if shorthand:
port = shorthand.group(1)
rest = shorthand.group(2)
self.args.url = scheme + 'localhost'
if port:
self.args.url += ':' + port
self.args.url += rest
else: else:
self.args.url = scheme + self.args.url self.args.url = scheme + self.args.url
self._process_auth() self._process_auth()

View File

@ -64,6 +64,7 @@ sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..')))
from httpie import ExitStatus from httpie import ExitStatus
from httpie import input from httpie import input
from httpie.cli import parser
from httpie.models import Environment from httpie.models import Environment
from httpie.core import main from httpie.core import main
from httpie.output import BINARY_SUPPRESSED_NOTICE from httpie.output import BINARY_SUPPRESSED_NOTICE
@ -1264,6 +1265,52 @@ class ItemParsingTest(BaseTestCase):
self.assertEqual(files['file'][1].read().strip().decode('utf8'), self.assertEqual(files['file'][1].read().strip().decode('utf8'),
FILE_CONTENT) FILE_CONTENT)
class CLIParserTestCase(unittest.TestCase):
def test_expand_localhost_shorthand(self):
args = parser.parse_args(args=[':'], env=TestEnvironment())
self.assertEqual(args.url, 'http://localhost')
def test_expand_localhost_shorthand_with_slash(self):
args = parser.parse_args(args=[':/'], env=TestEnvironment())
self.assertEqual(args.url, 'http://localhost/')
def test_expand_locahost_shorthand_with_port(self):
args = parser.parse_args(args=[':3000'], env=TestEnvironment())
self.assertEqual(args.url, 'http://localhost:3000')
def test_expand_localhost_shorthand_with_path(self):
args = parser.parse_args(args=[':/path'], env=TestEnvironment())
self.assertEqual(args.url, 'http://localhost/path')
def test_expand_localhost_shorthand_with_port_and_slash(self):
args = parser.parse_args(args=[':3000/'], env=TestEnvironment())
self.assertEqual(args.url, 'http://localhost:3000/')
def test_expand_localhost_shorthand_with_port_and_path(self):
args = parser.parse_args(args=[':3000/path'], env=TestEnvironment())
self.assertEqual(args.url, 'http://localhost:3000/path')
def test_dont_expand_shorthand_ipv6_as_shorthand(self):
args = parser.parse_args(args=['::1'], env=TestEnvironment())
self.assertEqual(args.url, 'http://::1')
def test_dont_expand_longer_ipv6_as_shorthand(self):
args = parser.parse_args(args=['::ffff:c000:0280'], env=TestEnvironment())
self.assertEqual(args.url, 'http://::ffff:c000:0280')
def test_dont_expand_full_ipv6_as_shorthand(self):
args = parser.parse_args(args=['0000:0000:0000:0000:0000:0000:0000:0001'], env=TestEnvironment())
self.assertEqual(args.url, 'http://0000:0000:0000:0000:0000:0000:0000:0001')
class ArgumentParserTestCase(unittest.TestCase): class ArgumentParserTestCase(unittest.TestCase):