-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ws_reverseproxy): add OptionWS for ws_reverseproxy
- Loading branch information
Showing
8 changed files
with
345 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package proxy | ||
|
||
import ( | ||
"errors" | ||
"net/http" | ||
"net/url" | ||
|
||
"github.com/fasthttp/websocket" | ||
"github.com/valyala/fasthttp" | ||
) | ||
|
||
// OptionWS to define all options to reverse web socket proxy. | ||
type OptionWS interface { | ||
apply(o *buildOptionWS) | ||
} | ||
|
||
type funcBuildOptionWS struct { | ||
f func(o *buildOptionWS) | ||
} | ||
|
||
func newFuncBuildOptionWS(f func(o *buildOptionWS)) funcBuildOptionWS { return funcBuildOptionWS{f: f} } | ||
func (fb funcBuildOptionWS) apply(o *buildOptionWS) { fb.f(o) } | ||
|
||
type forwardHeaderHandler func(ctx *fasthttp.RequestCtx) (forwardHeader http.Header) | ||
|
||
// buildOptionWS is Option for WS reverse-proxy | ||
type buildOptionWS struct { | ||
// target indicates which backend server to proxy. | ||
target *url.URL | ||
|
||
// fn is forwardHeaderHandler which allows users customize themselves' forward headers | ||
// to be proxied to backend server. | ||
fn forwardHeaderHandler | ||
|
||
// dialer contains options for connecting to the backend WebSocket server. | ||
// If nil, DefaultDialer is used. | ||
dialer *websocket.Dialer | ||
|
||
// upgrader specifies the parameters for upgrading a incoming HTTP | ||
// connection to a WebSocket connection. If nil, DefaultUpgrader is used. | ||
upgrader *websocket.FastHTTPUpgrader | ||
} | ||
|
||
func (o *buildOptionWS) validate() error { | ||
if o == nil { | ||
return errors.New("option is nil") | ||
} | ||
|
||
if o.target == nil { | ||
return errors.New("target is nil") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func defaultBuildOptionWS() *buildOptionWS { | ||
return &buildOptionWS{ | ||
target: nil, | ||
fn: nil, | ||
dialer: nil, | ||
upgrader: nil, | ||
} | ||
} | ||
|
||
// WithURL_OptionWS specify the url to backend websocket server. | ||
// WithURL_OptionWS("ws://YOUR_WEBSOCKET_HOST:PORT/AND/PATH") | ||
func WithURL_OptionWS(u string) OptionWS { | ||
return newFuncBuildOptionWS(func(o *buildOptionWS) { | ||
URL, err := url.Parse(u) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
o.target = URL | ||
}) | ||
} | ||
|
||
// WithDialer_OptionWS use specified dialer | ||
func WithDialer_OptionWS(dialer *websocket.Dialer) OptionWS { | ||
return newFuncBuildOptionWS(func(o *buildOptionWS) { | ||
o.dialer = dialer | ||
}) | ||
} | ||
|
||
// WithUpgrader_OptionWS use specified upgrader. | ||
func WithUpgrader_OptionWS(upgrader *websocket.FastHTTPUpgrader) OptionWS { | ||
return newFuncBuildOptionWS(func(o *buildOptionWS) { | ||
o.upgrader = upgrader | ||
}) | ||
} | ||
|
||
// WithForwardHeadersHandlers_OptionWS allows users to customize forward headers. | ||
func WithForwardHeadersHandlers_OptionWS(handler forwardHeaderHandler) OptionWS { | ||
return newFuncBuildOptionWS(func(o *buildOptionWS) { | ||
o.fn = handler | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package proxy | ||
|
||
import ( | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/valyala/fasthttp" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func Test_defaultBuildOptionWS(t *testing.T) { | ||
dst := defaultBuildOptionWS() | ||
|
||
assert.Nil(t, dst.target) | ||
assert.Nil(t, dst.dialer) | ||
assert.Nil(t, dst.upgrader) | ||
} | ||
|
||
func Test_WithURL_OptionWS(t *testing.T) { | ||
assert.NotPanics(t, func() { | ||
WithURL_OptionWS("ws://localhost:8080/path") | ||
}, "could not panic") | ||
|
||
dst := defaultBuildOptionWS() | ||
WithURL_OptionWS("ws://localhost:8080/path").apply(dst) | ||
assert.NotNil(t, dst.target) | ||
assert.Equal(t, "ws", dst.target.Scheme) | ||
assert.Equal(t, "localhost:8080", dst.target.Host) | ||
assert.Equal(t, "8080", dst.target.Port()) | ||
assert.Equal(t, "/path", dst.target.Path) | ||
} | ||
|
||
func Test_WithForwardHeadersHandlers_OptionWS(t *testing.T) { | ||
dst := defaultBuildOptionWS() | ||
WithForwardHeadersHandlers_OptionWS(func(reqHeader *fasthttp.RequestCtx) (forwardHeader http.Header) { | ||
return http.Header{ | ||
"X-Test": []string{"X-Test"}, | ||
} | ||
}).apply(dst) | ||
assert.NotNil(t, dst.fn) | ||
} |
Oops, something went wrong.