Aias00 commented on code in PR #7219:
URL: https://github.com/apache/shenyu/pull/7219#discussion_r4110671479


##########
shenyu-plugin/shenyu-plugin-global/src/main/java/org/apache/shenyu/plugin/global/DefaultShenyuContextBuilder.java:
##########
@@ -70,7 +70,8 @@ private Pair<String, MetaData> buildData(final 
ServerWebExchange exchange) {
             return Pair.of(rpcType, new MetaData());
         }
         String upgrade = headers.getFirst(UPGRADE);
-        if (StringUtils.isNotEmpty(upgrade) && 
RpcTypeEnum.WEB_SOCKET.getName().equals(upgrade)) {
+        // RFC 6455: the Upgrade header value is case-insensitive
+        if (StringUtils.isNotEmpty(upgrade) && 
RpcTypeEnum.WEB_SOCKET.getName().equalsIgnoreCase(upgrade)) {

Review Comment:
   Non-blocking, but please coordinate with #7195 (it edits these same two 
files).
   
   `build()` resolves the decorator with no null check:
   
   ```java
   return 
decoratorMap.get(buildData.getLeft()).decorator(buildDefaultContext(exchange.getRequest()),
 buildData.getRight());   // line 62
   ```
   
   `decoratorMap` only holds the `ShenyuContextDecorator` beans actually on the 
classpath (GlobalPluginConfiguration.java:71-74), so the `websocket` key exists 
only when `shenyu-spring-boot-starter-plugin-websocket` is present.
   
   Consequence of this line specifically: it widens the set of requests that 
resolve to `rpcType = websocket`. In a deployment without the websocket 
starter, `Upgrade: WebSocket` previously fell through to the `MetaDataCache` 
lookup and was proxied as HTTP; now it NPEs here. That hazard already exists on 
master for the lowercase spelling, so this is a widening rather than a new 
defect - but it is precisely what #7195 fixes, and that PR modifies this file 
and this test class too. Please land the null check (or merge #7195 first) so 
the widened input set cannot turn into a 500.
   



##########
shenyu-plugin/shenyu-plugin-global/src/test/java/org/apache/shenyu/plugin/global/DefaultShenyuContextBuilderTest.java:
##########
@@ -57,4 +60,29 @@ public void testBuild() {
         assertNotNull(shenyuContext);
         assertEquals(RpcTypeEnum.HTTP.getName(), shenyuContext.getRpcType());
     }
+
+    @Test
+    public void testBuildWithWebSocketUpgradeHeaderValueCaseInsensitive() {
+        // RFC 6455 requires the Upgrade header value to be compared 
case-insensitively
+        for (String upgradeValue : Arrays.asList("websocket", "WebSocket", 
"WEBSOCKET", "Websocket")) {
+            MockServerWebExchange exchange = 
MockServerWebExchange.from(MockServerHttpRequest.get("http://localhost:8080/websocket";)
+                    .remoteAddress(new InetSocketAddress(8092))
+                    .header("Upgrade", upgradeValue)
+                    .header("Connection", "Upgrade")
+                    .build());
+            ShenyuContext shenyuContext = 
defaultShenyuContextBuilder.build(exchange);
+            assertEquals(RpcTypeEnum.WEB_SOCKET.getName(), 
shenyuContext.getRpcType(),
+                    "Upgrade header value '" + upgradeValue + "' must be 
detected as websocket rpc type");
+        }
+    }
+
+    @Test
+    public void testBuildWithNonWebSocketUpgradeHeaderValue() {

Review Comment:
   Non-blocking: this one passes on master too, so it is a guard on the 
negative path rather than a second regression test - fine to keep as-is, I only 
note it so the test count is not read as two regression tests.
   
   One related case worth knowing about (not asking you to handle it): because 
the check above reads `headers.getFirst(UPGRADE)`, a comma-separated value such 
as `Upgrade: websocket, h2c` still resolves to HTTP. That is currently 
consistent rather than broken - Spring's `HandshakeWebSocketService` validates 
with `"WebSocket".equalsIgnoreCase(headers.getUpgrade())` 
(HandshakeWebSocketService.java:204) and `HttpHeaders#getUpgrade()` is also 
`getFirst(UPGRADE)` (HttpHeaders.java:1393-1395), so both layers reject the 
multi-token form identically. It would only become our problem if either side 
started parsing the list.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to