diff --git a/src/main/java/com/github/nkzawa/engineio/client/Socket.java b/src/main/java/com/github/nkzawa/engineio/client/Socket.java index a04e055..7ef488b 100644 --- a/src/main/java/com/github/nkzawa/engineio/client/Socket.java +++ b/src/main/java/com/github/nkzawa/engineio/client/Socket.java @@ -208,6 +208,16 @@ public class Socket extends Emitter { String transportName; if (Socket.this.rememberUpgrade && Socket.priorWebsocketSuccess && Socket.this.transports.contains(WebSocket.NAME)) { transportName = WebSocket.NAME; + } else if (0 == Socket.this.transports.size()) { + // Emit error on next tick so it can be listened to + final Socket self = Socket.this; + EventThread.nextTick(new Runnable() { + @Override + public void run() { + self.emit(Socket.EVENT_ERROR, new EngineIOException("No transports available")); + } + }); + return; } else { transportName = Socket.this.transports.get(0); } diff --git a/src/main/java/com/github/nkzawa/engineio/client/transports/PollingXHR.java b/src/main/java/com/github/nkzawa/engineio/client/transports/PollingXHR.java index 96b183f..da7e1a1 100644 --- a/src/main/java/com/github/nkzawa/engineio/client/transports/PollingXHR.java +++ b/src/main/java/com/github/nkzawa/engineio/client/transports/PollingXHR.java @@ -142,7 +142,10 @@ public class PollingXHR extends Polling { private String method; private String uri; + + // data is always a binary private byte[] data; + private SSLContext sslContext; private HttpURLConnection xhr; @@ -186,8 +189,6 @@ public class PollingXHR extends Polling { @Override public void run() { OutputStream output = null; - InputStream input = null; - BufferedReader reader = null; try { if (self.data != null) { xhr.setFixedLengthStreamingMode(self.data.length); @@ -210,33 +211,7 @@ public class PollingXHR extends Polling { final int statusCode = xhr.getResponseCode(); if (HttpURLConnection.HTTP_OK == statusCode) { - String contentType = xhr.getContentType(); - if ("application/octet-stream".equalsIgnoreCase(contentType)) { - input = new BufferedInputStream(xhr.getInputStream()); - List buffers = new ArrayList(); - int capacity = 0; - int len = 0; - byte[] buffer = new byte[1024]; - while ((len = input.read(buffer)) > 0) { - byte[] _buffer = new byte[len]; - System.arraycopy(buffer, 0, _buffer, 0, len); - buffers.add(_buffer); - capacity += len; - } - ByteBuffer data = ByteBuffer.allocate(capacity); - for (byte[] b : buffers) { - data.put(b); - } - self.onData(data.array()); - } else { - String line; - StringBuilder data = new StringBuilder(); - reader = new BufferedReader(new InputStreamReader(xhr.getInputStream())); - while ((line = reader.readLine()) != null) { - data.append(line); - } - self.onData(data.toString()); - } + self.onLoad(); } else { self.onError(new IOException(Integer.toString(statusCode))); } @@ -246,12 +221,6 @@ public class PollingXHR extends Polling { try { if (output != null) output.close(); } catch (IOException e) {} - try { - if (input != null) input.close(); - } catch (IOException e) {} - try { - if (reader != null) reader.close(); - } catch (IOException e) {} } } }).start(); @@ -294,6 +263,48 @@ public class PollingXHR extends Polling { xhr = null; } + private void onLoad() { + InputStream input = null; + BufferedReader reader = null; + String contentType = xhr.getContentType(); + try { + if ("application/octet-stream".equalsIgnoreCase(contentType)) { + input = new BufferedInputStream(this.xhr.getInputStream()); + List buffers = new ArrayList(); + int capacity = 0; + int len = 0; + byte[] buffer = new byte[1024]; + while ((len = input.read(buffer)) > 0) { + byte[] _buffer = new byte[len]; + System.arraycopy(buffer, 0, _buffer, 0, len); + buffers.add(_buffer); + capacity += len; + } + ByteBuffer data = ByteBuffer.allocate(capacity); + for (byte[] b : buffers) { + data.put(b); + } + this.onData(data.array()); + } else { + String line; + StringBuilder data = new StringBuilder(); + reader = new BufferedReader(new InputStreamReader(xhr.getInputStream())); + while ((line = reader.readLine()) != null) { + data.append(line); + } + this.onData(data.toString()); + } + } catch (IOException e) { + this.onError(e); + } finally { + try { + if (input != null) input.close(); + } catch (IOException e) {} + try { + if (reader != null) reader.close(); + } catch (IOException e) {} + } + } public void abort() { this.cleanup(); } diff --git a/src/main/java/com/github/nkzawa/engineio/parser/Parser.java b/src/main/java/com/github/nkzawa/engineio/parser/Parser.java index e93002c..04e0117 100644 --- a/src/main/java/com/github/nkzawa/engineio/parser/Parser.java +++ b/src/main/java/com/github/nkzawa/engineio/parser/Parser.java @@ -39,6 +39,10 @@ public class Parser { private Parser() {} public static void encodePacket(Packet packet, EncodeCallback callback) { + encodePacket(packet, false, callback); + } + + public static void encodePacket(Packet packet, boolean utf8encode, EncodeCallback callback) { if (packet.data instanceof byte[]) { @SuppressWarnings("unchecked") Packet _packet = packet; @@ -51,7 +55,7 @@ public class Parser { String encoded = String.valueOf(packets.get(packet.type)); if (null != packet.data) { - encoded += UTF8.encode(String.valueOf(packet.data)); + encoded += utf8encode ? UTF8.encode(String.valueOf(packet.data)) : String.valueOf(packet.data); } @SuppressWarnings("unchecked") @@ -68,16 +72,23 @@ public class Parser { } public static Packet decodePacket(String data) { + return decodePacket(data, false); + } + + public static Packet decodePacket(String data, boolean utf8decode) { int type; try { type = Character.getNumericValue(data.charAt(0)); } catch (IndexOutOfBoundsException e) { type = -1; } - try { - data = UTF8.decode(data); - } catch (UTF8Exception e) { - return err; + + if (utf8decode) { + try { + data = UTF8.decode(data); + } catch (UTF8Exception e) { + return err; + } } if (type < 0 || type >= packetslist.size()) { @@ -107,7 +118,7 @@ public class Parser { final ArrayList results = new ArrayList(packets.length); for (Packet packet : packets) { - encodePacket(packet, new EncodeCallback() { + encodePacket(packet, true, new EncodeCallback() { @Override public void call(Object packet) { if (packet instanceof String) { @@ -168,7 +179,7 @@ public class Parser { } if (msg.length() != 0) { - Packet packet = decodePacket(msg); + Packet packet = decodePacket(msg, true); if (err.type.equals(packet.type) && err.data.equals(packet.data)) { callback.call(err, 0, 1); return; @@ -237,7 +248,7 @@ public class Parser { if (buffer instanceof String) { @SuppressWarnings("unchecked") DecodePayloadCallback _callback = callback; - _callback.call(decodePacket((String)buffer), i, total); + _callback.call(decodePacket((String)buffer, true), i, total); } else if (buffer instanceof byte[]) { @SuppressWarnings("unchecked") DecodePayloadCallback _callback = callback; diff --git a/src/test/java/com/github/nkzawa/engineio/parser/ParserTest.java b/src/test/java/com/github/nkzawa/engineio/parser/ParserTest.java index 3723174..748b5b1 100644 --- a/src/test/java/com/github/nkzawa/engineio/parser/ParserTest.java +++ b/src/test/java/com/github/nkzawa/engineio/parser/ParserTest.java @@ -171,7 +171,7 @@ public class ParserTest { @Test public void decodeInvalidUTF8() { - Packet p = decodePacket("4\uffff"); + Packet p = decodePacket("4\uffff", true); assertThat(p.type, is(Packet.ERROR)); assertThat(p.data, is(ERROR_DATA)); } diff --git a/src/test/resources/package.json b/src/test/resources/package.json index 782b727..b0a7117 100644 --- a/src/test/resources/package.json +++ b/src/test/resources/package.json @@ -3,6 +3,6 @@ "version": "0.0.0", "private": true, "dependencies": { - "engine.io": "1.3.1" + "engine.io": "1.4.0" } }