Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit f57c374

Browse files
committed
feat(shell): Add uds support to shell
Add Unix Domain Socket support to shell, in order to have something like `shell := NewShell("/unix//tmp/sock")` working
1 parent 5d34b6b commit f57c374

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed

shell.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"fmt"
1010
"io"
1111
"io/ioutil"
12+
"net"
13+
"net/http"
1214
gohttp "net/http"
1315
"os"
1416
"path"
@@ -62,14 +64,28 @@ func NewLocalShell() *Shell {
6264
}
6365

6466
func NewShell(url string) *Shell {
65-
c := &gohttp.Client{
66-
Transport: &gohttp.Transport{
67-
Proxy: gohttp.ProxyFromEnvironment,
68-
DisableKeepAlives: true,
69-
},
67+
var client *http.Client
68+
69+
tpt := &http.Transport{
70+
Proxy: http.ProxyFromEnvironment,
71+
DisableKeepAlives: true,
72+
}
73+
74+
maddr, err := ma.NewMultiaddr(url)
75+
if err != nil {
76+
client = &http.Client{Transport: tpt}
77+
return NewShellWithClient(url, client)
78+
}
79+
80+
if value, err := maddr.ValueForProtocol(ma.P_UNIX); err == nil {
81+
url = "unix"
82+
tpt.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
83+
return net.Dial("unix", value)
84+
}
7085
}
7186

72-
return NewShellWithClient(url, c)
87+
client = &http.Client{Transport: tpt}
88+
return NewShellWithClient(url, client)
7389
}
7490

7591
func NewShellWithClient(url string, c *gohttp.Client) *Shell {

shell_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
package shell
22

33
import (
4+
"bufio"
45
"bytes"
56
"context"
67
"crypto/md5"
78
"fmt"
89
"io"
10+
"io/ioutil"
911
"math/rand"
12+
"net"
13+
"net/http"
14+
"os"
15+
"path/filepath"
1016
"sort"
1117
"strings"
1218
"testing"
@@ -361,6 +367,45 @@ func TestSwarmPeers(t *testing.T) {
361367
is.Nil(err)
362368
}
363369

370+
// TestNewShellWithUnixSocket only check that http client is well configured to
371+
// perform http request on unix socket address
372+
func TestNewShellWithUnixSocket(t *testing.T) {
373+
is := is.New(t)
374+
375+
// setup uds temporary dir
376+
path, err := ioutil.TempDir("", "uds-test")
377+
is.Nil(err)
378+
379+
defer os.RemoveAll(path)
380+
381+
// listen on sock path
382+
sockpath := filepath.Join(path, "sock")
383+
lsock, err := net.Listen("unix", sockpath)
384+
is.Nil(err)
385+
386+
defer lsock.Close()
387+
388+
// handle simple `hello` route
389+
mux := http.NewServeMux()
390+
mux.HandleFunc("/api/v0/hello", func(w http.ResponseWriter, _ *http.Request) {
391+
fmt.Fprint(w, "Hello World\n")
392+
})
393+
394+
go http.Serve(lsock, mux)
395+
396+
// create shell with "/unix/<sockpath>" multiaddr
397+
shell := NewShell("/unix/" + sockpath)
398+
res, err := shell.Request("hello").Send(context.Background())
399+
is.Nil(err)
400+
401+
defer res.Output.Close()
402+
403+
// read hello world from body
404+
str, err := bufio.NewReader(res.Output).ReadString('\n')
405+
is.Nil(err)
406+
is.Equal(str, "Hello World\n")
407+
}
408+
364409
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
365410
const (
366411
letterIdxBits = 6 // 6 bits to represent a letter index

0 commit comments

Comments
 (0)