2017-08-01 19:32:44 +02:00
package integration
2017-07-25 16:56:46 +02:00
import (
2017-09-06 09:36:02 +02:00
"crypto/tls"
"crypto/x509"
"io/ioutil"
2017-08-01 15:24:08 +02:00
"net"
"net/http"
"net/http/httptest"
2017-07-25 16:56:46 +02:00
"os"
2017-08-01 15:24:08 +02:00
"time"
2017-07-25 16:56:46 +02:00
2017-08-01 19:32:44 +02:00
"github.com/containous/traefik/integration/try"
2017-08-01 15:24:08 +02:00
"github.com/go-check/check"
gorillawebsocket "github.com/gorilla/websocket"
2017-07-25 16:56:46 +02:00
checker "github.com/vdemeester/shakers"
2017-08-01 15:24:08 +02:00
"golang.org/x/net/websocket"
2017-07-25 16:56:46 +02:00
)
// WebsocketSuite
type WebsocketSuite struct { BaseSuite }
func ( suite * WebsocketSuite ) TestBase ( c * check . C ) {
2017-08-01 15:24:08 +02:00
var upgrader = gorillawebsocket . Upgrader { } // use default options
2017-07-25 16:56:46 +02:00
srv := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
c , err := upgrader . Upgrade ( w , r , nil )
if err != nil {
return
}
defer c . Close ( )
for {
mt , message , err := c . ReadMessage ( )
if err != nil {
break
}
err = c . WriteMessage ( mt , message )
if err != nil {
break
}
}
} ) )
file := suite . adaptFile ( c , "fixtures/websocket/config.toml" , struct {
WebsocketServer string
} {
WebsocketServer : srv . URL ,
} )
defer os . Remove ( file )
cmd , _ := suite . cmdTraefik ( withConfigFile ( file ) , "--debug" )
err := cmd . Start ( )
c . Assert ( err , check . IsNil )
defer cmd . Process . Kill ( )
// wait for traefik
2017-08-01 19:32:44 +02:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/providers" , 10 * time . Second , try . BodyContains ( "127.0.0.1" ) )
2017-07-25 16:56:46 +02:00
c . Assert ( err , checker . IsNil )
2017-08-01 15:24:08 +02:00
conn , _ , err := gorillawebsocket . DefaultDialer . Dial ( "ws://127.0.0.1:8000/ws" , nil )
2017-08-18 02:18:02 +02:00
c . Assert ( err , checker . IsNil )
2017-07-25 16:56:46 +02:00
2017-08-18 02:18:02 +02:00
err = conn . WriteMessage ( gorillawebsocket . TextMessage , [ ] byte ( "OK" ) )
2017-07-25 16:56:46 +02:00
c . Assert ( err , checker . IsNil )
_ , msg , err := conn . ReadMessage ( )
c . Assert ( err , checker . IsNil )
c . Assert ( string ( msg ) , checker . Equals , "OK" )
}
2017-08-01 15:24:08 +02:00
func ( suite * WebsocketSuite ) TestWrongOrigin ( c * check . C ) {
var upgrader = gorillawebsocket . Upgrader { } // use default options
srv := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
c , err := upgrader . Upgrade ( w , r , nil )
if err != nil {
return
}
defer c . Close ( )
for {
mt , message , err := c . ReadMessage ( )
if err != nil {
break
}
err = c . WriteMessage ( mt , message )
if err != nil {
break
}
}
} ) )
file := suite . adaptFile ( c , "fixtures/websocket/config.toml" , struct {
WebsocketServer string
} {
WebsocketServer : srv . URL ,
} )
defer os . Remove ( file )
cmd , _ := suite . cmdTraefik ( withConfigFile ( file ) , "--debug" )
err := cmd . Start ( )
c . Assert ( err , check . IsNil )
defer cmd . Process . Kill ( )
// wait for traefik
2017-08-01 19:32:44 +02:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/providers" , 10 * time . Second , try . BodyContains ( "127.0.0.1" ) )
2017-08-01 15:24:08 +02:00
c . Assert ( err , checker . IsNil )
config , err := websocket . NewConfig ( "ws://127.0.0.1:8000/ws" , "ws://127.0.0.1:800" )
c . Assert ( err , check . IsNil )
conn , err := net . DialTimeout ( "tcp" , "127.0.0.1:8000" , time . Second )
2017-08-18 02:18:02 +02:00
c . Assert ( err , checker . IsNil )
2017-08-01 15:24:08 +02:00
_ , err = websocket . NewClient ( config , conn )
c . Assert ( err , checker . NotNil )
c . Assert ( err , checker . ErrorMatches , "bad status" )
}
func ( suite * WebsocketSuite ) TestOrigin ( c * check . C ) {
2017-08-18 02:18:02 +02:00
// use default options
var upgrader = gorillawebsocket . Upgrader { }
2017-08-01 15:24:08 +02:00
srv := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
c , err := upgrader . Upgrade ( w , r , nil )
if err != nil {
return
}
defer c . Close ( )
for {
mt , message , err := c . ReadMessage ( )
if err != nil {
break
}
err = c . WriteMessage ( mt , message )
if err != nil {
break
}
}
} ) )
file := suite . adaptFile ( c , "fixtures/websocket/config.toml" , struct {
WebsocketServer string
} {
WebsocketServer : srv . URL ,
} )
defer os . Remove ( file )
cmd , _ := suite . cmdTraefik ( withConfigFile ( file ) , "--debug" )
err := cmd . Start ( )
c . Assert ( err , check . IsNil )
defer cmd . Process . Kill ( )
// wait for traefik
2017-08-01 19:32:44 +02:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/providers" , 10 * time . Second , try . BodyContains ( "127.0.0.1" ) )
2017-08-01 15:24:08 +02:00
c . Assert ( err , checker . IsNil )
config , err := websocket . NewConfig ( "ws://127.0.0.1:8000/ws" , "ws://127.0.0.1:8000" )
c . Assert ( err , check . IsNil )
conn , err := net . DialTimeout ( "tcp" , "127.0.0.1:8000" , time . Second )
2017-08-18 02:18:02 +02:00
c . Assert ( err , check . IsNil )
2017-08-01 15:24:08 +02:00
client , err := websocket . NewClient ( config , conn )
c . Assert ( err , checker . IsNil )
n , err := client . Write ( [ ] byte ( "OK" ) )
c . Assert ( err , checker . IsNil )
c . Assert ( n , checker . Equals , 2 )
msg := make ( [ ] byte , 2 )
n , err = client . Read ( msg )
c . Assert ( err , checker . IsNil )
c . Assert ( n , checker . Equals , 2 )
c . Assert ( string ( msg ) , checker . Equals , "OK" )
}
func ( suite * WebsocketSuite ) TestWrongOriginIgnoredByServer ( c * check . C ) {
var upgrader = gorillawebsocket . Upgrader { CheckOrigin : func ( r * http . Request ) bool {
return true
} }
srv := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
c , err := upgrader . Upgrade ( w , r , nil )
if err != nil {
return
}
defer c . Close ( )
for {
mt , message , err := c . ReadMessage ( )
if err != nil {
break
}
err = c . WriteMessage ( mt , message )
if err != nil {
break
}
}
} ) )
file := suite . adaptFile ( c , "fixtures/websocket/config.toml" , struct {
WebsocketServer string
} {
WebsocketServer : srv . URL ,
} )
defer os . Remove ( file )
cmd , _ := suite . cmdTraefik ( withConfigFile ( file ) , "--debug" )
err := cmd . Start ( )
c . Assert ( err , check . IsNil )
defer cmd . Process . Kill ( )
// wait for traefik
2017-08-01 19:32:44 +02:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/providers" , 10 * time . Second , try . BodyContains ( "127.0.0.1" ) )
2017-08-01 15:24:08 +02:00
c . Assert ( err , checker . IsNil )
config , err := websocket . NewConfig ( "ws://127.0.0.1:8000/ws" , "ws://127.0.0.1:80" )
c . Assert ( err , check . IsNil )
conn , err := net . DialTimeout ( "tcp" , "127.0.0.1:8000" , time . Second )
2017-08-18 02:18:02 +02:00
c . Assert ( err , checker . IsNil )
2017-08-01 15:24:08 +02:00
client , err := websocket . NewClient ( config , conn )
c . Assert ( err , checker . IsNil )
n , err := client . Write ( [ ] byte ( "OK" ) )
c . Assert ( err , checker . IsNil )
c . Assert ( n , checker . Equals , 2 )
msg := make ( [ ] byte , 2 )
n , err = client . Read ( msg )
c . Assert ( err , checker . IsNil )
c . Assert ( n , checker . Equals , 2 )
c . Assert ( string ( msg ) , checker . Equals , "OK" )
}
2017-09-06 09:36:02 +02:00
func ( suite * WebsocketSuite ) TestSSLTermination ( c * check . C ) {
var upgrader = gorillawebsocket . Upgrader { } // use default options
srv := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
c , err := upgrader . Upgrade ( w , r , nil )
if err != nil {
return
}
defer c . Close ( )
for {
mt , message , err := c . ReadMessage ( )
if err != nil {
break
}
err = c . WriteMessage ( mt , message )
if err != nil {
break
}
}
} ) )
file := suite . adaptFile ( c , "fixtures/websocket/config_https.toml" , struct {
WebsocketServer string
} {
WebsocketServer : srv . URL ,
} )
defer os . Remove ( file )
cmd , _ := suite . cmdTraefik ( withConfigFile ( file ) , "--debug" )
err := cmd . Start ( )
c . Assert ( err , check . IsNil )
defer cmd . Process . Kill ( )
// wait for traefik
err = try . GetRequest ( "http://127.0.0.1:8080/api/providers" , 10 * time . Second , try . BodyContains ( "127.0.0.1" ) )
c . Assert ( err , checker . IsNil )
//Add client self-signed cert
roots := x509 . NewCertPool ( )
certContent , err := ioutil . ReadFile ( "./resources/tls/local.cert" )
roots . AppendCertsFromPEM ( certContent )
gorillawebsocket . DefaultDialer . TLSClientConfig = & tls . Config {
RootCAs : roots ,
}
conn , _ , err := gorillawebsocket . DefaultDialer . Dial ( "wss://127.0.0.1:8000/ws" , nil )
c . Assert ( err , checker . IsNil )
err = conn . WriteMessage ( gorillawebsocket . TextMessage , [ ] byte ( "OK" ) )
c . Assert ( err , checker . IsNil )
_ , msg , err := conn . ReadMessage ( )
c . Assert ( err , checker . IsNil )
c . Assert ( string ( msg ) , checker . Equals , "OK" )
}