Skip to content

Commit 49ef9d4

Browse files
authored
fix: set websocket when passed true and add websocket e2e test (#2497)
1 parent a35cad5 commit 49ef9d4

File tree

3 files changed

+140
-1
lines changed

3 files changed

+140
-1
lines changed

internal/provider/adc/translator/apisixroute.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (t *Translator) buildRoute(ar *apiv2.ApisixRoute, service *adc.Service, rul
177177
route.ID = id.GenID(route.Name)
178178
route.Desc = "Created by apisix-ingress-controller, DO NOT modify it manually"
179179
route.Labels = label.GenLabel(ar)
180-
route.EnableWebsocket = ptr.To(true)
180+
route.EnableWebsocket = ptr.To(rule.Websocket)
181181
route.FilterFunc = rule.Match.FilterFunc
182182
route.Hosts = rule.Match.Hosts
183183
route.Methods = rule.Match.Methods

test/e2e/crds/v2/route.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ import (
2424
"math"
2525
"net"
2626
"net/http"
27+
"net/url"
2728
"time"
2829

30+
"github.com/gorilla/websocket"
2931
. "github.com/onsi/ginkgo/v2"
3032
. "github.com/onsi/gomega"
3133
"k8s.io/apimachinery/pkg/types"
@@ -906,4 +908,137 @@ spec:
906908
})
907909
})
908910
})
911+
912+
Context("Test ApisixRoute WebSocket Support", func() {
913+
It("basic websocket functionality", func() {
914+
const websocketServerResources = `
915+
apiVersion: v1
916+
kind: Pod
917+
metadata:
918+
name: websocket-server
919+
labels:
920+
app: websocket-server
921+
spec:
922+
containers:
923+
- name: websocket-server
924+
image: jmalloc/echo-server:latest
925+
ports:
926+
- containerPort: 8080
927+
---
928+
apiVersion: v1
929+
kind: Service
930+
metadata:
931+
name: websocket-server-service
932+
spec:
933+
selector:
934+
app: websocket-server
935+
ports:
936+
- name: ws
937+
port: 8080
938+
protocol: TCP
939+
targetPort: 8080
940+
`
941+
const apisixRouteSpec = `
942+
apiVersion: apisix.apache.org/v2
943+
kind: ApisixRoute
944+
metadata:
945+
name: websocket-route
946+
spec:
947+
ingressClassName: apisix
948+
http:
949+
- name: rule1
950+
match:
951+
hosts:
952+
- httpbin.org
953+
paths:
954+
- /echo
955+
websocket: true
956+
backends:
957+
- serviceName: websocket-server-service
958+
servicePort: 8080
959+
`
960+
961+
const apisixRouteSpec2 = `
962+
apiVersion: apisix.apache.org/v2
963+
kind: ApisixRoute
964+
metadata:
965+
name: websocket-route
966+
spec:
967+
ingressClassName: apisix
968+
http:
969+
- name: rule1
970+
match:
971+
hosts:
972+
- httpbin.org
973+
paths:
974+
- /echo
975+
backends:
976+
- serviceName: websocket-server-service
977+
servicePort: 8080
978+
`
979+
980+
By("create WebSocket server resources")
981+
err := s.CreateResourceFromString(websocketServerResources)
982+
Expect(err).ShouldNot(HaveOccurred(), "creating WebSocket server resources")
983+
984+
By("create ApisixRoute without WebSocker")
985+
var apisixRouteWithoutWS apiv2.ApisixRoute
986+
applier.MustApplyAPIv2(
987+
types.NamespacedName{Namespace: s.Namespace(), Name: "websocket-route"},
988+
&apisixRouteWithoutWS,
989+
apisixRouteSpec2,
990+
)
991+
time.Sleep(8 * time.Second)
992+
993+
By("verify WebSocket connection fails without WebSocket enabled")
994+
u := url.URL{
995+
Scheme: "ws",
996+
Host: s.ApisixHTTPEndpoint(),
997+
Path: "/echo",
998+
}
999+
headers := http.Header{"Host": []string{"httpbin.org"}}
1000+
_, resp, _ := websocket.DefaultDialer.Dial(u.String(), headers)
1001+
// should receive 200 instead of 101
1002+
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
1003+
1004+
By("apply ApisixRoute for WebSocket")
1005+
var apisixRoute apiv2.ApisixRoute
1006+
applier.MustApplyAPIv2(
1007+
types.NamespacedName{Namespace: s.Namespace(), Name: "websocket-route"},
1008+
&apisixRoute,
1009+
apisixRouteSpec,
1010+
)
1011+
By("wait for WebSocket server to be ready")
1012+
time.Sleep(10 * time.Second)
1013+
By("verify WebSocket connection")
1014+
u = url.URL{
1015+
Scheme: "ws",
1016+
Host: s.ApisixHTTPEndpoint(),
1017+
Path: "/echo",
1018+
}
1019+
headers = http.Header{"Host": []string{"httpbin.org"}}
1020+
1021+
conn, resp, err := websocket.DefaultDialer.Dial(u.String(), headers)
1022+
Expect(err).ShouldNot(HaveOccurred(), "WebSocket handshake")
1023+
Expect(resp.StatusCode).Should(Equal(http.StatusSwitchingProtocols))
1024+
1025+
defer func() {
1026+
_ = conn.Close()
1027+
}()
1028+
1029+
By("send and receive message through WebSocket")
1030+
testMessage := "hello, this is APISIX"
1031+
err = conn.WriteMessage(websocket.TextMessage, []byte(testMessage))
1032+
Expect(err).ShouldNot(HaveOccurred(), "writing WebSocket message")
1033+
1034+
// The echo server sends an identification message first
1035+
_, _, err = conn.ReadMessage()
1036+
Expect(err).ShouldNot(HaveOccurred(), "reading identification message")
1037+
1038+
// Then our echo
1039+
_, msg, err := conn.ReadMessage()
1040+
Expect(err).ShouldNot(HaveOccurred(), "reading echo message")
1041+
Expect(string(msg)).To(Equal(testMessage), "message content verification")
1042+
})
1043+
})
9091044
})

test/e2e/scaffold/scaffold.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ func (s *Scaffold) NewAPISIXClient() *httpexpect.Expect {
162162
})
163163
}
164164

165+
func (s *Scaffold) ApisixHTTPEndpoint() string {
166+
return s.apisixHttpTunnel.Endpoint()
167+
}
168+
165169
// GetAPISIXHTTPSEndpoint get apisix https endpoint from tunnel map
166170
func (s *Scaffold) GetAPISIXHTTPSEndpoint() string {
167171
return s.apisixHttpsTunnel.Endpoint()

0 commit comments

Comments
 (0)