@ -5,14 +5,21 @@ package captivedetection
import (
import (
"context"
"context"
"net/http"
"net/http/httptest"
"net/url"
"runtime"
"runtime"
"strconv"
"sync"
"sync"
"sync/atomic"
"sync/atomic"
"testing"
"testing"
"time"
"tailscale.com/derp/derphttp"
"tailscale.com/net/netmon"
"tailscale.com/net/netmon"
"tailscale.com/syncs"
"tailscale.com/syncs"
"tailscale.com/tstest/nettest"
"tailscale.com/tstest/nettest"
"tailscale.com/util/must"
)
)
func TestAvailableEndpointsAlwaysAtLeastTwo ( t * testing . T ) {
func TestAvailableEndpointsAlwaysAtLeastTwo ( t * testing . T ) {
@ -81,3 +88,67 @@ func TestEndpointsAreUpAndReturnExpectedResponse(t *testing.T) {
t . Errorf ( "no good endpoints found" )
t . Errorf ( "no good endpoints found" )
}
}
}
}
func TestCaptivePortalRequest ( t * testing . T ) {
d := NewDetector ( t . Logf )
now := time . Now ( )
d . clock = func ( ) time . Time { return now }
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
s := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
if r . Method != "GET" {
t . Errorf ( "expected GET, got %q" , r . Method )
}
if r . URL . Path != "/generate_204" {
t . Errorf ( "expected /generate_204, got %q" , r . URL . Path )
}
q := r . URL . Query ( )
if got , want := q . Get ( "t" ) , strconv . Itoa ( int ( now . Unix ( ) ) ) ; got != want {
t . Errorf ( "timestamp param; got %v, want %v" , got , want )
}
w . Header ( ) . Set ( "X-Tailscale-Response" , "response " + r . Header . Get ( "X-Tailscale-Challenge" ) )
w . WriteHeader ( http . StatusNoContent )
} ) )
defer s . Close ( )
e := Endpoint {
URL : must . Get ( url . Parse ( s . URL + "/generate_204" ) ) ,
StatusCode : 204 ,
ExpectedContent : "" ,
SupportsTailscaleChallenge : true ,
}
found , err := d . verifyCaptivePortalEndpoint ( ctx , e , 0 )
if err != nil {
t . Fatalf ( "verifyCaptivePortalEndpoint = %v, %v" , found , err )
}
if found {
t . Errorf ( "verifyCaptivePortalEndpoint = %v, want false" , found )
}
}
func TestAgainstDERPHandler ( t * testing . T ) {
d := NewDetector ( t . Logf )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
s := httptest . NewServer ( http . HandlerFunc ( derphttp . ServeNoContent ) )
defer s . Close ( )
e := Endpoint {
URL : must . Get ( url . Parse ( s . URL + "/generate_204" ) ) ,
StatusCode : 204 ,
ExpectedContent : "" ,
SupportsTailscaleChallenge : true ,
}
found , err := d . verifyCaptivePortalEndpoint ( ctx , e , 0 )
if err != nil {
t . Fatalf ( "verifyCaptivePortalEndpoint = %v, %v" , found , err )
}
if found {
t . Errorf ( "verifyCaptivePortalEndpoint = %v, want false" , found )
}
}