diff --git a/README.md b/README.md index b65ed59..127b5e3 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,17 @@ If no channel is specified in the options to a rpc call the `default_channel` is {client, #{channels => [{default_channel, [{http, "localhost", 8080, []}], #{}}]}} ``` +Unix sockets (UDS) may also be used with the same notation that is defined in `gen_tcp`. Considerations: +* for UDS, only the `http` scheme is permitted +* the port must strictly be `0` +* only available on POSIX operating systems +* abstract UDS are only available on Linux, and such sockets' names must start with a zero byte +``` +{client, #{channels => [{default_channel, [{http, {local, "/path/to/unix/socket_name"}, 0, []}], #{}}]}} +%% or to use an abstract Unix socket: +%% {client, #{channels => [{default_channel, [{http, {local, [0 | "socket_name"]}, 0, []}], #{}}]}} +``` + The empty map at the end can contain configuration for the load balancing algorithm, interceptors, statistics handling and compression: ``` diff --git a/src/grpcbox.app.src b/src/grpcbox.app.src index 960d08e..d242c87 100644 --- a/src/grpcbox.app.src +++ b/src/grpcbox.app.src @@ -9,7 +9,7 @@ acceptor_pool, gproc, ctx]}, - {env, [{client, #{channels => [%% {default_channel, round_robin, [{http, "localhost", 8080, []}], #{}} + {env, [{client, #{channels => [%% {default_channel, [{http, "localhost", 8080, []}], #{}} ]}}, {grpc_opts, #{service_protos => [], diff --git a/src/grpcbox_subchannel.erl b/src/grpcbox_subchannel.erl index 5e13c1e..4f60bd3 100644 --- a/src/grpcbox_subchannel.erl +++ b/src/grpcbox_subchannel.erl @@ -48,6 +48,24 @@ init([Name, Channel, Endpoint, Encoding, StatsHandler]) -> endpoint=Endpoint, channel=Channel}}. +%% In case of unix socket transport +%% (defined as tuple {local, _UnixPath} in gen_tcp), +%% there is no standard on what the authority field value +%% should be, as HTTP/2 over UDS is not formally specified. +%% To follow other gRPC implementations' behavior, +%% the "localhost" value is used. +info_map({Scheme, {local, _UnixPath} = Host, Port, _, _}, Encoding, StatsHandler) -> + case {Scheme, Port} of + %% The ssl layer is not functional over unix sockets currently, + %% and the port is strictly required to be 0 by gen_tcp. + {http, 0} -> + #{authority => <<"localhost">>, + scheme => <<"http">>, + encoding => Encoding, + stats_handler => StatsHandler}; + _ -> + error({badarg, [Scheme, Host, Port]}) + end; info_map({http, Host, 80, _, _}, Encoding, StatsHandler) -> #{authority => list_to_binary(Host), scheme => <<"http">>,