Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go net/http unix domain socket connection

Tags:

http

go

sockets

I am having trouble connecting to my server, which listens on a Unix Domain Socket.

Go's net/http package doesn't seem to be able to use socket paths to connect to a target.

Is there a good alternative without having to create my own HTTP Protocol implementation using net?


I found lots of solutions like these, but they are unsuitable

I have tried:

_, err := http.Get("unix:///var/run/docker.sock") (changing unix to path/socket. It always complains about an unsupported protocol

like image 323
Matej Avatar asked Oct 06 '14 19:10

Matej


People also ask

How do I use a domain socket in UNIX?

To create a UNIX domain socket, use the socket function and specify AF_UNIX as the domain for the socket. The z/TPF system supports a maximum number of 16,383 active UNIX domain sockets at any time. After a UNIX domain socket is created, you must bind the socket to a unique file path by using the bind function.

What is UNIX socket connection?

A Unix domain socket aka UDS or IPC socket (inter-process communication socket) is a data communications endpoint for exchanging data between processes executing on the same host operating system.

Are UNIX sockets faster than TCP?

Unix domain sockets are often twice as fast as a TCP socket when both peers are on the same host. The Unix domain protocols are not an actual protocol suite, but a way of performing client/server communication on a single host using the same API that is used for clients and servers on different hosts.

Are UNIX domain sockets reliable?

Valid socket types in the UNIX domain are: SOCK_STREAM, for a stream-oriented socket; SOCK_DGRAM, for a datagram-oriented socket that preserves message boundaries (as on most UNIX implementations, UNIX domain datagram sockets are always reliable and don't reorder datagrams); and (since Linux 2.6.


1 Answers

You would have to implement your own RoundTripper to support unix sockets.

The easiest way is probably to just use http instead of unix sockets to communicate with docker.

Edit the init script and add -H tcp://127.0.0.1:xxxx, for example:

/usr/bin/docker -H tcp://127.0.0.1:9020

You can also just fake the dial function and pass it to the transport:

func fakeDial(proto, addr string) (conn net.Conn, err error) {
    return net.Dial("unix", sock)
}

tr := &http.Transport{
    Dial: fakeDial,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("http://d/test")

playground

There's only one tiny caveat, all your client.Get / .Post calls has to be a valid url (http://xxxx.xxx/path not unix://...), the domain name doesn't matter since it won't be used in connecting.

like image 96
OneOfOne Avatar answered Oct 06 '22 10:10

OneOfOne