Saturday, June 25, 2011

SPDY Server Push in express-spdy

‹prev | My Chain | next›

Having verified that multi-page sites work just fine in express-spdy, I am ready to investigate SPDY server push.

To test out navigating through multi-page SPDY sites, I added three static pages: one.html, two.html, and three.html. To test SPDY server push, I think I will try to push those pages out, along with the CSS for all three pages.

The syntax that I added to node-spdy looks like:
var options = {
// ...
push: function(pusher) {
// Only push in response to the first request
if (pusher.streamID > 1) return;

// It's also possible to conditionally respond based on the request
// var req = pusher.cframe.data.nameValues;
// if (req.url != "/") return;
// if (req.method != "GET") return;

pusher.push_file("pub/style.css", "https://localhost:8082/style.css");
pusher.push_file("pub/spdy.jpg", "https://localhost:8082/spdy.jpg");
}
};

var server = spdy.createServer(options, function(req, res) {
// ...
});
I will not fiddle with the request based push (described in the comment above) today. Instead I opt for a simpler route in my express-spdy app:
var app = module.exports = express.createServer({
//...
push: function(pusher) {
// Only push in response to the first request
if (pusher.streamID > 1) return;

pusher.push_file("public/one.html", "https://localhost:3000/one.html");
pusher.push_file("public/two.html", "https://localhost:3000/two.html");
pusher.push_file("public/three.html", "https://localhost:3000/three.html");
pusher.push_file("public/stylesheets/style.css", "https://localhost:3000/stylesheets/style.css");
}
});
When I make my first request to the express-spdy app (on stream ID #1), this should push out the three additional HTML pages along with style.css

And, checking things out in the SPDY tab of about:net-internals, I find:
# Request and SYN_REPLY for first page

...

#####
# The first pushed stream (one.html)
# Along with the associated data frames

t=1309021949666 [st= 98] SPDY_SESSION_PUSHED_SYN_STREAM
--> associated_stream = 1
--> flags = 2
--> status: 200
url: https://localhost:3000/one.html
version: http/1.1
--> id = 2
t=1309021949666 [st= 98] SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 208
--> stream_id = 2
t=1309021949666 [st= 98] SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 0
--> stream_id = 2

#####
# Second push frame (two.html)
t=1309021949667 [st= 99] SPDY_SESSION_PUSHED_SYN_STREAM
--> associated_stream = 1
--> flags = 2
--> status: 200
url: https://localhost:3000/two.html
version: http/1.1
--> id = 4
# Data frames omitted


#####
# Third push frame (three.html)
t=1309021949667 [st= 99] SPDY_SESSION_PUSHED_SYN_STREAM
--> associated_stream = 1
--> flags = 2
--> status: 200
url: https://localhost:3000/three.html
version: http/1.1
--> id = 6
# Data frames omitted

#####
# Fourth push frame (CSS)
t=1309021949667 [st= 99] SPDY_SESSION_PUSHED_SYN_STREAM
--> associated_stream = 1
--> flags = 2
--> status: 200
url: https://localhost:3000/stylesheets/style.css
version: http/1.1
--> id = 8
# Data frames omitted

#####
# Data frames for the original request (the homepage)
t=1309021949667 [st= 99] SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 303
--> stream_id = 1
t=1309021949667 [st= 99] SPDY_SESSION_RECV_DATA
--> flags = 0
--> size = 0
--> stream_id = 1

#####
# Yay! It's a real push stream now:
t=1309021949681 [st= 113] SPDY_STREAM_ADOPTED_PUSH_STREAM
...
That all looks good. It would be nice to send the three subsequent pages after the homepage data. The homepage only needs the HTML data and the stylesheet to render. The other stuff is nice-to-have for immediate (from browser cache) page loads, but the CSS is the only thing that really needs to be in cache before the browser starts rendering the homepage.

I will worry about that another day. For now, I just want to test out the secondary pages. If this has worked, there will be no subsequent requests to the server since SPDY server push has pushed everything into browser cache.

And it works! Kind of. There are no more page requests of the server, but the page one.html renders like:



Heh. Clearly I need to supply a content-type when pushing out HTML. Back when I had first tested out SPDY server push, I had only pushed CSS and images. It seems that Chrome is a bit more forgiving of those resources without content-type than it is of content-type-less HTML.

I am not going to solve that tonight. My initial goal of ensuring that SPDY server push works with express-spdy is satisfied (it works for CSS and image data). Tomorrow and the following day I will pick up with getting HTML to work and allowing data to be sent after the requested resource is sent to the browser.

For now, I am off to write more SPDY Book.

Day #58

No comments:

Post a Comment