Skip to content

Commit 5974fb4

Browse files
committed
TUN-3500: Integrate replace h2mux by http2 work with multiple origin support
1 parent eef5b78 commit 5974fb4

File tree

16 files changed

+251
-715
lines changed

16 files changed

+251
-715
lines changed

cmd/cloudflared/config/configuration.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ func ValidateUnixSocket(c *cli.Context) (string, error) {
190190

191191
// ValidateUrl will validate url flag correctness. It can be either from --url or argument
192192
// Notice ValidateUnixSocket, it will enforce --unix-socket is not used with --url or argument
193-
func ValidateUrl(c *cli.Context, allowFromArgs bool) (*url.URL, error) {
193+
func ValidateUrl(c *cli.Context, allowURLFromArgs bool) (*url.URL, error) {
194194
var url = c.String("url")
195-
if allowFromArgs && c.NArg() > 0 {
195+
if allowURLFromArgs && c.NArg() > 0 {
196196
if c.IsSet("url") {
197197
return nil, errors.New("Specified origin urls using both --url and argument. Decide which one you want, I can only support one.")
198198
}

cmd/cloudflared/tunnel/cmd.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,12 @@ func StartServer(
367367
return errors.Wrap(err, "error setting up transport logger")
368368
}
369369

370-
tunnelConfig, err := prepareTunnelConfig(c, buildInfo, version, log, transportLogger, namedTunnel, isUIEnabled)
370+
tunnelConfig, ingressRules, err := prepareTunnelConfig(c, buildInfo, version, log, transportLogger, namedTunnel, isUIEnabled)
371371
if err != nil {
372372
return err
373373
}
374374

375-
tunnelConfig.IngressRules.StartOrigins(&wg, log, shutdownC, errC)
375+
ingressRules.StartOrigins(&wg, log, shutdownC, errC)
376376

377377
reconnectCh := make(chan origin.ReconnectSignal, 1)
378378
if c.IsSet("stdin-control") {
@@ -391,8 +391,7 @@ func StartServer(
391391
version,
392392
hostname,
393393
metricsListener.Addr().String(),
394-
// TODO (TUN-3461): Update UI to show multiple origin URLs
395-
&tunnelConfig.IngressRules,
394+
&ingressRules,
396395
tunnelConfig.HAConnections,
397396
)
398397
logLevels, err := logger.ParseLevelString(c.String("loglevel"))

cmd/cloudflared/tunnel/configuration.go

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tunnel
22

33
import (
4+
"crypto/tls"
45
"fmt"
56
"io/ioutil"
67
"os"
@@ -160,27 +161,27 @@ func prepareTunnelConfig(
160161
transportLogger logger.Service,
161162
namedTunnel *connection.NamedTunnelConfig,
162163
uiIsEnabled bool,
163-
) (*origin.TunnelConfig, error) {
164+
) (*origin.TunnelConfig, ingress.Ingress, error) {
164165
isNamedTunnel := namedTunnel != nil
165166

166167
hostname, err := validation.ValidateHostname(c.String("hostname"))
167168
if err != nil {
168169
logger.Errorf("Invalid hostname: %s", err)
169-
return nil, errors.Wrap(err, "Invalid hostname")
170+
return nil, ingress.Ingress{}, errors.Wrap(err, "Invalid hostname")
170171
}
171172
isFreeTunnel := hostname == ""
172173
clientID := c.String("id")
173174
if !c.IsSet("id") {
174175
clientID, err = generateRandomClientID(logger)
175176
if err != nil {
176-
return nil, err
177+
return nil, ingress.Ingress{}, err
177178
}
178179
}
179180

180181
tags, err := NewTagSliceFromCLI(c.StringSlice("tag"))
181182
if err != nil {
182183
logger.Errorf("Tag parse failure: %s", err)
183-
return nil, errors.Wrap(err, "Tag parse failure")
184+
return nil, ingress.Ingress{}, errors.Wrap(err, "Tag parse failure")
184185
}
185186

186187
tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID})
@@ -189,7 +190,7 @@ func prepareTunnelConfig(
189190
if !isFreeTunnel {
190191
originCert, err = getOriginCert(c, logger)
191192
if err != nil {
192-
return nil, errors.Wrap(err, "Error getting origin cert")
193+
return nil, ingress.Ingress{}, errors.Wrap(err, "Error getting origin cert")
193194
}
194195
}
195196

@@ -200,7 +201,7 @@ func prepareTunnelConfig(
200201
if isNamedTunnel {
201202
clientUUID, err := uuid.NewRandom()
202203
if err != nil {
203-
return nil, errors.Wrap(err, "can't generate clientUUID")
204+
return nil, ingress.Ingress{}, errors.Wrap(err, "can't generate clientUUID")
204205
}
205206
namedTunnel.Client = tunnelpogs.ClientInfo{
206207
ClientID: clientUUID[:],
@@ -210,10 +211,10 @@ func prepareTunnelConfig(
210211
}
211212
ingressRules, err = ingress.ParseIngress(config.GetConfiguration())
212213
if err != nil && err != ingress.ErrNoIngressRules {
213-
return nil, err
214+
return nil, ingress.Ingress{}, err
214215
}
215216
if !ingressRules.IsEmpty() && c.IsSet("url") {
216-
return nil, ingress.ErrURLIncompatibleWithIngress
217+
return nil, ingress.Ingress{}, ingress.ErrURLIncompatibleWithIngress
217218
}
218219
} else {
219220
classicTunnel = &connection.ClassicTunnelConfig{
@@ -226,36 +227,28 @@ func prepareTunnelConfig(
226227

227228
// Convert single-origin configuration into multi-origin configuration.
228229
if ingressRules.IsEmpty() {
229-
ingressRules, err = ingress.NewSingleOrigin(c, compatibilityMode, logger)
230+
ingressRules, err = ingress.NewSingleOrigin(c, !isNamedTunnel, logger)
230231
if err != nil {
231-
return nil, err
232+
return nil, ingress.Ingress{}, err
232233
}
233234
}
234235

235236
protocolSelector, err := connection.NewProtocolSelector(c.String("protocol"), namedTunnel, edgediscovery.HTTP2Percentage, origin.ResolveTTL, logger)
236237
if err != nil {
237-
return nil, err
238+
return nil, ingress.Ingress{}, err
238239
}
239240
logger.Infof("Initial protocol %s", protocolSelector.Current())
240241

241242
edgeTLSConfigs := make(map[connection.Protocol]*tls.Config, len(connection.ProtocolList))
242243
for _, p := range connection.ProtocolList {
243244
edgeTLSConfig, err := tlsconfig.CreateTunnelConfig(c, p.ServerName())
244245
if err != nil {
245-
return nil, errors.Wrap(err, "unable to create TLS config to connect with edge")
246+
return nil, ingress.Ingress{}, errors.Wrap(err, "unable to create TLS config to connect with edge")
246247
}
247248
edgeTLSConfigs[p] = edgeTLSConfig
248249
}
249250

250-
proxyConfig := &origin.ProxyConfig{
251-
Client: httpTransport,
252-
URL: originURL,
253-
TLSConfig: httpTransport.TLSClientConfig,
254-
HostHeader: c.String("http-host-header"),
255-
NoChunkedEncoding: c.Bool("no-chunked-encoding"),
256-
Tags: tags,
257-
}
258-
originClient := origin.NewClient(proxyConfig, logger)
251+
originClient := origin.NewClient(ingressRules, tags, logger)
259252
connectionConfig := &connection.Config{
260253
OriginClient: originClient,
261254
GracePeriod: c.Duration("grace-period"),
@@ -275,7 +268,6 @@ func prepareTunnelConfig(
275268

276269
return &origin.TunnelConfig{
277270
ConnectionConfig: connectionConfig,
278-
ProxyConfig: proxyConfig,
279271
BuildInfo: buildInfo,
280272
ClientID: clientID,
281273
EdgeAddrs: c.StringSlice("edge"),
@@ -284,6 +276,7 @@ func prepareTunnelConfig(
284276
IsAutoupdated: c.Bool("is-autoupdated"),
285277
IsFreeTunnel: isFreeTunnel,
286278
LBPool: c.String("lb-pool"),
279+
Tags: tags,
287280
Logger: logger,
288281
Observer: connection.NewObserver(transportLogger, tunnelEventChan),
289282
ReportedVersion: version,
@@ -293,10 +286,9 @@ func prepareTunnelConfig(
293286
ClassicTunnel: classicTunnel,
294287
MuxerConfig: muxerConfig,
295288
TunnelEventChan: tunnelEventChan,
296-
IngressRules: ingressRules,
297289
ProtocolSelector: protocolSelector,
298290
EdgeTLSConfigs: edgeTLSConfigs,
299-
}, nil
291+
}, ingressRules, nil
300292
}
301293

302294
func isRunningFromTerminal() bool {

connection/h2mux.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const (
2222
type h2muxConnection struct {
2323
config *Config
2424
muxerConfig *MuxerConfig
25-
originURL string
2625
muxer *h2mux.Muxer
2726
// connectionID is only used by metrics, and prometheus requires labels to be string
2827
connIndexStr string
@@ -54,15 +53,13 @@ func (mc *MuxerConfig) H2MuxerConfig(h h2mux.MuxedStreamHandler, logger logger.S
5453
func NewH2muxConnection(ctx context.Context,
5554
config *Config,
5655
muxerConfig *MuxerConfig,
57-
originURL string,
5856
edgeConn net.Conn,
5957
connIndex uint8,
6058
observer *Observer,
6159
) (*h2muxConnection, error, bool) {
6260
h := &h2muxConnection{
6361
config: config,
6462
muxerConfig: muxerConfig,
65-
originURL: originURL,
6663
connIndexStr: uint8ToString(connIndex),
6764
connIndex: connIndex,
6865
observer: observer,
@@ -188,7 +185,7 @@ func (h *h2muxConnection) ServeStream(stream *h2mux.MuxedStream) error {
188185
}
189186

190187
func (h *h2muxConnection) newRequest(stream *h2mux.MuxedStream) (*http.Request, error) {
191-
req, err := http.NewRequest("GET", h.originURL, h2mux.MuxedStreamReader{MuxedStream: stream})
188+
req, err := http.NewRequest("GET", "http://localhost:8080", h2mux.MuxedStreamReader{MuxedStream: stream})
192189
if err != nil {
193190
return nil, errors.Wrap(err, "Unexpected error from http.NewRequest")
194191
}

connection/http2.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"math"
88
"net"
99
"net/http"
10-
"net/url"
1110
"strings"
1211
"sync"
1312

@@ -31,7 +30,6 @@ type HTTP2Connection struct {
3130
conn net.Conn
3231
server *http2.Server
3332
config *Config
34-
originURL *url.URL
3533
namedTunnel *NamedTunnelConfig
3634
connOptions *tunnelpogs.ConnectionOptions
3735
observer *Observer
@@ -44,7 +42,6 @@ type HTTP2Connection struct {
4442
func NewHTTP2Connection(
4543
conn net.Conn,
4644
config *Config,
47-
originURL *url.URL,
4845
namedTunnelConfig *NamedTunnelConfig,
4946
connOptions *tunnelpogs.ConnectionOptions,
5047
observer *Observer,
@@ -57,7 +54,6 @@ func NewHTTP2Connection(
5754
MaxConcurrentStreams: math.MaxUint32,
5855
},
5956
config: config,
60-
originURL: originURL,
6157
namedTunnel: namedTunnelConfig,
6258
connOptions: connOptions,
6359
observer: observer,
@@ -83,9 +79,6 @@ func (c *HTTP2Connection) ServeHTTP(w http.ResponseWriter, r *http.Request) {
8379
c.wg.Add(1)
8480
defer c.wg.Done()
8581

86-
r.URL.Scheme = c.originURL.Scheme
87-
r.URL.Host = c.originURL.Host
88-
8982
respWriter := &http2RespWriter{
9083
r: r.Body,
9184
w: w,

hello/hello.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const (
2222
UptimeRoute = "/uptime"
2323
WSRoute = "/ws"
2424
SSERoute = "/sse"
25+
HealthRoute = "/_health"
2526
defaultSSEFreq = time.Second * 10
2627
)
2728

@@ -114,6 +115,7 @@ func StartHelloWorldServer(logger logger.Service, listener net.Listener, shutdow
114115
muxer.HandleFunc(UptimeRoute, uptimeHandler(time.Now()))
115116
muxer.HandleFunc(WSRoute, websocketHandler(logger, upgrader))
116117
muxer.HandleFunc(SSERoute, sseHandler(logger))
118+
muxer.HandleFunc(HealthRoute, healthHandler())
117119
muxer.HandleFunc("/", rootHandler(serverName))
118120
httpServer := &http.Server{Addr: listener.Addr().String(), Handler: muxer}
119121
go func() {
@@ -221,6 +223,12 @@ func sseHandler(logger logger.Service) http.HandlerFunc {
221223
}
222224
}
223225

226+
func healthHandler() http.HandlerFunc {
227+
return func(w http.ResponseWriter, r *http.Request) {
228+
w.Write([]byte("ok"))
229+
}
230+
}
231+
224232
func rootHandler(serverName string) http.HandlerFunc {
225233
responseTemplate := template.Must(template.New("index").Parse(indexTemplate))
226234
return func(w http.ResponseWriter, r *http.Request) {

ingress/ingress.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ type Ingress struct {
6363

6464
// NewSingleOrigin constructs an Ingress set with only one rule, constructed from
6565
// legacy CLI parameters like --url or --no-chunked-encoding.
66-
func NewSingleOrigin(c *cli.Context, compatibilityMode bool, logger logger.Service) (Ingress, error) {
66+
func NewSingleOrigin(c *cli.Context, allowURLFromArgs bool, logger logger.Service) (Ingress, error) {
6767

68-
service, err := parseSingleOriginService(c, compatibilityMode)
68+
service, err := parseSingleOriginService(c, allowURLFromArgs)
6969
if err != nil {
7070
return Ingress{}, err
7171
}
@@ -85,19 +85,15 @@ func NewSingleOrigin(c *cli.Context, compatibilityMode bool, logger logger.Servi
8585
}
8686

8787
// Get a single origin service from the CLI/config.
88-
func parseSingleOriginService(c *cli.Context, compatibilityMode bool) (OriginService, error) {
88+
func parseSingleOriginService(c *cli.Context, allowURLFromArgs bool) (OriginService, error) {
8989
if c.IsSet("hello-world") {
9090
return new(helloWorld), nil
9191
}
9292
if c.IsSet("url") {
93-
originURLStr, err := config.ValidateUrl(c, compatibilityMode)
93+
originURL, err := config.ValidateUrl(c, allowURLFromArgs)
9494
if err != nil {
9595
return nil, errors.Wrap(err, "Error validating origin URL")
9696
}
97-
originURL, err := url.Parse(originURLStr)
98-
if err != nil {
99-
return nil, errors.Wrap(err, "couldn't parse origin URL")
100-
}
10197
return &localService{URL: originURL, RootURL: originURL}, nil
10298
}
10399
if c.IsSet("unix-socket") {

ingress/origin_service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ type statusCode struct {
245245
func newStatusCode(status int) statusCode {
246246
resp := &http.Response{
247247
StatusCode: status,
248-
Status: http.StatusText(status),
248+
Status: fmt.Sprintf("%d %s", status, http.StatusText(status)),
249249
Body: new(NopReadCloser),
250250
}
251251
return statusCode{resp: resp}

0 commit comments

Comments
 (0)