We want to pass the response object (obtained from the server's callback function onRequest()) to the request handler through the request route. The handler can then respond to the request using functions on that object.
Let’s make changes to server.js first:
var http = require("http");
var url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " pathname " received.");
route(handle, pathname, response);
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
We pass the response object as the third parameter to the route() function, and we remove all response-related function calls in the onRequest() handler, because we want this part of the work to be done by the route() function to complete.
Next modify router.js:
function route(handle, pathname, response) {
console.log("About to route a request for " pathname);
if (typeof handle[pathname] === 'function') {
handle[pathname](response);
} else {
console.log("No request handler found for " pathname);
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not found");
response.end();
}
}
exports.route = route;
Same pattern: instead of getting the return value from the request handler, this time the response object is passed directly. If there is no corresponding request processor to process, we will directly return a "404" error.
Next modify requestHandler.js:
var exec = require("child_process").exec;
function start(response) {
console.log("Request handler 'start' was called.");
exec("ls -lah", function (error, stdout, stderr) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(stdout);
response.end();
});
}
function upload(response) {
console.log("Request handler 'upload' was called.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello Upload");
response.end();
}
exports.start = start;
exports.upload = upload;
Our handler function needs to receive the response parameter in order to respond directly to the request. The start handler does the request response operation in the anonymous callback function of exec(), while the upload handler still simply replies "Hello World", but this time it uses the response object.
If you want to prove that the time-consuming operations in the /start handler will not block the immediate response to the /upload request, you can modify requestHandlers.js to the following form:
var exec = require("child_process").exec;
function start(response) {
console.log("Request handler 'start' was called.");
exec("find /",
{ timeout: 10000, maxBuffer: 20000*1024 },
function (error, stdout, stderr) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(stdout);
response.end();
}
);
}
function upload(response) {
console.log("Request handler 'upload' was called.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello Upload");
response.end();
}
exports.start = start;
exports.upload = upload;
In this way, when requesting http://localhost:8888/start, it will take 10 seconds to load, but when requesting http://localhost:8888/upload, it will respond immediately , even though the /start response is still being processed at this time.