Skip to content

Commit

Permalink
tunnel: introduce custom Duration for time fields
Browse files Browse the repository at this point in the history
All Tunnel timeout values are based on seconds however, there isn't a great way
to do this in a flexible way with Go due to `time.Duration` not having
marshal/unmarshal support in Go 1[1]. Instead, we introduce a custom
`TunnelDuration` value here and ensure it always converts durations into
seconds without impacting other users of `time.Duration`.

[1]: golang/go#10275
  • Loading branch information
jacobbednarz committed Jun 8, 2023
1 parent bddcc22 commit 9767bb7
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .changelog/1303.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:breaking-change
tunnel: swap `ConnectTimeout`, `TLSTimeout`, `TCPKeepAlive` and `KeepAliveTimeout` to `TunnelDuration` instead of `time.Duration`
```
33 changes: 29 additions & 4 deletions tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,34 @@ import (
"errors"
"fmt"
"net/http"
"strconv"
"time"
)

// A TunnelDuration is a Duration that has custom serialization for JSON.
// JSON in Javascript assumes that int fields are 32 bits and Duration fields
// are deserialized assuming that numbers are in nanoseconds, which in 32bit
// integers limits to just 2 seconds. This type assumes that when
// serializing/deserializing from JSON, that the number is in seconds, while it
// maintains the YAML serde assumptions.
type TunnelDuration struct {
time.Duration
}

func (s TunnelDuration) MarshalJSON() ([]byte, error) {
return json.Marshal(s.Duration.Seconds())
}

func (s *TunnelDuration) UnmarshalJSON(data []byte) error {
seconds, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
return err
}

s.Duration = time.Duration(seconds * int64(time.Second))
return nil
}

// ErrMissingTunnelID is for when a required tunnel ID is missing from the
// parameters.
var ErrMissingTunnelID = errors.New("required missing tunnel ID")
Expand Down Expand Up @@ -118,17 +143,17 @@ type UnvalidatedIngressRule struct {
// config.
type OriginRequestConfig struct {
// HTTP proxy timeout for establishing a new connection
ConnectTimeout *time.Duration `json:"connectTimeout,omitempty"`
ConnectTimeout *TunnelDuration `json:"connectTimeout,omitempty"`
// HTTP proxy timeout for completing a TLS handshake
TLSTimeout *time.Duration `json:"tlsTimeout,omitempty"`
TLSTimeout *TunnelDuration `json:"tlsTimeout,omitempty"`
// HTTP proxy TCP keepalive duration
TCPKeepAlive *time.Duration `json:"tcpKeepAlive,omitempty"`
TCPKeepAlive *TunnelDuration `json:"tcpKeepAlive,omitempty"`
// HTTP proxy should disable "happy eyeballs" for IPv4/v6 fallback
NoHappyEyeballs *bool `json:"noHappyEyeballs,omitempty"`
// HTTP proxy maximum keepalive connection pool size
KeepAliveConnections *int `json:"keepAliveConnections,omitempty"`
// HTTP proxy timeout for closing an idle connection
KeepAliveTimeout *time.Duration `json:"keepAliveTimeout,omitempty"`
KeepAliveTimeout *TunnelDuration `json:"keepAliveTimeout,omitempty"`
// Sets the HTTP Host header for the local webserver.
HTTPHostHeader *string `json:"httpHostHeader,omitempty"`
// Hostname on the origin server certificate.
Expand Down
6 changes: 3 additions & 3 deletions tunnel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func TestUpdateTunnelConfiguration(t *testing.T) {
Enabled: true,
},
OriginRequest: OriginRequestConfig{
ConnectTimeout: DurationPtr(10),
ConnectTimeout: &TunnelDuration{10},
},
}}

Expand All @@ -233,7 +233,7 @@ func TestUpdateTunnelConfiguration(t *testing.T) {
Enabled: true,
},
OriginRequest: OriginRequestConfig{
ConnectTimeout: DurationPtr(10 * time.Second),
ConnectTimeout: &TunnelDuration{10},
},
},
})
Expand Down Expand Up @@ -275,7 +275,7 @@ func TestGetTunnelConfiguration(t *testing.T) {
Enabled: true,
},
OriginRequest: OriginRequestConfig{
ConnectTimeout: DurationPtr(10),
ConnectTimeout: &TunnelDuration{10},
},
}}

Expand Down

0 comments on commit 9767bb7

Please sign in to comment.