diff --git a/elasticsearch/client/__init__.py b/elasticsearch/client/__init__.py index dbdbb3798..b7508d85c 100644 --- a/elasticsearch/client/__init__.py +++ b/elasticsearch/client/__init__.py @@ -1,9 +1,10 @@ +from __future__ import unicode_literals import weakref import logging from ..transport import Transport from ..exceptions import NotFoundError, TransportError -from ..compat import string_types +from ..compat import string_types, urlparse from .indices import IndicesClient from .cluster import ClusterClient from .cat import CatClient @@ -30,22 +31,27 @@ def _normalize_hosts(hosts): # normalize hosts to dicts for i, host in enumerate(hosts): if isinstance(host, string_types): - host = host.strip('/') - # remove schema information - if '://' in host: + if '://' not in host: + host = "//%s" % host + + parsed_url = urlparse(host) + h = {"host": parsed_url.hostname} + + if parsed_url.port: + h["port"] = parsed_url.port + + if parsed_url.scheme == "https": + h['port'] = parsed_url.port or 443 + h['use_ssl'] = True + elif parsed_url.scheme == "http": logger.warning( "List of nodes should not include schema information (http://): %r.", host ) - host = host[host.index('://') + 3:] - - h = {"host": host} - if ':' in host: - # TODO: detect auth urls - host, port = host.rsplit(':', 1) - if port.isdigit(): - port = int(port) - h = {"host": host, "port": port} + + if parsed_url.username or parsed_url.password: + h['http_auth'] = '%s:%s' % (parsed_url.username, parsed_url.password) + out.append(h) else: out.append(host) diff --git a/elasticsearch/compat.py b/elasticsearch/compat.py index 5004096e7..deee3c524 100644 --- a/elasticsearch/compat.py +++ b/elasticsearch/compat.py @@ -5,8 +5,9 @@ if PY2: string_types = basestring, from urllib import quote_plus, urlencode + from urlparse import urlparse from itertools import imap as map else: string_types = str, bytes - from urllib.parse import quote_plus, urlencode + from urllib.parse import quote_plus, urlencode, urlparse map = map diff --git a/test_elasticsearch/test_client/__init__.py b/test_elasticsearch/test_client/__init__.py index a9f6b9f13..111009227 100644 --- a/test_elasticsearch/test_client/__init__.py +++ b/test_elasticsearch/test_client/__init__.py @@ -13,12 +13,19 @@ def test_none_uses_defaults(self): def test_strings_are_used_as_hostnames(self): self.assertEquals([{"host": "elasticsearch.org"}], _normalize_hosts(["elasticsearch.org"])) - def test_strings_are_parsed_for_port(self): + def test_strings_are_parsed_for_port_and_user(self): self.assertEquals( - [{"host": "elasticsearch.org", "port": 42}, {"host": "user:secret@elasticsearch.com"}], + [{"host": "elasticsearch.org", "port": 42}, {"host": "elasticsearch.com", "http_auth": "user:secret"}], _normalize_hosts(["elasticsearch.org:42", "user:secret@elasticsearch.com"]) ) + def test_strings_are_parsed_for_scheme(self): + self.assertEquals( + [{"host": "elasticsearch.org", "port": 42, "use_ssl": True}, + {"host": "elasticsearch.com", "http_auth": "user:secret", "use_ssl": True, "port": 443}], + _normalize_hosts(["https://elasticsearch.org:42", "https://user:secret@elasticsearch.com"]) + ) + def test_dicts_are_left_unchanged(self): self.assertEquals([{"host": "local", "extra": 123}], _normalize_hosts([{"host": "local", "extra": 123}]))