167 Log.logTrace("Reading payloadData: data={0}", data); 168 unconsumedPayloadLen -= data.remaining(); 169 boolean isLast = unconsumedPayloadLen == 0; 170 if (opcode.isControl()) { 171 if (binaryData != null) { // An intermediate or the last chunk 172 binaryData.put(data); 173 } else if (!isLast) { // The first chunk 174 int remaining = data.remaining(); 175 // It shouldn't be 125, otherwise the next chunk will be of size 176 // 0, which is not what Reader promises to deliver (eager 177 // reading) 178 assert remaining < 125 : dump(remaining); 179 binaryData = ByteBuffer.allocate(125).put(data); 180 } else { // The only chunk 181 binaryData = ByteBuffer.allocate(data.remaining()).put(data); 182 } 183 } else { 184 part = determinePart(isLast); 185 boolean text = opcode == Opcode.TEXT || originatingOpcode == Opcode.TEXT; 186 if (!text) { 187 output.onBinary(part, data.slice()); 188 data.position(data.limit()); // Consume 189 } else { 190 boolean binaryNonEmpty = data.hasRemaining(); 191 CharBuffer textData; 192 try { 193 textData = decoder.decode(data, part == MessagePart.WHOLE || part == MessagePart.LAST); 194 } catch (CharacterCodingException e) { 195 throw new FailWebSocketException( 196 "Invalid UTF-8 in frame " + opcode, StatusCodes.NOT_CONSISTENT) 197 .initCause(e); 198 } 199 if (!(binaryNonEmpty && !textData.hasRemaining())) { 200 // If there's a binary data, that result in no text, then we 201 // don't deliver anything 202 output.onText(part, textData); 203 } 204 } 205 } 206 } 207 208 @Override 209 public void endFrame() { 210 if (opcode.isControl()) { 211 binaryData.flip(); 212 } 213 switch (opcode) { 214 case CLOSE: 215 char statusCode = NO_STATUS_CODE; 216 String reason = ""; 217 if (payloadLen != 0) { 218 int len = binaryData.remaining(); 219 assert 2 <= len && len <= 125 : dump(len, payloadLen); 220 statusCode = binaryData.getChar(); 221 if (!isLegalToReceiveFromServer(statusCode)) { 222 throw new FailWebSocketException( | 167 Log.logTrace("Reading payloadData: data={0}", data); 168 unconsumedPayloadLen -= data.remaining(); 169 boolean isLast = unconsumedPayloadLen == 0; 170 if (opcode.isControl()) { 171 if (binaryData != null) { // An intermediate or the last chunk 172 binaryData.put(data); 173 } else if (!isLast) { // The first chunk 174 int remaining = data.remaining(); 175 // It shouldn't be 125, otherwise the next chunk will be of size 176 // 0, which is not what Reader promises to deliver (eager 177 // reading) 178 assert remaining < 125 : dump(remaining); 179 binaryData = ByteBuffer.allocate(125).put(data); 180 } else { // The only chunk 181 binaryData = ByteBuffer.allocate(data.remaining()).put(data); 182 } 183 } else { 184 part = determinePart(isLast); 185 boolean text = opcode == Opcode.TEXT || originatingOpcode == Opcode.TEXT; 186 if (!text) { 187 output.onBinary(data.slice(), part); 188 data.position(data.limit()); // Consume 189 } else { 190 boolean binaryNonEmpty = data.hasRemaining(); 191 CharBuffer textData; 192 try { 193 textData = decoder.decode(data, part == MessagePart.WHOLE || part == MessagePart.LAST); 194 } catch (CharacterCodingException e) { 195 throw new FailWebSocketException( 196 "Invalid UTF-8 in frame " + opcode, StatusCodes.NOT_CONSISTENT) 197 .initCause(e); 198 } 199 if (!(binaryNonEmpty && !textData.hasRemaining())) { 200 // If there's a binary data, that result in no text, then we 201 // don't deliver anything 202 output.onText(textData, part); 203 } 204 } 205 } 206 } 207 208 @Override 209 public void endFrame() { 210 if (opcode.isControl()) { 211 binaryData.flip(); 212 } 213 switch (opcode) { 214 case CLOSE: 215 char statusCode = NO_STATUS_CODE; 216 String reason = ""; 217 if (payloadLen != 0) { 218 int len = binaryData.remaining(); 219 assert 2 <= len && len <= 125 : dump(len, payloadLen); 220 statusCode = binaryData.getChar(); 221 if (!isLegalToReceiveFromServer(statusCode)) { 222 throw new FailWebSocketException( |