Skip to content

Commit

Permalink
refactor(netxlite): expose useful HTTPTransport factories
Browse files Browse the repository at this point in the history
These factories will soon be useful to finish with
ooni/probe#2135.
  • Loading branch information
bassosimone committed Jun 8, 2022
1 parent 1a706e4 commit 65ffabf
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 26 deletions.
8 changes: 3 additions & 5 deletions internal/engine/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,9 @@ func NewSession(ctx context.Context, config SessionConfig) (*Session, error) {
Logger: sess.logger,
ProxyURL: proxyURL,
}
dialer := netxlite.NewDialerWithResolver(sess.logger, sess.resolver)
dialer = netxlite.MaybeWrapWithProxyDialer(dialer, proxyURL)
handshaker := netxlite.NewTLSHandshakerStdlib(sess.logger)
tlsDialer := netxlite.NewTLSDialer(dialer, handshaker)
txp := netxlite.NewHTTPTransport(sess.logger, dialer, tlsDialer)
txp := netxlite.NewHTTPTransportWithLoggerResolverAndOptionalProxyURL(
sess.logger, sess.resolver, sess.proxyURL,
)
txp = bytecounter.WrapHTTPTransport(txp, sess.byteCounter)
sess.httpDefaultTransport = txp
return sess, nil
Expand Down
20 changes: 20 additions & 0 deletions internal/netxlite/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"net"
"net/http"
"net/url"
"time"

oohttp "github.com/ooni/oohttp"
Expand Down Expand Up @@ -105,6 +106,25 @@ func (txp *httpTransportConnectionsCloser) CloseIdleConnections() {
txp.TLSDialer.CloseIdleConnections()
}

// NewHTTPTransportWithLoggerResolverAndOptionalProxyURL creates HTTP transport using the
// given logger and resolver and an optional proxy URL.
//
// Arguments:
//
// - logger is the MANDATORY logger;
//
// - resolver is the MANDATORY resolver;
//
// - purl is the OPTIONAL proxy URL.
func NewHTTPTransportWithLoggerResolverAndOptionalProxyURL(
logger model.DebugLogger, resolver model.Resolver, purl *url.URL) model.HTTPTransport {
dialer := NewDialerWithResolver(logger, resolver)
dialer = MaybeWrapWithProxyDialer(dialer, purl)
handshaker := NewTLSHandshakerStdlib(logger)
tlsDialer := NewTLSDialer(dialer, handshaker)
return NewHTTPTransport(logger, dialer, tlsDialer)
}

// NewHTTPTransportWithResolver creates a new HTTP transport using
// the stdlib for everything but the given resolver.
func NewHTTPTransportWithResolver(logger model.DebugLogger, reso model.Resolver) model.HTTPTransport {
Expand Down
9 changes: 9 additions & 0 deletions internal/netxlite/http3.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,12 @@ func NewHTTP3Transport(
dialer: dialer,
})
}

// NewHTTP3TransportStdlib creates a new HTTPTransport using http3 that
// uses standard functionality for everything but the logger.
func NewHTTP3TransportStdlib(logger model.DebugLogger) model.HTTPTransport {
ql := NewQUICListener()
reso := NewStdlibResolver(logger)
qd := NewQUICDialerWithResolver(ql, logger, reso)
return NewHTTP3Transport(logger, qd, nil)
}
54 changes: 33 additions & 21 deletions internal/netxlite/http3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"net/http"
"testing"

"github.com/apex/log"
"github.com/lucas-clemente/quic-go/http3"
"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/model/mocks"
nlmocks "github.com/ooni/probe-cli/v3/internal/netxlite/mocks"
)
Expand Down Expand Up @@ -63,29 +63,41 @@ func TestHTTP3Transport(t *testing.T) {
})
}

func verifyTypeChainForHTTP3(t *testing.T, txp model.HTTPTransport,
underlyingLogger model.DebugLogger, qd model.QUICDialer, config *tls.Config) {
logger := txp.(*httpTransportLogger)
if logger.Logger != underlyingLogger {
t.Fatal("invalid logger")
}
ew := logger.HTTPTransport.(*httpTransportErrWrapper)
h3txp := ew.HTTPTransport.(*http3Transport)
if qd != nil && h3txp.dialer != qd {
t.Fatal("invalid dialer")
}
h3 := h3txp.child.(*http3.RoundTripper)
if h3.Dial == nil {
t.Fatal("invalid Dial")
}
if !h3.DisableCompression {
t.Fatal("invalid DisableCompression")
}
if h3.TLSClientConfig != config {
t.Fatal("invalid TLSClientConfig")
}
}

