PhantomJS: Ensuring that the response object stays alive in server.listen(...)

Viewed 3358

I'm using server.listen(...) from PhantomJS. I realize that it is largely experimental and that it shouldn't be used in production. I'm using it for a simple screenshot-server that accepts generates screenshots for a URL; it's a toy project that I'm using to play around with PhantomJS. I've noticed an issue with long-running requests in particular, where the response object is unavailable. Here are the relevant snippets from my code:

var service = server.listen(8080, function (request, response) {

    response.statusCode = 200;

    if (loglevel === level.VERBOSE) {
        log(request);
    } else {
        console.log("Incoming request with querystring:", request.url);
    }

    var params = parseQueryString(request.url);
    if (params[screenshotOptions.ACTION] === action.SCREENSHOT) {
        getScreenshot(params, function (screenshot) {

            response.headers["success"] = screenshot.success; //<-- here is where I get the error that response.headers is unavailable. Execution pretty much stops at that point for that particular request.
            response.headers["message"] = screenshot.message;

            if (screenshot.success) {
                response.write(screenshot.base64);
            } else {
                response.write("<html><body>There were errors!<br /><br />");
                response.write(screenshot.message.replace(/\n/g, "<br />"));
                response.write("</body></html>");
            }

            response.close();
        });
    } else {
        response.write("<html><body><h1>Welcome to the screenshot server!</h1></body></html>")   
        response.close();
    }
});

getScreenshot is an asynchronous method that uses the WebPage.open(...) function to open a webpage; this function is also asynchronous. So what seems to be happening is that when the callback that is passed in as an argument to getScreenshot is finally called, it appears that the response object has already been deleted. I basically end up with the following error from PhantomJS:

Error: cannot access member `headers' of deleted QObject

I believe this is because the request times out and so the connection is closed. The documentation mentions calling response.write("") at least once to ensure that the connection stays open. I tried calling response.write("") at the beginning of server.listen(...) and I even tried a pretty hacky solution where I used setInterval(...) to perform a response.write("") every 500 milliseconds (I even lowered it down to as little as 50). I also made sure to clear the interval once I was done. However, I still seem to get this issue.

Is this something that I'm just going to have to deal with until they make the webserver module more robust? Or is there a way around it?

2 Answers
Related