diff --git a/pom.xml b/pom.xml index 148eefd20..2679aa4b9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,14 +1,22 @@ + + + au.com.iwsoftware + iwsoftware + 3.4 + + 4.0.0 org.java-websocket Java-WebSocket jar - 1.5.6 - Java-WebSocket + 1.5.6.Ascom + ${project.artifactId}-${project.version} A barebones WebSocket client and server implementation written 100% in Java https://github.com/TooTallNate/Java-WebSocket + UTF-8 2.0.6 @@ -30,6 +38,7 @@ org.java-websocket:Java-WebSocket marci4-github https://sonarcloud.io + 11 diff --git a/src/main/java/org/java_websocket/WebSocketAdapter.java b/src/main/java/org/java_websocket/WebSocketAdapter.java index d06ca6f91..7fdf043d3 100644 --- a/src/main/java/org/java_websocket/WebSocketAdapter.java +++ b/src/main/java/org/java_websocket/WebSocketAdapter.java @@ -99,7 +99,7 @@ public void onWebsocketPong(WebSocket conn, Framedata f) { * Default implementation for onPreparePing, returns a (cached) PingFrame that has no application * data. * - * @param conn The WebSocket connection from which the ping frame will be sent. + * @param conn The {@code WebSocket} connection from which the ping frame will be sent. * @return PingFrame to be sent. * @see org.java_websocket.WebSocketListener#onPreparePing(WebSocket) */ diff --git a/src/main/java/org/java_websocket/WebSocketImpl.java b/src/main/java/org/java_websocket/WebSocketImpl.java index c2cd223b9..0ea734d47 100644 --- a/src/main/java/org/java_websocket/WebSocketImpl.java +++ b/src/main/java/org/java_websocket/WebSocketImpl.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -302,6 +303,10 @@ private boolean decodeHandshake(ByteBuffer socketBufferNew) { closeConnectionDueToInternalServerError(e); return false; } + if (response.getHttpStatus() >= 400) { + closeConnectionDueToCustomFailure(response); + return false; + } write(d.createHandshake( d.postProcessHandshakeResponseAsServer(handshake, response))); draft = d; @@ -442,6 +447,43 @@ private void closeConnectionDueToInternalServerError(RuntimeException exception) write(generateHttpResponseDueToError(500)); flushAndClose(CloseFrame.NEVER_CONNECTED, exception.getMessage(), false); } + + /** + * Close the connection with a custom failure code and message. + * + * @param response The pre-filled response. + */ + private void closeConnectionDueToCustomFailure(ServerHandshakeBuilder response) { + write(generateCustomFailedHttpResponse(response)); + flushAndClose(CloseFrame.NEVER_CONNECTED, response.getHttpStatusMessage(), false); + } + + /** + * Create the response data for a custom failure message. + * + * @param response The pre-filled response + * @return The raw data to be sent + */ + private ByteBuffer generateCustomFailedHttpResponse(ServerHandshakeBuilder response) { + String responseContent = String.format( + "

%d %s

