Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update forwarding API #120

Merged
merged 1 commit into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.5.0

- Added new forwarding API. See `[Session].ListenAndForward` and `[Session].ListenAndServeHTTP`.
- Deprecates `WithHTTPServer` and `WithHTTPHandler`. Use `[Session].ListenAndServeHTTP` instead.

## 1.4.0

- Switch to `connect.ngrok-agent.com:443` as the default server address
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.4.1
1.5.0
12 changes: 12 additions & 0 deletions config/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,21 @@ type commonOpts struct {
ForwardsTo string
}

type CommonOptionsFunc func(cfg *commonOpts)

type CommonOption interface {
ApplyCommon(cfg *commonOpts)
}

func (of CommonOptionsFunc) ApplyCommon(cfg *commonOpts) {
of(cfg)
}

func (cfg *commonOpts) getForwardsTo() string {
if cfg.ForwardsTo == "" {
return defaultForwardsTo()
}
return cfg.ForwardsTo
}

func (cfg commonOpts) tunnelOptions() {}
58 changes: 8 additions & 50 deletions config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package config

import (
"net/http"
"reflect"
"testing"

Expand All @@ -20,14 +19,6 @@ func assertSlice[T any](opts []any) []T {
return out
}

func handlerPtr(h http.Handler) *http.Handler {
return &h
}

func serverPtr(srv *http.Server) **http.Server {
return &srv
}

func labelPtr(labels map[string]*string) *map[string]*string {
return &labels
}
Expand Down Expand Up @@ -55,16 +46,14 @@ func (m matchBindExtra) RequireMatches(t *testing.T, actual proto.BindExtra) {
}

type testCase[T tunnelConfigPrivate, O any] struct {
name string
opts Tunnel
expectForwardsTo *string
expectProto *string
expectExtra *matchBindExtra
expectLabels *map[string]*string
expectHTTPServer **http.Server
expectHTTPHandler *http.Handler
expectOpts func(t *testing.T, opts *O)
expectNilOpts bool
name string
opts Tunnel
expectForwardsTo *string
expectProto *string
expectExtra *matchBindExtra
expectLabels *map[string]*string
expectOpts func(t *testing.T, opts *O)
expectNilOpts bool
}

type testCases[T tunnelConfigPrivate, O any] []testCase[T, O]
Expand Down Expand Up @@ -101,37 +90,6 @@ func (tc testCase[T, O]) Run(t *testing.T) {
require.Truef(t, ok, "Opts has the type %v", reflect.TypeOf((*O)(nil)))
tc.expectOpts(t, opts)
}

if tc.expectHTTPServer != nil {
withHTTPServer, ok := tc.opts.(interface {
HTTPServer() *http.Server
})
if *tc.expectHTTPServer != nil {
require.True(t, ok, "opts should have the HTTPServer method")
actual := withHTTPServer.HTTPServer()
require.Equal(t, *tc.expectHTTPServer, actual)
} else if ok {
require.Nil(t, withHTTPServer.HTTPServer())
}
}

if tc.expectHTTPHandler != nil {
withHTTPServer, ok := tc.opts.(interface {
HTTPServer() *http.Server
})
if *tc.expectHTTPHandler != nil {
require.True(t, ok, "opts should have the HTTPServer method")
actualServer := withHTTPServer.HTTPServer()
require.NotNil(t, actualServer)
actual := actualServer.Handler
require.Equal(t, *tc.expectHTTPHandler, actual)
} else if ok {
actualServer := withHTTPServer.HTTPServer()
if actualServer != nil {
require.Nil(t, actualServer.Handler)
}
}
}
})
}

Expand Down
21 changes: 10 additions & 11 deletions config/forwards_to.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,32 @@ import (
"path/filepath"
)

type forwardsToOption string