func TestNewHTTP3Transport(t *testing.T) {
t.Run("creates the correct type chain", func(t *testing.T) {
qd := &mocks.QUICDialer{}
config := &tls.Config{}
txp := NewHTTP3Transport(log.Log, qd, config)
logger := txp.(*httpTransportLogger)
if logger.Logger != log.Log {
t.Fatal("invalid logger")
}
ew := logger.HTTPTransport.(*httpTransportErrWrapper)
h3txp := ew.HTTPTransport.(*http3Transport)
if h3txp.dialer != qd {
t.Fatal("invalid dialer")
}
h3 := h3txp.child.(*http3.RoundTripper)
if h3.Dial == nil {
t.Fatal("invalid Dial")
}
if !h3.DisableCompression {
t.Fatal("invalid DisableCompression")
}
if h3.TLSClientConfig != config {
t.Fatal("invalid TLSClientConfig")
}
txp := NewHTTP3Transport(model.DiscardLogger, qd, config)
verifyTypeChainForHTTP3(t, txp, model.DiscardLogger, qd, config)
})
}

func TestNewHTTP3TransportStdlib(t *testing.T) {
t.Run("creates the correct type chain", func(t *testing.T) {
txp := NewHTTP3TransportStdlib(model.DiscardLogger)
verifyTypeChainForHTTP3(t, txp, model.DiscardLogger, nil, nil)
})
}
43 changes: 43 additions & 0 deletions internal/netxlite/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"net"
"net/http"
"net/url"
"strings"
"testing"
"time"
Expand All @@ -16,6 +17,48 @@ import (
"github.com/ooni/probe-cli/v3/internal/model/mocks"
)

func TestNewHTTPTransportWithLoggerResolverAndOptionalProxyURL(t *testing.T) {
t.Run("without proxy URL", func(t *testing.T) {
logger := &mocks.Logger{}
resolver := &mocks.Resolver{}
txp := NewHTTPTransportWithLoggerResolverAndOptionalProxyURL(logger, resolver, nil)
txpLogger := txp.(*httpTransportLogger)
if txpLogger.Logger != logger {
t.Fatal("unexpected logger")
}
txpErrWrapper := txpLogger.HTTPTransport.(*httpTransportErrWrapper)
txpCc := txpErrWrapper.HTTPTransport.(*httpTransportConnectionsCloser)
dialer := txpCc.Dialer
dialerWithReadTimeout := dialer.(*httpDialerWithReadTimeout)
dialerLog := dialerWithReadTimeout.Dialer.(*dialerLogger)
dialerReso := dialerLog.Dialer.(*dialerResolver)
if dialerReso.Resolver != resolver {
t.Fatal("invalid resolver")
}
})

t.Run("with proxy URL", func(t *testing.T) {
URL := &url.URL{}
logger := &mocks.Logger{}
resolver := &mocks.Resolver{}
txp := NewHTTPTransportWithLoggerResolverAndOptionalProxyURL(logger, resolver, URL)
txpLogger := txp.(*httpTransportLogger)
if txpLogger.Logger != logger {
t.Fatal("unexpected logger")
}
txpErrWrapper := txpLogger.HTTPTransport.(*httpTransportErrWrapper)
txpCc := txpErrWrapper.HTTPTransport.(*httpTransportConnectionsCloser)
dialer := txpCc.Dialer
dialerWithReadTimeout := dialer.(*httpDialerWithReadTimeout)
dialerProxy := dialerWithReadTimeout.Dialer.(*proxyDialer)
dialerLog := dialerProxy.Dialer.(*dialerLogger)
dialerReso := dialerLog.Dialer.(*dialerResolver)
if dialerReso.Resolver != resolver {
t.Fatal("invalid resolver")
}
})
}

func TestNewHTTPTransportWithResolver(t *testing.T) {
expected := errors.New("mocked error")
reso := &mocks.Resolver{
Expand Down

0 comments on commit 65ffabf

Please sign in to comment.