", + response.getHttpStatus(), + response.getHttpStatusMessage()); + + StringBuilder responseBuilder = new StringBuilder(); + responseBuilder.append("HTTP/1.1 ").append(response.getHttpStatus()).append("\r\n"); + responseBuilder.append("Content-Type: text/html\r\n"); + responseBuilder.append("Server: TooTallNate Java-WebSocket\r\n"); + responseBuilder.append("Content-Length: ").append(responseContent.length()).append("\r\n"); + for (Iterator iter = response.iterateHttpFields(); iter.hasNext(); ) { + String header = iter.next(); + responseBuilder.append(header).append(": ").append(response.getFieldValue(header)).append("\r\n"); + } + responseBuilder.append("\r\n"); + responseBuilder.append(responseContent); + return ByteBuffer.wrap( + Charsetfunctions.asciiBytes(responseBuilder.toString())); + } /** * Generate a simple response for the corresponding endpoint to indicate some error diff --git a/src/main/java/org/java_websocket/WebSocketListener.java b/src/main/java/org/java_websocket/WebSocketListener.java index f0b21d526..511f085e4 100644 --- a/src/main/java/org/java_websocket/WebSocketListener.java +++ b/src/main/java/org/java_websocket/WebSocketListener.java @@ -38,8 +38,8 @@ import org.java_websocket.handshake.ServerHandshakeBuilder; /** - * Implemented by WebSocketClient and WebSocketServer. The methods within are - * called by WebSocket. Almost every method takes a first parameter conn which represents + * Implemented by {@code WebSocketClient} and {@code WebSocketServer}. The methods within are + * called by {@code WebSocket}. Almost every method takes a first parameter conn which represents * the source of the respective event. */ public interface WebSocketListener { @@ -86,7 +86,7 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) /** * Called when an entire text frame has been received. Do whatever you want here... * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param message The UTF-8 decoded message that was received. */ void onWebsocketMessage(WebSocket conn, String message); @@ -94,7 +94,7 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) /** * Called when an entire binary frame has been received. Do whatever you want here... * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param blob The binary message that was received. */ void onWebsocketMessage(WebSocket conn, ByteBuffer blob); @@ -103,16 +103,16 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) * Called after onHandshakeReceived returns true. Indicates that a complete * WebSocket connection has been established, and we are ready to send/receive data. * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param d The handshake of the websocket instance */ void onWebsocketOpen(WebSocket conn, Handshakedata d); /** - * Called after WebSocket#close is explicity called, or when the other end of the + * Called after {@code WebSocket#close} is explicity called, or when the other end of the * WebSocket connection is closed. * - * @param ws The WebSocket instance this event is occurring on. + * @param ws The {@code WebSocket} instance this event is occurring on. * @param code The codes can be looked up here: {@link CloseFrame} * @param reason Additional information string * @param remote Returns whether or not the closing of the connection was initiated by the remote @@ -123,7 +123,7 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) /** * Called as soon as no further frames are accepted * - * @param ws The WebSocket instance this event is occurring on. + * @param ws The {@code WebSocket} instance this event is occurring on. * @param code The codes can be looked up here: {@link CloseFrame} * @param reason Additional information string * @param remote Returns whether or not the closing of the connection was initiated by the remote @@ -134,7 +134,7 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) /** * send when this peer sends a close handshake * - * @param ws The WebSocket instance this event is occurring on. + * @param ws The {@code WebSocket} instance this event is occurring on. * @param code The codes can be looked up here: {@link CloseFrame} * @param reason Additional information string */ @@ -144,7 +144,7 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) * Called if an exception worth noting occurred. If an error causes the connection to fail onClose * will be called additionally afterwards. * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param ex The exception that occurred.
Might be null if the exception is not related to * any specific connection. For example if the server port could not be bound. */ @@ -153,7 +153,7 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) /** * Called a ping frame has been received. This method must send a corresponding pong by itself. * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param f The ping frame. Control frames may contain payload. */ void onWebsocketPing(WebSocket conn, Framedata f); @@ -162,7 +162,7 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) * Called just before a ping frame is sent, in order to allow users to customize their ping frame * data. * - * @param conn The WebSocket connection from which the ping frame will be sent. + * @param conn The {@code WebSocket} connection from which the ping frame will be sent. * @return PingFrame to be sent. */ PingFrame onPreparePing(WebSocket conn); @@ -170,7 +170,7 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) /** * Called when a pong frame is received. * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param f The pong frame. Control frames may contain payload. **/ void onWebsocketPong(WebSocket conn, Framedata f); @@ -179,19 +179,19 @@ void onWebsocketHandshakeSentAsClient(WebSocket conn, ClientHandshake request) * This method is used to inform the selector thread that there is data queued to be written to * the socket. * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. */ void onWriteDemand(WebSocket conn); /** - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @return Returns the address of the endpoint this socket is bound to. * @see WebSocket#getLocalSocketAddress() */ InetSocketAddress getLocalSocketAddress(WebSocket conn); /** - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @return Returns the address of the endpoint this socket is connected to, or{@code null} if it * is unconnected. * @see WebSocket#getRemoteSocketAddress() diff --git a/src/main/java/org/java_websocket/server/WebSocketServer.java b/src/main/java/org/java_websocket/server/WebSocketServer.java index 8e00c5b22..1dcba0dbf 100644 --- a/src/main/java/org/java_websocket/server/WebSocketServer.java +++ b/src/main/java/org/java_websocket/server/WebSocketServer.java @@ -71,7 +71,7 @@ import org.slf4j.LoggerFactory; /** - * WebSocketServer is an abstract class that only takes care of the + * {@code WebSocketServer} is an abstract class that only takes care of the * HTTP handshake portion of WebSockets. It's up to a subclass to add functionality/purpose to the * server. */ @@ -183,7 +183,7 @@ public WebSocketServer(InetSocketAddress address, int decodercount, List /** * Creates a WebSocketServer that will attempt to bind/listen on the given address, and - * comply with Draft version draft. + * comply with {@code Draft} version draft. * * @param address The address (host:port) this server should listen on. * @param decodercount The number of {@link WebSocketWorker}s that will be used to process @@ -888,7 +888,7 @@ public InetSocketAddress getRemoteSocketAddress(WebSocket conn) { * Called after an opening handshake has been performed and the given websocket is ready to be * written on. * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param handshake The handshake of the websocket instance */ public abstract void onOpen(WebSocket conn, ClientHandshake handshake); @@ -896,7 +896,7 @@ public InetSocketAddress getRemoteSocketAddress(WebSocket conn) { /** * Called after the websocket connection has been closed. * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param code The codes can be looked up here: {@link CloseFrame} * @param reason Additional information string * @param remote Returns whether or not the closing of the connection was initiated by the remote @@ -907,7 +907,7 @@ public InetSocketAddress getRemoteSocketAddress(WebSocket conn) { /** * Callback for string messages received from the remote host * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param message The UTF-8 decoded message that was received. * @see #onMessage(WebSocket, ByteBuffer) **/ @@ -935,7 +935,7 @@ public InetSocketAddress getRemoteSocketAddress(WebSocket conn) { /** * Callback for binary messages received from the remote host * - * @param conn The WebSocket instance this event is occurring on. + * @param conn The {@code WebSocket} instance this event is occurring on. * @param message The binary message that was received. * @see #onMessage(WebSocket, ByteBuffer) **/ diff --git a/src/main/java/org/java_websocket/util/Base64.java b/src/main/java/org/java_websocket/util/Base64.java index 067a027e1..6839836d4 100644 --- a/src/main/java/org/java_websocket/util/Base64.java +++ b/src/main/java/org/java_websocket/util/Base64.java @@ -35,7 +35,7 @@ *
* byte[] myByteArray = Base64.decode( encoded ); * - *

The options parameter, which appears in a few places, is used to pass + *

The {@code options} parameter, which appears in a few places, is used to pass * several pieces of information to the encoder. In the "higher level" methods such as encodeBytes( * bytes, options ) the options parameter can be used to indicate such things as first gzipping the * bytes before encoding them, not inserting linefeeds, and encoding using the URL-safe and Ordered @@ -140,9 +140,9 @@ * when data that's being decoded is gzip-compressed and will decompress it * automatically. Generally things are cleaner. You'll probably have to * change some method calls that you were making to support the new - * options format (ints that you "OR" together). + * options format ({@code int}s that you "OR" together). *

  • v1.5.1 - Fixed bug when decompressing and decoding to a - * byte[] using decode( String s, boolean gzipCompressed ). + * byte[] using {@code decode( String s, boolean gzipCompressed )}. * Added the ability to "suspend" encoding in the Output Stream so * you can turn on and off the encoding if you need to embed base64 * data in an otherwise "normal" stream (like an XML file).
  • @@ -873,7 +873,7 @@ else if (source[srcOffset + 3] == EQUALS_SIGN) { /** * A {@link Base64.OutputStream} will write data to another - * java.io.OutputStream, given in the constructor, + * {@code java.io.OutputStream}, given in the constructor, * and encode/decode to/from Base64 notation on the fly. * * @see Base64 @@ -895,7 +895,7 @@ public static class OutputStream extends java.io.FilterOutputStream { /** * Constructs a {@link Base64.OutputStream} in ENCODE mode. * - * @param out the java.io.OutputStream to which data will be written. + * @param out the {@code java.io.OutputStream} to which data will be written. * @since 1.3 */ public OutputStream(java.io.OutputStream out) { @@ -914,7 +914,7 @@ public OutputStream(java.io.OutputStream out) { *

    * Example: new Base64.OutputStream( out, Base64.ENCODE ) * - * @param out the java.io.OutputStream to which data will be written. + * @param out the {@code java.io.OutputStream} to which data will be written. * @param options Specified options. * @see Base64#ENCODE * @see Base64#DO_BREAK_LINES diff --git a/src/test/java/org/java_websocket/issues/Issue941Test.java b/src/test/java/org/java_websocket/issues/Issue941Test.java index a9aedbaef..3c678eb5b 100644 --- a/src/test/java/org/java_websocket/issues/Issue941Test.java +++ b/src/test/java/org/java_websocket/issues/Issue941Test.java @@ -25,8 +25,6 @@ package org.java_websocket.issues; -import static org.junit.Assert.assertArrayEquals; - import java.net.InetSocketAddress; import java.net.URI; import java.nio.ByteBuffer; @@ -39,6 +37,7 @@ import org.java_websocket.handshake.ServerHandshake; import org.java_websocket.server.WebSocketServer; import org.java_websocket.util.SocketUtil; +import static org.junit.Assert.assertArrayEquals; import org.junit.Test; public class Issue941Test { @@ -47,7 +46,7 @@ public class Issue941Test { private CountDownLatch pongLatch = new CountDownLatch(1); private byte[] pingBuffer, receivedPingBuffer, pongBuffer; - @Test + @Test(timeout = 10000) public void testIssue() throws Exception { int port = SocketUtil.getAvailablePort(); WebSocketClient client = new WebSocketClient(new URI("ws://localhost:" + port)) {