|
3 | 3 | import io.socket.engineio.parser.Packet; |
4 | 4 | import io.socket.engineio.parser.ServerParser; |
5 | 5 | import io.socket.engineio.server.Transport; |
| 6 | +import io.socket.parseqs.ParseQS; |
| 7 | +import org.json.JSONArray; |
| 8 | +import org.json.JSONObject; |
6 | 9 |
|
7 | 10 | import javax.servlet.ServletInputStream; |
8 | 11 | import javax.servlet.http.HttpServletRequest; |
@@ -69,23 +72,41 @@ public synchronized void send(List<Packet> packets) { |
69 | 72 | packets.add(new Packet(Packet.CLOSE)); |
70 | 73 | } |
71 | 74 |
|
72 | | - @SuppressWarnings("unchecked") |
73 | | - final boolean supportsBinary = (!((Map<String, String>) mRequest.getAttribute("query")).containsKey("b64")); |
| 75 | + //noinspection unchecked |
| 76 | + final Map<String, String> query = (Map<String, String>) mRequest.getAttribute("query"); |
| 77 | + |
| 78 | + final boolean supportsBinary = !query.containsKey("b64"); |
| 79 | + final boolean jsonp = query.containsKey("j"); |
74 | 80 |
|
75 | 81 | if(packets.size() == 0) { |
76 | 82 | throw new IllegalArgumentException("No packets to send."); |
77 | 83 | } |
78 | 84 | ServerParser.encodePayload(packets.toArray(new Packet[0]), supportsBinary, data -> { |
79 | | - final String contentType = (data instanceof String)? "text/plain; charset=UTF-8" : "application/octet-stream"; |
80 | | - final int contentLength = (data instanceof String)? ((String) data).length() : ((byte[]) data).length; |
| 85 | + final String contentType; |
| 86 | + final byte[] contentBytes; |
| 87 | + |
| 88 | + if (jsonp) { |
| 89 | + final String jsonpIndex = query.get("j").replaceAll("[^0-9]", ""); |
| 90 | + final String jsonContentString = (data instanceof String)? |
| 91 | + JSONObject.quote((String)data) : |
| 92 | + JSONObject.valueToString(new JSONArray(data)); |
| 93 | + final String jsContentString = jsonContentString |
| 94 | + .replace("\u2028", "\\u2028") |
| 95 | + .replace("\u2029", "\\u2029"); |
| 96 | + final String contentString = "___eio[" + jsonpIndex + "](" + jsContentString + ")"; |
| 97 | + |
| 98 | + contentType = "text/javascript; charset=UTF-8"; |
| 99 | + contentBytes = contentString.getBytes(StandardCharsets.UTF_8); |
| 100 | + } else { |
| 101 | + contentType = (data instanceof String)? "text/plain; charset=UTF-8" : "application/octet-stream"; |
| 102 | + contentBytes = (data instanceof String)? ((String)data).getBytes(StandardCharsets.UTF_8) : ((byte[])data); |
| 103 | + } |
81 | 104 |
|
82 | 105 | mResponse.setContentType(contentType); |
83 | | - mResponse.setContentLength(contentLength); |
| 106 | + mResponse.setContentLength(contentBytes.length); |
84 | 107 |
|
85 | 108 | try (OutputStream outputStream = mResponse.getOutputStream()) { |
86 | | - // TODO: Support JSONP |
87 | | - byte[] writeBytes = (data instanceof String)? ((String) data).getBytes(StandardCharsets.UTF_8) : ((byte[]) data); |
88 | | - outputStream.write(writeBytes); |
| 109 | + outputStream.write(contentBytes); |
89 | 110 | } catch (IOException ex) { |
90 | 111 | onError("write failure", ex.getMessage()); |
91 | 112 | } |
@@ -148,15 +169,25 @@ private void onPollRequest(@SuppressWarnings("unused") HttpServletRequest reques |
148 | 169 | } |
149 | 170 |
|
150 | 171 | private void onDataRequest(final HttpServletRequest request, final HttpServletResponse response) throws IOException { |
| 172 | + //noinspection unchecked |
| 173 | + final Map<String, String> query = (Map<String, String>) mRequest.getAttribute("query"); |
| 174 | + |
151 | 175 | final boolean isBinary = request.getContentType().equals("application/octet-stream"); |
| 176 | + final boolean jsonp = query.containsKey("j"); |
152 | 177 |
|
153 | 178 | try(final ServletInputStream inputStream = request.getInputStream()) { |
154 | 179 | final byte[] mReadBuffer = new byte[request.getContentLength()]; |
155 | 180 |
|
156 | 181 | //noinspection ResultOfMethodCallIgnored |
157 | 182 | inputStream.read(mReadBuffer, 0, mReadBuffer.length); |
158 | 183 |
|
159 | | - onData((isBinary)? mReadBuffer : (new String(mReadBuffer, StandardCharsets.UTF_8))); |
| 184 | + if (jsonp) { |
| 185 | + final String packetPayloadRaw = ParseQS.decode(new String(mReadBuffer, StandardCharsets.UTF_8)).get("d"); |
| 186 | + final String packetPayload = packetPayloadRaw.replace("\\n", "\n"); |
| 187 | + onData(packetPayload); |
| 188 | + } else { |
| 189 | + onData((isBinary)? mReadBuffer : (new String(mReadBuffer, StandardCharsets.UTF_8))); |
| 190 | + } |
160 | 191 | } |
161 | 192 |
|
162 | 193 | response.setContentType("text/html"); |
|
0 commit comments