Skip to content

Commit

Permalink
Merge pull request #974 from draios/ws-proxy-path-option
Browse files Browse the repository at this point in the history
Add WS ProxyPath option
  • Loading branch information
kozlovic committed May 10, 2022
2 parents 4b259ed + 4f94f48 commit 144a3b2
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
13 changes: 13 additions & 0 deletions nats.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,10 @@ type Options struct {
// supports compression. If the server does too, then data will be compressed.
Compression bool

// For websocket connections, adds a path to connections url.
// This is useful when connecting to NATS behind a proxy.
ProxyPath string

// InboxPrefix allows the default _INBOX prefix to be customized
InboxPrefix string
}
Expand Down Expand Up @@ -1147,6 +1151,15 @@ func Compression(enabled bool) Option {
}
}

// ProxyPath is an option for websocket connections that adds a path to connections url.
// This is useful when connecting to NATS behind a proxy.
func ProxyPath(path string) Option {
return func(o *Options) error {
o.ProxyPath = path
return nil
}
}

// CustomInboxPrefix configures the request + reply inbox prefix
func CustomInboxPrefix(p string) Option {
return func(o *Options) error {
Expand Down
9 changes: 9 additions & 0 deletions ws.go
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,15 @@ func (nc *Conn) wsInitHandshake(u *url.URL) error {
scheme = "https"
}
ustr := fmt.Sprintf("%s://%s", scheme, u.Host)

if nc.Opts.ProxyPath != "" {
proxyPath := nc.Opts.ProxyPath
if !strings.HasPrefix(proxyPath, "/") {
proxyPath = "/" + proxyPath
}
ustr += proxyPath
}

u, err = url.Parse(ustr)
if err != nil {
return err
Expand Down
50 changes: 50 additions & 0 deletions ws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ package nats
import (
"bytes"
"compress/flate"
"context"
"crypto/tls"
"encoding/binary"
"fmt"
"io"
"math/rand"
"net"
"net/http"
"reflect"
"runtime"
"strings"
Expand Down Expand Up @@ -1108,3 +1111,50 @@ func TestWSNoDeadlockOnAuthFailure(t *testing.T) {

tm.Stop()
}

func TestWSProxyPath(t *testing.T) {
const proxyPath = "proxy1"

// Listen to a random port
l, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatalf("Error in listen: %v", err)
}
defer l.Close()

proxyPort := l.Addr().(*net.TCPAddr).Port

ch := make(chan struct{}, 1)
proxySrv := &http.Server{
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/"+proxyPath {
ch <- struct{}{}
}
}),
}
defer proxySrv.Shutdown(context.Background())
go proxySrv.Serve(l)

for _, test := range []struct {
name string
path string
}{
{"without slash", proxyPath},
{"with slash", "/" + proxyPath},
} {
t.Run(test.name, func(t *testing.T) {
url := fmt.Sprintf("ws://127.0.0.1:%d", proxyPort)
nc, err := Connect(url, ProxyPath(test.path))
if err == nil {
nc.Close()
t.Fatal("Did not expect to connect")
}
select {
case <-ch:
// OK:
case <-time.After(time.Second):
t.Fatal("Proxy was not reached")
}
})
}
}

0 comments on commit 144a3b2

Please sign in to comment.