Skip to content
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
18 changes: 12 additions & 6 deletions internal/provider/localtunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"net"
"net/http"
"strconv"
"sync"
"time"

Expand All @@ -20,6 +21,11 @@ const (
// maximum concurrent connections allowed for us,
// override if tunnel api sends their limit
clientMaxConn = 10

httpClientTimeout = 10 * time.Second
tcpDialTimeout = 10 * time.Second
localDialTimeOut = 4 * time.Second
proxyDeadlineTimeOut = 30 * time.Second
)

// localTunnel implements the Provider interface for localtunnel.me
Expand Down Expand Up @@ -55,7 +61,7 @@ type TunnelInfo struct {
// NewLocalTunnel creates a new localTunnel provider instance.
func NewLocalTunnel(httpClient *http.Client) tunnel.Provider {
if httpClient == nil {
httpClient = http.DefaultClient
httpClient = &http.Client{Timeout: httpClientTimeout}
}

return &localTunnel{
Expand Down Expand Up @@ -172,9 +178,9 @@ func (lt *localTunnel) openConnections() error {

// dialTunnel creates a single TCP connection to the localtunnel server.
func (lt *localTunnel) dialTunnel() (net.Conn, error) {
// TODO: give IPv6 support here using net.JoinHostPort later
address := fmt.Sprintf("%s:%d", lt.tunnelHost, lt.tunnelPort)
conn, err := net.DialTimeout("tcp", address, 10*time.Second)
address := net.JoinHostPort(lt.tunnelHost, strconv.Itoa(lt.tunnelPort)) //IPv6 safe
conn, err := net.DialTimeout("tcp", address, localDialTimeOut)

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -230,8 +236,8 @@ func (lt *localTunnel) proxyRequest(tunnelConn net.Conn) error {

// Set deadlines, it helps to avoid hanging connections
// e.g: if either side doesn't respond in time, the copy will end
_ = tunnelConn.SetDeadline(time.Now().Add(30 * time.Second))
_ = localConn.SetDeadline(time.Now().Add(30 * time.Second))
_ = tunnelConn.SetDeadline(time.Now().Add(proxyDeadlineTimeOut))
_ = localConn.SetDeadline(time.Now().Add(proxyDeadlineTimeOut))

// Start bidirectional copy
// mental model: copy(blocking ops) the data from tunnel to local and
Expand Down
2 changes: 1 addition & 1 deletion internal/provider/localtunnel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func Test_NewLocalTunnel(t *testing.T) {
t.Fatal("expected default httpClient, got nil")
}

if lt.httpClient.Timeout != http.DefaultClient.Timeout {
if lt.httpClient.Timeout != httpClientTimeout {
t.Errorf("expected %v timeout, got %v", http.DefaultClient.Timeout, lt.httpClient.Timeout)
}

Expand Down