// WithForwardsTo sets the ForwardsTo string for this tunnel.
// This can be veiwed via the API or dashboard.
func WithForwardsTo(meta string) interface {
HTTPEndpointOption
LabeledTunnelOption
TCPEndpointOption
TLSEndpointOption
} {
func WithForwardsTo(meta string) Options {
return forwardsToOption(meta)
}

type forwardsToOption string
func (fwd forwardsToOption) ApplyCommon(cfg *commonOpts) {
cfg.ForwardsTo = string(fwd)
}

func (fwd forwardsToOption) ApplyHTTP(cfg *httpOptions) {
cfg.commonOpts.ForwardsTo = string(fwd)
fwd.ApplyCommon(&cfg.commonOpts)
}

func (fwd forwardsToOption) ApplyTCP(cfg *tcpOptions) {
cfg.commonOpts.ForwardsTo = string(fwd)
fwd.ApplyCommon(&cfg.commonOpts)
}

func (fwd forwardsToOption) ApplyTLS(cfg *tlsOptions) {
cfg.commonOpts.ForwardsTo = string(fwd)
fwd.ApplyCommon(&cfg.commonOpts)
}

func (fwd forwardsToOption) ApplyLabeled(cfg *labeledOptions) {
cfg.commonOpts.ForwardsTo = string(fwd)
fwd.ApplyCommon(&cfg.commonOpts)
}

func defaultForwardsTo() string {
Expand Down
10 changes: 8 additions & 2 deletions config/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type httpOptions struct {

// If non-nil, start a goroutine which runs this http server
// accepting connections from the http tunnel
// Deprecated: Pass HTTP server refs via session.ListenAndServeHTTP instead.
httpServer *http.Server

// Certificates to use for client authentication at the ngrok edge.
Expand Down Expand Up @@ -121,22 +122,27 @@ func (cfg *httpOptions) toProtoConfig() *proto.HTTPEndpoint {
return opts
}

func (cfg httpOptions) tunnelOptions() {}

func (cfg httpOptions) ForwardsTo() string {
return cfg.commonOpts.getForwardsTo()
}

func (cfg httpOptions) WithForwardsTo(hostname string) {
cfg.commonOpts.ForwardsTo = hostname
}

func (cfg httpOptions) Extra() proto.BindExtra {
return proto.BindExtra{
Metadata: cfg.Metadata,
}
}

func (cfg httpOptions) Proto() string {
if cfg.Scheme == "" {
return string(SchemeHTTPS)
}
return string(cfg.Scheme)
}

func (cfg httpOptions) Opts() any {
return cfg.toProtoConfig()
}
Expand Down
28 changes: 16 additions & 12 deletions config/http_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ type httpServerOption struct {
Server *http.Server
}

type Options interface {
HTTPEndpointOption
TLSEndpointOption
TCPEndpointOption
LabeledTunnelOption
CommonOption
}

func (opt *httpServerOption) ApplyCommon(cfg *commonOpts) {

}

func (opt *httpServerOption) ApplyHTTP(cfg *httpOptions) {
cfg.httpServer = opt.Server
}
Expand All @@ -26,22 +38,14 @@ func (opt *httpServerOption) ApplyLabeled(cfg *labeledOptions) {

// WithHTTPHandler adds the provided credentials to the list of basic
// authentication credentials.
func WithHTTPHandler(h http.Handler) interface {
HTTPEndpointOption
TLSEndpointOption
TCPEndpointOption
LabeledTunnelOption
} {
// Deprecated: Use session.ListenAndHandleHTTP instead.
func WithHTTPHandler(h http.Handler) Options {
return WithHTTPServer(&http.Server{Handler: h})
}

// WithHTTPServer adds the provided credentials to the list of basic
// authentication credentials.
func WithHTTPServer(srv *http.Server) interface {
HTTPEndpointOption
TLSEndpointOption
TCPEndpointOption
LabeledTunnelOption
} {
// Deprecated: Use session.ListenAndServeHTTP instead.
func WithHTTPServer(srv *http.Server) Options {
return &httpServerOption{Server: srv}
}
50 changes: 0 additions & 50 deletions config/http_handler_test.go

This file was deleted.

11 changes: 9 additions & 2 deletions config/labeled.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type labeledOptions struct {
labels map[string]string

// An HTTP Server to run traffic on
// Deprecated: Pass HTTP server refs via session.ListenAndServeHTTP instead.
httpServer *http.Server
}

Expand All @@ -48,22 +49,28 @@ func WithLabel(label, value string) LabeledTunnelOption {
})
}

func (cfg labeledOptions) tunnelOptions() {}

func (cfg labeledOptions) ForwardsTo() string {
return cfg.commonOpts.getForwardsTo()
}

func (cfg labeledOptions) WithForwardsTo(hostname string) {
cfg.commonOpts.ForwardsTo = hostname
}

func (cfg labeledOptions) Extra() proto.BindExtra {
return proto.BindExtra{
Metadata: cfg.Metadata,
}
}

func (cfg labeledOptions) Proto() string {
return ""
}

func (cfg labeledOptions) Opts() any {
return nil
}

func (cfg labeledOptions) Labels() map[string]string {
return cfg.labels
}
Expand Down
11 changes: 9 additions & 2 deletions config/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type tcpOptions struct {
// The TCP address to request for this edge.
RemoteAddr string
// An HTTP Server to run traffic on
// Deprecated: Pass HTTP server refs via session.ListenAndServeHTTP instead.
httpServer *http.Server
}

Expand All @@ -50,22 +51,28 @@ func (cfg *tcpOptions) toProtoConfig() *proto.TCPEndpoint {
}
}

func (cfg tcpOptions) tunnelOptions() {}

func (cfg tcpOptions) ForwardsTo() string {
return cfg.commonOpts.getForwardsTo()
}

func (cfg tcpOptions) WithForwardsTo(hostname string) {
cfg.commonOpts.ForwardsTo = hostname
}

func (cfg tcpOptions) Extra() proto.BindExtra {
return proto.BindExtra{
Metadata: cfg.Metadata,
}
}

func (cfg tcpOptions) Proto() string {
return "tcp"
}

func (cfg tcpOptions) Opts() any {
return cfg.toProtoConfig()
}

func (cfg tcpOptions) Labels() map[string]string {
return nil
}
Expand Down
Loading