UI Server: fix connection upgrade error handling
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 17 Dec 2022 19:24:41 +0000 (20:24 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 17 Dec 2022 19:24:41 +0000 (20:24 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/charging-station/AutomaticTransactionGenerator.ts
src/charging-station/ChargingStation.ts
src/charging-station/ui-server/UIWebSocketServer.ts

index a6d3031c88336801233beaba865ab68bf2c5abe6..2548836022a7e7381d51002a37a487f52309380e 100644 (file)
@@ -69,6 +69,9 @@ export default class AutomaticTransactionGenerator extends AsyncResource {
   }
 
   public start(): void {
+    if (this.checkChargingStation() === false) {
+      return;
+    }
     if (this.started === true) {
       logger.warn(`${this.logPrefix()} is already started`);
       return;
@@ -87,6 +90,9 @@ export default class AutomaticTransactionGenerator extends AsyncResource {
   }
 
   public startConnector(connectorId: number): void {
+    if (this.checkChargingStation(connectorId) === false) {
+      return;
+    }
     if (this.connectorsStatus.has(connectorId) === false) {
       logger.error(`${this.logPrefix(connectorId)} starting on non existing connector`);
       throw new BaseError(`Connector ${connectorId} does not exist`);
@@ -447,4 +453,11 @@ export default class AutomaticTransactionGenerator extends AsyncResource {
       this.connectorsStatus.get(connectorId).rejectedStartTransactionRequests++;
     }
   }
+
+  private checkChargingStation(connectorId?: number): boolean {
+    if (this.chargingStation.started === false) {
+      logger.warn(`${this.logPrefix(connectorId)} charging station is stopped, cannot proceed`);
+    }
+    return this.chargingStation.started;
+  }
 }
index 04c33a1028c90e0f7ba0f833e717c60af6ec6cd3..58648ed272932e1b064286815699256bf30d2582 100644 (file)
@@ -608,6 +608,12 @@ export default class ChargingStation {
     options.handshakeTimeout = options?.handshakeTimeout ?? this.getConnectionTimeout() * 1000;
     params.closeOpened = params?.closeOpened ?? false;
     params.terminateOpened = params?.terminateOpened ?? false;
+    if (this.started === false) {
+      logger.warn(
+        `${this.logPrefix()} Cannot open OCPP connection to URL ${this.wsConnectionUrl.toString()} on stopped charging station`
+      );
+      return;
+    }
     if (
       !Utils.isNullOrUndefined(this.stationInfo.supervisionUser) &&
       !Utils.isNullOrUndefined(this.stationInfo.supervisionPassword)
index 60a4e3c186221f9c00556744e68110ec123cfa1b..d7b3a811c72303ce77b3b836d784139f974dcbec 100644 (file)
@@ -72,14 +72,29 @@ export default class UIWebSocketServer extends AbstractUIServer {
       'upgrade',
       (req: IncomingMessage, socket: internal.Duplex, head: Buffer): void => {
         this.authenticate(req, (err) => {
-          if (err) {
-            socket.write(`HTTP/1.1 ${StatusCodes.UNAUTHORIZED} Unauthorized\r\n\r\n`);
+          if (req.headers?.connection === 'Upgrade' && req.headers?.upgrade === 'websocket') {
+            if (err) {
+              socket.write(`HTTP/1.1 ${StatusCodes.UNAUTHORIZED} Unauthorized\r\n\r\n`);
+              socket.destroy();
+              return;
+            }
+            try {
+              this.webSocketServer.handleUpgrade(req, socket, head, (ws: WebSocket) => {
+                this.webSocketServer.emit('connection', ws, req);
+              });
+            } catch (error) {
+              logger.error(
+                `${this.logPrefix(
+                  moduleName,
+                  'start.httpServer.on.upgrade'
+                )} Error at handling connection upgrade:`,
+                error
+              );
+            }
+          } else {
+            socket.write(`HTTP/1.1 ${StatusCodes.BAD_REQUEST} Bad Request\r\n\r\n`);
             socket.destroy();
-            return;
           }
-          this.webSocketServer.handleUpgrade(req, socket, head, (ws: WebSocket) => {
-            this.webSocketServer.emit('connection', ws, req);
-          });
         });
       }
     );