Propagate http status code when http upgrade request failed

R=mosum@google.com

Change-Id: I547d19da251bdea0c259d3896e6e333f9afd0bca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384522
Auto-Submit: Thomas Guerin <thomas.guerin2@gmail.com>
Reviewed-by: Brian Quinlan <bquinlan@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
diff --git a/sdk/lib/_http/websocket.dart b/sdk/lib/_http/websocket.dart
index 4ef5b08..28b8bcd 100644
--- a/sdk/lib/_http/websocket.dart
+++ b/sdk/lib/_http/websocket.dart
@@ -407,8 +407,14 @@
 
 class WebSocketException implements IOException {
   final String message;
+  final int? httpStatusCode;
 
-  const WebSocketException([this.message = ""]);
+  const WebSocketException([this.message = "", this.httpStatusCode]);
 
-  String toString() => "WebSocketException: $message";
+  String toString() {
+    if (httpStatusCode != null) {
+      return "WebSocketException: $message, HTTP status code: $httpStatusCode";
+    }
+    return "WebSocketException: $message";
+  }
 }
diff --git a/sdk/lib/_http/websocket_impl.dart b/sdk/lib/_http/websocket_impl.dart
index 2830556..4e7bf59 100644
--- a/sdk/lib/_http/websocket_impl.dart
+++ b/sdk/lib/_http/websocket_impl.dart
@@ -1046,13 +1046,13 @@
 
       return request.close();
     }).then((response) {
-      Future<WebSocket> error(String message) {
+      Future<WebSocket> error(String message, [int? httpStatusCode]) {
         // Flush data.
         response.detachSocket().then((socket) {
           socket.destroy();
         });
         return Future<WebSocket>.error(
-            WebSocketException(message), callerStackTrace);
+            WebSocketException(message, httpStatusCode), callerStackTrace);
       }
 
       var connectionHeader = response.headers[HttpHeaders.connectionHeader];
@@ -1061,7 +1061,8 @@
           !connectionHeader.any((value) => value.toLowerCase() == "upgrade") ||
           response.headers.value(HttpHeaders.upgradeHeader)!.toLowerCase() !=
               "websocket") {
-        return error("Connection to '$uri' was not upgraded to websocket");
+        return error("Connection to '$uri' was not upgraded to websocket",
+            response.statusCode);
       }
       String? accept = response.headers.value("Sec-WebSocket-Accept");
       if (accept == null) {
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 99a4287..0aa3c59 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -300,6 +300,7 @@
       });
 
       Future<WebSocket?>.value(createClient(server.port)).catchError((error) {
+        Expect.equals(HttpStatus.notFound, error.httpStatusCode);
         server.close();
       });
     });