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

Enhancement Request: WebSocket Class for Protocol Persistence and Header Authentication #3782

Open
ognaranjo opened this issue Jan 24, 2024 · 2 comments
Assignees

Comments

@ognaranjo
Copy link

Hello, Codename One Team,

I am writing to highlight an issue and propose an enhancement for the WebSocket class in Codename One, particularly regarding protocol persistence during reconnections and the possibility of adding header authentication.

Issue Description:
In the current implementation of the WebSocket class, when using the autoReconnect feature, any protocol specified during the initial connection is lost upon reconnection. This poses a challenge, especially when integrating with systems like AWS API Gateway, which relies on the Sec-WebSocket-Protocol field for specific subprotocol requests that can be used to pass the user information and authentication.

Current Implementation (Code Snippet):

` String protocols = "userid:userID/auth:auth"
final WebSocket sock = new WebSocket("ws://awsxxxxxxx/WebSocketServer/whiteboardendpoint", protocols) {

	@Override
	protected void onOpen() {
		// code
	}

	@Override
	protected void onClose(int statusCode, String reason) {
		// code
	}

	@Override
	protected void onMessage(String message) {
	   // code
	}

	@Override
	protected void onError(Exception ex) {

	}

	 @Override
	 protected void onMessage(byte[] message) {
		 // code
	 }
}.autoReconnect(5000);
sock.connect();`

If we evaluate the WebSocket class constructor Code, it sets the protocols into the WebSocketNativeImpl object:

`

public WebSocket(String url, String protocols) {
    this.url = url;
    
    impl = (WebSocketNativeImpl)NativeLookup.create(WebSocketNativeImpl.class);
    impl.setId(nextId++);
    id = impl.getId();
    sockets.put(id, this);
    if (protocols != null) {
        setProtocols(protocols);
    }
    //impl.setUrl(url);
    //System.out.println("url is set");
}

`

However, the reconnect method instantiates the object without the protocols:

public void reconnect() { if (connecting || getReadyState() != WebSocketState.CLOSED) { return; } System.out.println("Attempting to reconnect..."); impl = (WebSocketNativeImpl)NativeLookup.create(WebSocketNativeImpl.class); impl.setId(nextId++); sockets.put(impl.getId(), this); connecting = false; connectHasBeenCalledAtLeastOnce=false; try { connect(connectTimeout); } catch (Throwable t) { System.out.println("Failed to reconnect. Will make another attempt in "+autoReconnectTimeout+"ms"); } }

As observed, the protocol set during the initial connection is not preserved during the reconnect process.

Proposed Modification (Code Snippet):

To address this, I enhanced the WebSocket class by adding a private string variable for the protocol, I set it in the constructor and updated the reconnect function to include the protocol in the reconnection process.

`
private String protocols;

public WebSocket(String url, String protocols) {
	this.url = url;
	
	impl = (WebSocketNativeImpl)NativeLookup.create(WebSocketNativeImpl.class);
	impl.setId(nextId++);
	id = impl.getId();
	sockets.put(id, this);
	if (protocols != null) {
		setProtocols(protocols);
		this.protocols = protocols;
	}
	//impl.setUrl(url);
	//System.out.println("url is set");
}

public void reconnect() {
	if (connecting || getReadyState() != WebSocketState.CLOSED) {
		return;
	}
	System.out.println("Attempting to reconnect...");
	impl = (WebSocketNativeImpl)NativeLookup.create(WebSocketNativeImpl.class);
	impl.setId(nextId++);
	if (this.protocols != null) {
		setProtocols(this.protocols);
	}
	sockets.put(impl.getId(), this);
	connecting = false;
	connectHasBeenCalledAtLeastOnce=false;
	try {
		connect(connectTimeout);
	} catch (Throwable t) {
		System.out.println("Failed to reconnect.  Will make another attempt in "+autoReconnectTimeout+"ms");
	}
}	`

Enhancement Request:

Protocol Persistence:
Could the WebSocket class be enhanced to natively support protocol persistence during the AutoReconnect process, similar to the modification I have proposed?

Header Authentication:
Additionally, I would like to inquire about the possibility of extending the WebSocket class to allow the inclusion of custom headers, particularly for authentication purposes. This feature would be extremely beneficial for secure WebSocket communications. AWS: "Request Authorizer allows you to configure identity source(s), which information(s) on the request will be passed into your Authorizer function. You can use headers, query strings, stage variables, and/or context parameter as identity source(s). "

These enhancements would significantly improve the WebSocket class's functionality, especially for applications requiring robust and secure WebSocket communications.

Thank you for considering this request. I look forward to your feedback and any suggestions you may have.

Best regards,
Oscar Naranjo

@shannah
Copy link
Collaborator

shannah commented Jan 27, 2024

@ognaranjo Great suggestion. I think that it might make more sense to just add support for custom headers, then you can add any header you like, including the Sec-WebSocket-Protocol header

@ognaranjo
Copy link
Author

Thank you @shannah for considering my enhancement request and for your swift response. The suggestion to add support for custom headers, including the ability to specify the Sec-WebSocket-Protocol header, definitely addresses my needs. This solution not only resolves my immediate requirement for protocol persistence but also opens up broader possibilities for customizing WebSocket communication, which is fantastic.

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