Today, I continue working through the SPDY server push issue in my node-spdy fork that is resulting in:
Today I am going to focus on the SYN_STREAM frames (identified by an ID of 2):
...In the non-push conversations, the packet look like:
t=1306553787485 [st=45] SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 20
--> stream_id = 2
t=1306553787485 [st=45] SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 0
--> stream_id = 2
t=1306553787485 [st=45] SPDY_SESSION_SEND_RST_STREAM
--> status = 1
--> stream_id = 1
...
t=1306632639034 [st= 46] SPDY_SESSION_SYN_REPLYI start by comparing the data seen in Wireshark against the spec:
--> flags = 0
--> accept-ranges: bytes
cache-control: public, max-age=0
connection: keep-alive
content-length: 698
content-type: text/html; charset=UTF-8
etag: "698-1306200491000"
last-modified: Tue, 24 May 2011 01:28:11 GMT
status: 200 OK
version: HTTP/1.1
--> id = 1
t=1306632639035 [st= 47] SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 698
--> stream_id = 1
t=1306632639035 [st= 47] SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 0
--> stream_id = 1
+----------------------------------+Ah, well that would explain it. There is no associated stream ID.
80 02 00 01 |1| 1 | 1 |
+----------------------------------+
02 00 00 3b | Flags (8) | Length (24 bits) |
+----------------------------------+
00 00 00 02 |X| Stream-ID (31bits) |
+----------------------------------+
00 00 00 00 |X|Associated-To-Stream-ID (31bits)|
+----------------------------------+
00 01 62 60 | Pri | Unused | |
+------------------ |
64 60 06 05 | Name/value header block |
81 42 46 49 | ... |
49 41 b1 95
be 3e 28 31
e5 80 8a 0c 2b 0b 03 0b 43 fd e2 92
ca 9c 54 bd e4 e2 62 00 00 00 00 ff ff 02 00 00
00 ff ff
Digging through the code a bit, I find that the associated stream ID is written by the very long
function nvsToBuffer(zlib, headers, nvs) {When I reload, I find:
//...
// Insert assocStreamID for SYN_STREAM
console.log(buff);
buff.writeUInt32(assocStreamID & 0x7fffffff, 6, 'big');
console.log(buff);
//...
console.log(buff);
return buff;
};
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>All right. It seems to be set as expected. So where do things go wrong?
<Buffer 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>
<Buffer 00 00 00 02 00 00 00 00 00 01 62 60 64 60 06 05 81 42 46 49 49 41 b1 95 be 3e 28 31 e5 80 8a 0c 2b 0b 03 0b 43 fd e2 92 ca 9c 54 bd e4 e2 62 00 00 00 00 ff ff 02 00 00 00 ff ff>
It turns out that it is set as expected, but in the wrong place. The assembled packet looks very familiar:
<Buffer 80 02 00 01 02 00 00 3b 00 00 00 02 00 00 00 00 00 01 62 60 64 60 06 05 81 42 46 49 49 41 b1 95 be 3e 28 31 e5 80 8a 0c 2b 0b 03 0b 43 fd e2 92 ca 9c 54 bd e4 e2 62 00 00 00 00 ff ff 02 00 00 00 ff ff>That is the same packet that I saw in Wireshark... Ah, the associated stream ID is being set, just in the wrong place:
+----------------------------------+As-is, it is not the associated stream ID, but the Primary flag.
80 02 00 01 |1| 1 | 1 |
+----------------------------------+
02 00 00 3b | Flags (8) | Length (24 bits) |
+----------------------------------+
00 00 00 02 |X| Stream-ID (31bits) |
+----------------------------------+
00 00 00 00 |X|Associated-To-Stream-ID (31bits)|
+----------------------------------+
00 01 62 60 | Pri | Unused | |
+------------------ |
64 60 06 05 | Name/value header block |
81 42 46 49 | ... |
49 41 b1 95
be 3e 28 31
e5 80 8a 0c 2b 0b 03 0b 43 fd e2 92
ca 9c 54 bd e4 e2 62 00 00 00 00 ff ff 02 00 00
00 ff ff
I cannot quite follow the bit flipping that goes on in the
nvsToBuffer
method, but I can easily move the associated stream ID location back two bytes by switching this:buff.writeUInt32(assocStreamID & 0x7fffffff, 6, 'big');To this:
buff.writeUInt32(assocStreamID & 0x7fffffff, 4, 'big');With that, I get my packet printing out as desired:
+----------------------------------+But the real test is the browser, does it work any better now?
80 02 00 01 |1| 1 | 1 |
+----------------------------------+
02 00 00 3b | Flags (8) | Length (24 bits) |
+----------------------------------+
00 00 00 02 |X| Stream-ID (31bits) |
+----------------------------------+
00 00 00 01 |X|Associated-To-Stream-ID (31bits)|
+----------------------------------+
00 00 62 60 | Pri | Unused | |
+------------------ |
64 60 06 05 | Name/value header block |
81 42 46 49 | ... |
49 41 b1 95
be 3e 28 31
e5 80 8a 0c 2b 0b 03 0b 43 fd e2 92 ca 9c 54 bd e4 e2 62 00 00 00 00 ff ff 02 00 00 00 ff ff
Sadly, no:
Grrr... it seems that the problem is elsewhere. I will pick back up with that tomorrow, but first I will cherry-pick the associated stream ID fix back into master so that I can submit a pull request.
Day #33
No comments:
Post a Comment