Skip to content

Commit

Permalink
Add support for unix domain sockets
Browse files Browse the repository at this point in the history
adapted from some code from docker-py:

* https://github.com/docker/docker-py/blob/master/docker/unixconn/unixconn.py

Also submitted this UnixAdapter code to requests as
https://github.com/kennethreitz/requests/pull/2355

Fixes: httpieGH-209 (httpie#209)
  • Loading branch information
msabramo committed Nov 25, 2014
1 parent 0481957 commit d838a91
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
54 changes: 54 additions & 0 deletions httpie/adapters.py
@@ -0,0 +1,54 @@
import socket

from requests.adapters import HTTPAdapter
from requests.compat import urlparse, unquote
from requests.packages.urllib3.connection import HTTPConnection
from requests.packages.urllib3.connectionpool import HTTPConnectionPool


# The following was adapted from some code from docker-py
# https://github.com/docker/docker-py/blob/master/docker/unixconn/unixconn.py
class UnixHTTPConnection(HTTPConnection):
def __init__(self, unix_socket_url, timeout=60):
"""Create an HTTP connection to a unix domain socket
:param unix_socket_url: A URL with a scheme of 'http+unix' and the
netloc is a percent-encoded path to a unix domain socket. E.g.:
'http+unix://%2Ftmp%2Fprofilesvc.sock/status/pid'
"""
HTTPConnection.__init__(self, 'localhost', timeout=timeout)
self.unix_socket_url = unix_socket_url
self.timeout = timeout

def connect(self):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.settimeout(self.timeout)
socket_path = unquote(urlparse(self.unix_socket_url).netloc)
sock.connect(socket_path)
self.sock = sock

def request(self, method, url, **kwargs):
url = urlparse(url).path
HTTPConnection.request(self, method, url, **kwargs)


class UnixHTTPConnectionPool(HTTPConnectionPool):
def __init__(self, socket_path, timeout=60):
HTTPConnectionPool.__init__(self, 'localhost', timeout=timeout)
self.socket_path = socket_path
self.timeout = timeout

def _new_conn(self):
return UnixHTTPConnection(self.socket_path, self.timeout)


class UnixAdapter(HTTPAdapter):
def __init__(self, timeout=60):
super(UnixAdapter, self).__init__()
self.timeout = timeout

def get_connection(self, socket_path, proxies=None):
if proxies:
raise ValueError('%s does not support specifying proxies'
% self.__class__.__name__)
return UnixHTTPConnectionPool(socket_path, self.timeout)
9 changes: 8 additions & 1 deletion httpie/client.py
Expand Up @@ -6,6 +6,7 @@

from httpie import sessions
from httpie import __version__
from httpie.adapters import UnixAdapter
from httpie.compat import str
from httpie.plugins import plugin_manager

Expand All @@ -22,7 +23,7 @@ def get_response(args, config_dir):
requests_kwargs = get_requests_kwargs(args)
if args.debug:
dump_request(requests_kwargs)
response = requests.request(**requests_kwargs)
response = get_session().request(**requests_kwargs)
else:
response = sessions.get_response(
args=args,
Expand All @@ -34,6 +35,12 @@ def get_response(args, config_dir):
return response


def get_session():
session = requests.Session()
session.mount('http+unix://', UnixAdapter())
return session


def dump_request(kwargs):
sys.stderr.write('\n>>> requests.request(%s)\n\n'
% pformat(kwargs))
Expand Down
3 changes: 2 additions & 1 deletion httpie/input.py
Expand Up @@ -25,6 +25,7 @@
HTTP_GET = 'GET'
HTTP = 'http://'
HTTPS = 'https://'
HTTP_UNIX = 'http+unix://'


# Various separators used in args
Expand Down Expand Up @@ -132,7 +133,7 @@ def parse_args(self, env, args=None, namespace=None):
self._parse_items()
if not self.args.ignore_stdin and not env.stdin_isatty:
self._body_from_file(self.env.stdin)
if not (self.args.url.startswith((HTTP, HTTPS))):
if not (self.args.url.startswith((HTTP, HTTPS, HTTP_UNIX))):
scheme = HTTP

# See if we're using curl style shorthand for localhost (:3000/foo)
Expand Down

0 comments on commit d838a91

Please sign in to comment.