Skip to content

Commit 6a62131

Browse files
committed
Fix issue with requests processed too fast
Some requests would fall across two netty messages. These were not handled correctly, and would result in a timeout in iOS.
1 parent 7143109 commit 6a62131

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

src/main/java/com/beowulfe/hap/impl/connections/LengthPrefixedByteArrayProcessor.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,76 @@
44
import java.util.Collection;
55
import java.util.LinkedList;
66

7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
710
class LengthPrefixedByteArrayProcessor {
811

912
private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
1013
private Byte firstLengthByteBuffer; //Only used if we've received a single byte at the start of a message
1114
private int targetLength = 0;
15+
16+
private final static Logger LOGGER = LoggerFactory.getLogger(LengthPrefixedByteArrayProcessor.class);
1217

1318
public synchronized Collection<byte[]> handle(byte[] data) {
1419
Collection<byte[]> results = new LinkedList<>();
1520
int pos = 0;
21+
LOGGER.trace("Received message of length {}. Existing buffer is {}", data.length, buffer.size());
1622
if (buffer.size() == 0) {
1723
while(data.length - pos > 18) {
1824
int targetLength = (data[0] & 0xFF) + (data[1] & 0xFF) * 256 + 16 + 2;
25+
LOGGER.trace("Attempting to read message of length {}", targetLength);
1926
if (data.length >= pos + targetLength) {
2027
byte[] b = new byte[targetLength - 2];
2128
System.arraycopy(data, pos+2, b, 0, targetLength-2);
2229
results.add(b);
30+
LOGGER.trace("Read complete message");
2331
pos = pos + targetLength;
2432
} else {
33+
LOGGER.trace("Not enough data available");
2534
break;
2635
}
2736
}
2837
}
2938
if (data.length > pos) {
39+
LOGGER.trace("Remaining data available");
3040
step(data, pos, results);
3141
}
42+
LOGGER.trace("Returning {} results", results.size());
3243
return results;
3344
}
3445

3546
private void step(byte[] data, int pos, Collection<byte[]> results) {
36-
if (buffer.size() == 0 && data.length == 1 + pos) {
47+
LOGGER.trace("Performing step operation on buffer of length {} with pos {}", data.length, pos);
48+
if (targetLength == 0 && data.length == 1 + pos) {
3749
firstLengthByteBuffer = data[pos];
50+
LOGGER.trace("Received a single byte message, storing byte {} for later", firstLengthByteBuffer);
3851
return;
3952
}
40-
if (buffer.size() == 0) {
53+
if (targetLength == 0) {
4154
if (firstLengthByteBuffer != null) {
42-
targetLength = firstLengthByteBuffer + data[pos] * 256 + 16;
55+
targetLength = (firstLengthByteBuffer & 0xFF) + (data[pos] & 0xFF) * 256 + 16;
4356
pos += 1;
57+
LOGGER.trace("Received the second byte after storing the first byte. New length is {}", targetLength);
4458
} else {
45-
targetLength = data[pos] + data[pos+1] * 256 + 16;
59+
targetLength = (data[pos] & 0xFF) + (data[pos+1] & 0xFF) * 256 + 16;
4660
pos += 2;
61+
LOGGER.trace("targetLength is {}", targetLength);
4762
}
4863
}
4964
int toWrite = targetLength - buffer.size();
50-
if (toWrite > data.length - pos) {
65+
if (toWrite <= data.length - pos) {
5166
//We have a complete message
67+
LOGGER.trace("Received a complete message");
5268
buffer.write(data, pos, toWrite);
5369
results.add(buffer.toByteArray());
5470
buffer.reset();
55-
step(data, pos + toWrite, results);
71+
targetLength=0;
72+
if (pos + toWrite > data.length) {
73+
step(data, pos + toWrite, results);
74+
}
5675
} else {
76+
LOGGER.trace("Storing {} bytes in buffer until we receive the complete {}", data.length-pos, targetLength);
5777
buffer.write(data, pos, data.length - pos);
5878
}
5979
}

0 commit comments

Comments
 (0)