2017-08-01 17:32:44 +00:00
|
|
|
package integration
|
2017-07-25 14:56:46 +00:00
|
|
|
|
|
|
|
import (
|
2017-09-06 07:36:02 +00:00
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
|
|
|
"io/ioutil"
|
2017-08-01 13:24:08 +00:00
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2017-07-25 14:56:46 +00:00
|
|
|
"os"
|
2017-08-01 13:24:08 +00:00
|
|
|
"time"
|
2017-07-25 14:56:46 +00:00
|
|
|
|
2017-08-01 17:32:44 +00:00
|
|
|
"github.com/containous/traefik/integration/try"
|
2017-08-01 13:24:08 +00:00
|
|
|
"github.com/go-check/check"
|
|
|
|
gorillawebsocket "github.com/gorilla/websocket"
|
2017-07-25 14:56:46 +00:00
|
|
|
checker "github.com/vdemeester/shakers"
|
2017-08-01 13:24:08 +00:00
|
|
|
"golang.org/x/net/websocket"
|
2017-07-25 14:56:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// WebsocketSuite
|
|
|
|
type WebsocketSuite struct{ BaseSuite }
|
|
|
|
|
2017-09-13 08:34:04 +00:00
|
|
|
func (s *WebsocketSuite) TestBase(c *check.C) {
|
2017-08-01 13:24:08 +00:00
|
|
|
var upgrader = gorillawebsocket.Upgrader{} // use default options
|
2017-07-25 14:56:46 +00: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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
|
2017-09-13 08:34:04 +00:00
|
|
|
file := s.adaptFile(c, "fixtures/websocket/config.toml", struct {
|
2017-07-25 14:56:46 +00:00
|
|
|
WebsocketServer string
|
|
|
|
}{
|
|
|
|
WebsocketServer: srv.URL,
|
|
|
|
})
|
|
|
|
|
|
|
|
defer os.Remove(file)
|
2017-09-13 08:34:04 +00:00
|
|
|
cmd, display := s.traefikCmd(withConfigFile(file), "--debug")
|
|
|
|
defer display(c)
|
2017-07-25 14:56:46 +00:00
|
|
|
|
|
|
|
err := cmd.Start()
|
|
|
|
c.Assert(err, check.IsNil)
|
|
|
|
defer cmd.Process.Kill()
|
|
|
|
|
|
|
|
// wait for traefik
|
2017-08-01 17:32:44 +00:00
|
|
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.BodyContains("127.0.0.1"))
|
2017-07-25 14:56:46 +00:00
|
|
|
c.Assert(err, checker.IsNil)
|
|
|
|
|
2017-08-01 13:24:08 +00:00
|
|
|
conn, _, err := gorillawebsocket.DefaultDialer.Dial("ws://127.0.0.1:8000/ws", nil)
|
2017-08-18 00:18:02 +00:00
|
|
|
c.Assert(err, checker.IsNil)
|
2017-07-25 14:56:46 +00:00
|
|
|
|
2017-08-18 00:18:02 +00:00
|
|
|
err = conn.WriteMessage(gorillawebsocket.TextMessage, []byte("OK"))
|
2017-07-25 14:56:46 +00: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 13:24:08 +00:00
|
|
|
|
2017-09-13 08:34:04 +00:00
|
|
|
func (s *WebsocketSuite) TestWrongOrigin(c *check.C) {
|
2017-08-01 13:24:08 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
|
2017-09-13 08:34:04 +00:00
|
|
|
file := s.adaptFile(c, "fixtures/websocket/config.toml", struct {
|
2017-08-01 13:24:08 +00:00
|
|
|
WebsocketServer string
|
|
|
|
}{
|
|
|
|
WebsocketServer: srv.URL,
|
|
|
|
})
|
|
|
|
|
|
|
|
defer os.Remove(file)
|
2017-09-13 08:34:04 +00:00
|
|
|
cmd, display := s.traefikCmd(withConfigFile(file), "--debug")
|
|
|
|
defer display(c)
|
2017-08-01 13:24:08 +00:00
|
|
|
|
|
|
|
err := cmd.Start()
|
|
|
|
c.Assert(err, check.IsNil)
|
|
|
|
defer cmd.Process.Kill()
|
|
|
|
|
|
|
|
// wait for traefik
|
2017-08-01 17:32:44 +00:00
|
|
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.BodyContains("127.0.0.1"))
|
2017-08-01 13:24:08 +00: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 00:18:02 +00:00
|
|
|
c.Assert(err, checker.IsNil)
|
2017-08-01 13:24:08 +00:00
|
|
|
_, err = websocket.NewClient(config, conn)
|
|
|
|
c.Assert(err, checker.NotNil)
|
|
|
|
c.Assert(err, checker.ErrorMatches, "bad status")
|
|
|
|
}
|
|
|
|
|
2017-09-13 08:34:04 +00:00
|
|
|
func (s *WebsocketSuite) TestOrigin(c *check.C) {
|
2017-08-18 00:18:02 +00:00
|
|
|
// use default options
|
|
|
|
var upgrader = gorillawebsocket.Upgrader{}
|
2017-08-01 13:24:08 +00: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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
|
2017-09-13 08:34:04 +00:00
|
|
|
file := s.adaptFile(c, "fixtures/websocket/config.toml", struct {
|
2017-08-01 13:24:08 +00:00
|
|
|
WebsocketServer string
|
|
|
|
}{
|
|
|
|
WebsocketServer: srv.URL,
|
|
|
|
})
|
|
|
|
|
|
|
|
defer os.Remove(file)
|
2017-09-13 08:34:04 +00:00
|
|
|
cmd, display := s.traefikCmd(withConfigFile(file), "--debug")
|
|
|
|
defer display(c)
|
2017-08-01 13:24:08 +00:00
|
|
|
|
|
|
|
err := cmd.Start()
|
|
|
|
c.Assert(err, check.IsNil)
|
|
|
|
defer cmd.Process.Kill()
|
|
|
|
|
|
|
|
// wait for traefik
|
2017-08-01 17:32:44 +00:00
|
|
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.BodyContains("127.0.0.1"))
|
2017-08-01 13:24:08 +00: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 00:18:02 +00:00
|
|
|
c.Assert(err, check.IsNil)
|
2017-08-01 13:24:08 +00: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-13 08:34:04 +00:00
|
|
|
func (s *WebsocketSuite) TestWrongOriginIgnoredByServer(c *check.C) {
|
2017-08-01 13:24:08 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
|
2017-09-13 08:34:04 +00:00
|
|
|
file := s.adaptFile(c, "fixtures/websocket/config.toml", struct {
|
2017-08-01 13:24:08 +00:00
|
|
|
WebsocketServer string
|
|
|
|
}{
|
|
|
|
WebsocketServer: srv.URL,
|
|
|
|
})
|
|
|
|
|
|
|
|
defer os.Remove(file)
|
2017-09-13 08:34:04 +00:00
|
|
|
cmd, display := s.traefikCmd(withConfigFile(file), "--debug")
|
|
|
|
defer display(c)
|
2017-08-01 13:24:08 +00:00
|
|
|
|
|
|
|
err := cmd.Start()
|
|
|
|
c.Assert(err, check.IsNil)
|
|
|
|
defer cmd.Process.Kill()
|
|
|
|
|
|
|
|
// wait for traefik
|
2017-08-01 17:32:44 +00:00
|
|
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.BodyContains("127.0.0.1"))
|
2017-08-01 13:24:08 +00: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 00:18:02 +00:00
|
|
|
c.Assert(err, checker.IsNil)
|
2017-08-01 13:24:08 +00: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 07:36:02 +00:00
|
|
|
|
2017-09-13 08:34:04 +00:00
|
|
|
func (s *WebsocketSuite) TestSSLTermination(c *check.C) {
|
2017-09-06 07:36:02 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}))
|
2017-09-13 08:34:04 +00:00
|
|
|
file := s.adaptFile(c, "fixtures/websocket/config_https.toml", struct {
|
2017-09-06 07:36:02 +00:00
|
|
|
WebsocketServer string
|
|
|
|
}{
|
|
|
|
WebsocketServer: srv.URL,
|
|
|
|
})
|
|
|
|
|
|
|
|
defer os.Remove(file)
|
2017-09-13 08:34:04 +00:00
|
|
|
cmd, display := s.traefikCmd(withConfigFile(file), "--debug")
|
|
|
|
defer display(c)
|
2017-09-06 07:36:02 +00:00
|
|
|
|
|
|
|
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")
|
|
|
|
}
|