I think that I want a better API for pushing SPDY data before and after responses than:
var app = module.exports = express.createServer({Ultimately, I think I would like to be able to tell the SPDY server that, for a given resource, push this data before the response and that data after the response. I think I want that, but I am not sure. What I do know is that I made a bit of a mess of the
// ...
push: function(pusher) {
// Only push in response to the first request
if (pusher.streamID > 1) return;
pusher.push_file("public/stylesheets/style.css", "https://localhost:3000/stylesheets/style.css");
},
push_after: 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");
}
});
Response#write
method in node-spdy.Uncertainty and messy code. Sounds like a good time to write some tests.
Node-spdy uses vows.js for its testing, so I start on a
test/response-test.js
file.There is a bit of setup for a control frame that is required for
createResponse()
, so I make that setup the topic of my first batch of tests:vows.describe('Pushing Additional Resources').addBatch({For now, I do not want to test directly on that
'A response': {
topic: function() {
var cframe = spdy.createControlFrame(spdy.createZLib(), {
type: spdy.enums.SYN_STREAM,
streamID: 1,
priority: 0,
flags: 0
}, {
version: 'HTTP/1.1',
url: '/',
method: 'GET'
});
var connection = {
zlib: spdy.createZLib(),
write: function() {}
};
return spdy.createResponse(cframe, connection);
}
}
}).run();
Response
object. Rather, I want to verify that my push-stream callbacks are being called. Fortunately, vows makes it easy to verify that a callback is called with the this.callback
construct. If this.callback
is called, its arguments become the topic of the test:vows.describe('Pushing Additional Resources').addBatch({Finally, I can verify not only that my push-stream callbacks are called, but are called with the
'A response': {
topic: function() {
// ...
return spdy.createResponse(cframe, connection);
},
'with a push_stream call': {
topic: function (response) {
var callback = this.callback;
response.setPush(callback);
response._write('foo');
}
}
}
}).run();
Response
object itself:vows.describe('Pushing Additional Resources').addBatch({Unfortunately, when I run my assembled vows, I am greeted with:
'A response': {
topic: function() {
// ...
return spdy.createResponse(cframe, connection);
},
'with a push_stream call': {
topic: function (response) {
var callback = this.callback;
response.setPush(callback);
response._write('foo');
},
'should push data on write': function (pusher) {
assert.equal(pusher, response);
}
}
}
}).run();
➜ node-spdy git:(post-response-push) ✗ node test/response-test.jsThat undefined bit of code from
node.js:183
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Cannot read property 'streamID' of undefined
at new <anonymous> (/home/cstrom/repos/node-spdy/lib/spdy/response.js:22:30)
...
Response
is the data
attribute of the cframe
that I created in my original topic.Hrmm...
Ah, it seems that
cframes
s and dframe
s, at least when downstream objects receive them, are not Buffers wrapped in an object. Rather they are just objects:this.emit(headers.c ? 'cframe' : 'dframe', {That simplifies my testing a bit, but now when I run my vows, I get:
headers: headers,
data: data
});
➜ node-spdy git:(post-response-push) ✗ vows test/response-test.js"An unexpected error was caught"? What does that mean? Did I throw that object somewhere deep in the bowels of node-spdy?
✗
A response with a push_stream call
✗ should push data on write
» An unexpected error was caught: {"cframe":{"0":128,"1":2,"2":0,"3":1,"4":0,"5":0,"6":0,"7":50,"8":0,"9":0,"10":0,"11":1,"12":0,"13":0,"14":0,"15":0,"16":189,"17":0,"18":120,"19":187,"20":223,"21":162,"22":81,"23":178,"24":98,"25":96,"26":102,"27":96,"28":135,"29":114,"30":25,"31":56,"32":96,"33":170,"34":24,"35":152,
...
Googling this error, I come across this post from a very clever author. Reading through that post leads me to ask...
How can I be the only idiot making that mistake?!
OK, so callback needs to be called with two arguments. My push-streams only callback with a single argument.
var response = spdy.createResponse(cframe, connection);With that, I finally have my vows in working order:
vows.describe('Pushing Additional Resources').addBatch({
'A response': {
topic: response,
'with a push_stream call': {
topic: function (response) {
var callback = this.callback;
response.setPush(function(pusher) {callback(null, pusher)});
response._write();
},
'should push data on write': function (pusher) {
assert.equal(pusher, response);
}
}
}
}).export(module);
➜ node-spdy git:(post-response-push) ✗ vows test/response-test.js --specI call it a day there. I have made a good faith attempt at getting started on specs for server push in node-spdy. Tomorrow, I will build on this by adding tests for post-response push.
♢ Pushing Additional Resources
function
A response with a push_stream call
✓ should push data on write
✓ OK » 1 honored (0.003s)
But, for now, I'm off to write SPDY Book.
Day #60
No comments:
Post a Comment