use 127.0.0.1 instead of localhost

localhost can cause some issues on badly behaved or misconfigured systems,
and 127 seems simpler.
This commit is contained in:
Min RK
2016-02-03 10:30:09 +01:00
parent 6c072bdb3d
commit f626d2f6e5
7 changed files with 14 additions and 47 deletions

View File

@@ -50,7 +50,7 @@ from ._data import DATA_FILES_PATH
from .log import CoroutineLogFormatter, log_request from .log import CoroutineLogFormatter, log_request
from .traitlets import URLPrefix, Command from .traitlets import URLPrefix, Command
from .utils import ( from .utils import (
url_path_join, localhost, url_path_join,
ISO8601_ms, ISO8601_s, ISO8601_ms, ISO8601_s,
) )
# classes for config # classes for config
@@ -260,7 +260,7 @@ class JupyterHub(Application):
token = orm.new_token() token = orm.new_token()
return token return token
proxy_api_ip = Unicode(localhost(), config=True, proxy_api_ip = Unicode('127.0.0.1', config=True,
help="The ip for the proxy API handlers" help="The ip for the proxy API handlers"
) )
proxy_api_port = Integer(config=True, proxy_api_port = Integer(config=True,
@@ -272,7 +272,7 @@ class JupyterHub(Application):
hub_port = Integer(8081, config=True, hub_port = Integer(8081, config=True,
help="The port for this process" help="The port for this process"
) )
hub_ip = Unicode(localhost(), config=True, hub_ip = Unicode('127.0.0.1', config=True,
help="The ip for this process" help="The ip for this process"
) )

View File

@@ -26,7 +26,7 @@ from sqlalchemy import create_engine
from .utils import ( from .utils import (
random_port, url_path_join, wait_for_server, wait_for_http_server, random_port, url_path_join, wait_for_server, wait_for_http_server,
new_token, hash_token, compare_token, localhost, new_token, hash_token, compare_token,
) )
@@ -78,7 +78,7 @@ class Server(Base):
ip = self.ip ip = self.ip
if ip in {'', '0.0.0.0'}: if ip in {'', '0.0.0.0'}:
# when listening on all interfaces, connect to localhost # when listening on all interfaces, connect to localhost
ip = localhost() ip = '127.0.0.1'
return "{proto}://{ip}:{port}".format( return "{proto}://{ip}:{port}".format(
proto=self.proto, proto=self.proto,
ip=ip, ip=ip,
@@ -100,7 +100,7 @@ class Server(Base):
since it can be non-connectable value, such as '', meaning all interfaces. since it can be non-connectable value, such as '', meaning all interfaces.
""" """
if self.ip in {'', '0.0.0.0'}: if self.ip in {'', '0.0.0.0'}:
return self.url.replace('localhost', self.ip or '*', 1) return self.url.replace('127.0.0.1', self.ip or '*', 1)
return self.url return self.url
@gen.coroutine @gen.coroutine
@@ -109,12 +109,12 @@ class Server(Base):
if http: if http:
yield wait_for_http_server(self.url, timeout=timeout) yield wait_for_http_server(self.url, timeout=timeout)
else: else:
yield wait_for_server(self.ip or localhost(), self.port, timeout=timeout) yield wait_for_server(self.ip or '127.0.0.1', self.port, timeout=timeout)
def is_up(self): def is_up(self):
"""Is the server accepting connections?""" """Is the server accepting connections?"""
try: try:
socket.create_connection((self.ip or localhost(), self.port)) socket.create_connection((self.ip or '127.0.0.1', self.port))
except socket.error as e: except socket.error as e:
if e.errno == errno.ENETUNREACH: if e.errno == errno.ENETUNREACH:
try: try:

View File

@@ -22,7 +22,7 @@ from traitlets import (
) )
from .traitlets import Command from .traitlets import Command
from .utils import random_port, localhost from .utils import random_port
class Spawner(LoggingConfigurable): class Spawner(LoggingConfigurable):
"""Base class for spawning single-user notebook servers. """Base class for spawning single-user notebook servers.
@@ -41,7 +41,7 @@ class Spawner(LoggingConfigurable):
hub = Any() hub = Any()
authenticator = Any() authenticator = Any()
api_token = Unicode() api_token = Unicode()
ip = Unicode(localhost(), config=True, ip = Unicode('127.0.0.1', config=True,
help="The IP address (or hostname) the single-user server should listen on" help="The IP address (or hostname) the single-user server should listen on"
) )
start_timeout = Integer(60, config=True, start_timeout = Integer(60, config=True,

View File

@@ -17,7 +17,6 @@ from ..spawner import LocalProcessSpawner
from ..app import JupyterHub from ..app import JupyterHub
from ..auth import PAMAuthenticator from ..auth import PAMAuthenticator
from .. import orm from .. import orm
from ..utils import localhost
from pamela import PAMError from pamela import PAMError
@@ -111,7 +110,7 @@ class MockHub(JupyterHub):
db_file = None db_file = None
def _ip_default(self): def _ip_default(self):
return localhost() return '127.0.0.1'
def _authenticator_class_default(self): def _authenticator_class_default(self):
return MockPAMAuthenticator return MockPAMAuthenticator

View File

@@ -20,7 +20,7 @@ def test_server(db):
assert server.proto == 'http' assert server.proto == 'http'
assert isinstance(server.port, int) assert isinstance(server.port, int)
assert isinstance(server.cookie_name, str) assert isinstance(server.cookie_name, str)
assert server.host == 'http://localhost:%i' % server.port assert server.host == 'http://127.0.0.1:%i' % server.port
assert server.url == server.host + '/' assert server.url == server.host + '/'
assert server.bind_url == 'http://*:%i/' % server.port assert server.bind_url == 'http://*:%i/' % server.port
server.ip = '127.0.0.1' server.ip = '127.0.0.1'

View File

@@ -45,7 +45,7 @@ def new_spawner(db, **kwargs):
def test_spawner(db, io_loop): def test_spawner(db, io_loop):
spawner = new_spawner(db) spawner = new_spawner(db)
io_loop.run_sync(spawner.start) io_loop.run_sync(spawner.start)
assert spawner.user.server.ip == 'localhost' assert spawner.user.server.ip == '127.0.0.1'
# wait for the process to get to the while True: loop # wait for the process to get to the while True: loop
time.sleep(1) time.sleep(1)
@@ -59,7 +59,7 @@ def test_spawner(db, io_loop):
def test_single_user_spawner(db, io_loop): def test_single_user_spawner(db, io_loop):
spawner = new_spawner(db, cmd=['jupyterhub-singleuser']) spawner = new_spawner(db, cmd=['jupyterhub-singleuser'])
io_loop.run_sync(spawner.start) io_loop.run_sync(spawner.start)
assert spawner.user.server.ip == 'localhost' assert spawner.user.server.ip == '127.0.0.1'
# wait for http server to come up, # wait for http server to come up,
# checking for early termination every 1s # checking for early termination every 1s
def wait(): def wait():

View File

@@ -195,35 +195,3 @@ def url_path_join(*pieces):
return result return result
def localhost():
"""Return localhost or 127.0.0.1"""
if hasattr(localhost, '_localhost'):
return localhost._localhost
binder = connector = None
try:
binder = socket.socket()
binder.bind(('localhost', 0))
binder.listen(1)
port = binder.getsockname()[1]
def accept():
try:
conn, addr = binder.accept()
except ConnectionAbortedError:
pass
else:
conn.close()
t = Thread(target=accept)
t.start()
connector = socket.create_connection(('localhost', port), timeout=10)
t.join(timeout=10)
except (socket.error, socket.gaierror) as e:
warnings.warn("localhost doesn't appear to work, using 127.0.0.1\n%s" % e, RuntimeWarning)
localhost._localhost = '127.0.0.1'
else:
localhost._localhost = 'localhost'
finally:
if binder:
binder.close()
if connector:
connector.close()
return localhost._localhost