Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for 401 Status Code in HTTP Response for WebSocket Handshake #1423

Open
jjm159 opened this issue Jun 19, 2024 · 1 comment
Open

Support for 401 Status Code in HTTP Response for WebSocket Handshake #1423

jjm159 opened this issue Jun 19, 2024 · 1 comment

Comments

@jjm159
Copy link

jjm159 commented Jun 19, 2024

Hello,

Currently, I am developing an electric vehicle charging control program, using the Java-WebSocket library to connect with chargers. This program is called CSMS. The OCA organization has created a protocol called OCPP (Open Charge Point Protocol) for communication between CSMS and chargers. OCA provides certification tests to ensure how well CSMS complies with OCPP.

During these certification tests, an issue has arisen with the Java-WebSocket library. In a test case where the charger attempts to connect via WebSocket and the username and password provided in the HTTP headers are not verified by the CSMS, the HTTP response must include a "401" status in the status line.

Currently, the Java-WebSocket library does not allow including a 401 status in the status line of the response. Even if an error with status code and message is thrown in onWebsocketHandshakeReceivedAsServer, the HTTP response status line is handled as 404 instead.

private void closeConnectionDueToWrongHandshake(InvalidDataException exception) {
  write(generateHttpResponseDueToError(404));
  flushAndClose(exception.getCloseCode(), exception.getMessage(), false);
}
private ByteBuffer generateHttpResponseDueToError(int errorCode) {
    String errorCodeDescription;
    switch (errorCode) {
      case 404:
        errorCodeDescription = "404 WebSocket Upgrade Failure";
        break;
      case 500:
      default:
        errorCodeDescription = "500 Internal Server Error";
    }
    return ByteBuffer.wrap(Charsetfunctions.asciiBytes("HTTP/1.1 " + errorCodeDescription
        + "\\r\\nContent-Type: text/html\\r\\nServer: TooTallNate Java-WebSocket\\r\\nContent-Length: "
        + (48 + errorCodeDescription.length()) + "\\r\\n\\r\\n<html><head></head><body><h1>"
        + errorCodeDescription + "</h1></body></html>"));
  }

Regarding this issue, I have reviewed previous issues #977 and #1278 but could not find a clear reason why a 401 error should not be included in the HTTP response status line.

RFC6455 states that during the Opening Handshake, the server can perform additional client authentication and include a 401 status code in the HTTP response in case of authentication failure. Please refer to the link.

Therefore, I believe the server should be able to include a 401 status in the HTTP response upon authentication failure when performing client authentication in onWebsocketHandshakeReceivedAsServer.

I propose the following solution, and would appreciate any better suggestions:

private void closeConnectionDueToWrongHandshake(InvalidDataException exception) {
  int closeCode = exception.getCloseCode();
  String message = exception.getMessage();
  write(generateHttpResponseDueToError(closeCode, message));
  flushAndClose(closeCode, message, false);
}

private void closeConnectionDueToInternalServerError(RuntimeException exception) {
  String message = exception.getMessage();
  write(generateHttpResponseDueToError(500, message));
  flushAndClose(CloseFrame.NEVER_CONNECTED, message, false);
}

private ByteBuffer generateHttpResponseDueToError(int errorCode, String errorMessage) {
  String errorCodeDescription;
  switch (errorCode) {
    case 500:
      if (errorMessage == null || errorMessage.isEmpty()) {
        errorCodeDescription = "500 Internal Server Error";
      } else {
        errorCodeDescription = String.format("500 %s", errorMessage);
      }
      break;
    default:
      if (errorMessage == null || errorMessage.isEmpty()) {
        errorCodeDescription = String.format("%d WebSocket Upgrade Failure", errorCode);
      } else {
        errorCodeDescription = String.format("%d %s", errorCode, errorMessage);
      }
  }
  return ByteBuffer.wrap(Charsetfunctions.asciiBytes("HTTP/1.1 " + errorCodeDescription
      + "\r\nContent-Type: text/html\r\nServer: TooTallNate Java-WebSocket\r\nContent-Length: "
      + (48 + errorCodeDescription.length()) + "\r\n\r\n<html><head></head><body><h1>"
      + errorCodeDescription + "</h1></body></html>"));
}

Currently, Java-OCA-OCPP uses the Java-WebSocket library for OCPP certification. If the 401 status code is not included in the HTTP response of the opening handshake, many Java developers taking the OCPP certification test will need to make extensive code modifications. I hope my request will be considered. Thank you.

@sungbeenkim
Copy link

I'm experiencing the same problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants