Post reply with node.js doesn't work

I've been working on a node.js based server for a project. Currently, I have a script on an html page that POSTS data to a jsp page on the same server - which works. However, I can't seem to send data back down the pipe. I've noted the same with various node.js posting scripts.

EDIT: Where I say JSP, I just mean standard javascript; I just made pages with .jsp extensions instead of .js so I could still send scripts as .js.

EDIT 2: The headers /do/ get sent. It just appears that response.write() or reponse.end() aren't acutally sending anything.. I've tried gzipping the data and changing the transfer-encoding header to match with no luck. Think I might wireshark it.

EDIT 3: Wireshark can't detect the POSTs for some reason >.>

EDIT 4: Noticed that response.write() is returning false. Not sure how to debug. I'll add some more code at the end.

Here's the JSP page's code.

/**
 * This POST parser takes XML data and translates it as follows..
 * 
 * XML -> JS Object -> XML
 * 
 * This is so I can test some libraries.
 */

// Eyes, to inspect variables
var inspect = require('eyes').inspector({maxLength: false});

// This is an XML parser, that parses XML into standard JS arrays
var xml2js = require('xml2js');

// This one converts JSON (Or JS objects) to XML.
var jsontoxml = require('jsontoxml');

exports.seperateHeader = false; // We have no separate header function
exports.separateEnd = true;

exports.GET = function(query, request, response) { // Our GET function.

    response.writeHead(200, { // Write the header
        'Content-Type': 'text/plain; charset=utf-8'
    });

    response.end("No POST data here!"); // Tell the user that there was no POST data.
}

exports.POST = function(query, postdata, request, response) { // Out POST function.

    var rootnode = undefined;
    var realdata = undefined;
    var result = undefined;

    if( postdata["data"].startsWith("<?xml") ) // It's XML, parse it
    {
        console.log("      | Detected XML.");
        var parser = new xml2js.Parser(); // Create an XML parser
        parser.parseString(postdata["data"], function (err, data) { // Parse the XML from the POST data
            if(err){
                inspect(err); // If we have an error, inspect it with eyes
            }
            else
            {
                // inspect(result); // Removed; printed the XML data as an array

                for (var prop in data) { // Get the root node of our XML; this is the command
                    rootnode = prop;
                    break;
                }

                realdata = data[rootnode]; // Get the data without the root node
                result = data;
            }
        });
    }
    else // Try to parse it as JSON
    {
        console.log("      | Detected JSON.");
        result = JSON.parse(postdata["data"]);
        for (var prop in result) { // Get the root node of our JSON; this is the command
            rootnode = prop;
            break;
        }

        realdata = result[rootnode]; // Get the data without the root node
    }
    console.log("      | Before: ")
    inspect(postdata["data"]); // Inspect the data we've got (XML or JSON)
    console.log("      | Native object: ")
    inspect(result); // Inspect the data that's been parsed to an object
    console.log("      | XML: ")
    xmldata = jsontoxml.obj_to_xml(result) // Object -> XML
    xmldata = '<?xml version="1.0" encoding="UTF-8"?><Request>' + xmldata + "</Request>"; // WUPOS extra XML stuff and the XML header
    inspect(xmldata); // Inspect the XML created from the object

    response.writeHead(200, { // Write the header
        'Content-Type':   'text/plain; charset=utf-8',
        'Content-Length': xmldata.length
    });

    response.write(xmldata); 
}

And here is the internal code for the http response..

var fs = require('fs');
var url = require('url');
var path = require('path');
var querystring = require("querystring")

var ext = require("./ext.js").ext // For getting MIME types (I know, there's another module for this)

// Logging function
function Log(message, prefix, isSecure)
{
    if (!prefix)
    {
        prefix = "     ";
    }
    else
    {
        if (isSecure)
        {
            prefix = "HTTPS";
        }
        else
        {
            prefix = "HTTP ";
        }
    }

    console.log(prefix + " | " + message);
}

exports.Log = Log;

// httpRequest; this function serves standard HTTP requests
function httpRequest(request, response, isSecure) {
    request.setEncoding('utf-8'); // Set the encoding
    requrl = url.parse(request.url, true); // Parse the URL
    reqhost = request.connection.address();// Get the IP and port of the user

    if (requrl.pathname == "/") // If they were requesting the root..
    {   
        if (path.existsSync("../html/index.jsp")) // If index.jsp exists..
        {   
            reqfile = "/index.jsp"; // Remember that we want that file
        }
        else // Otherwise, index.html
        {
            reqfile = "/index.html"; 
        }
        // Log it
        if (requrl.search) { 
            Log( 
                "[" + reqhost.address + ":" + reqhost.port + "] " + request.method + " " + reqfile + requrl.search + " (Redirected from \"/\")", 
                true, isSecure
            ); 
        }
        else { 
            Log( 
                "[" + reqhost.address + ":" + reqhost.port + "] " + request.method + " " + reqfile + " (Redirected from \"/\")", 
                true, isSecure
            ); 
        }
    }
    else // If not,
    {   // Log it,
        Log( 
            "[" + reqhost.address + ":" + reqhost.port + "] " + request.method + " " + requrl.href
            , true, isSecure
        );
        reqfile = requrl.pathname; // Remember which file was requested
    }



    if (reqfile.endsWith(".jsp")) { // If the file is a JS page
        try { // Try..
            reqjs = require("../html/" + reqfile); // ..to import the code from our script
            if (reqjs.separateHeader) { // If the script has a separate function for sending the header..
                reqjs.headers(request, response); // Send it
            }
            if (request.method == 'GET') // If we have a GET
            {
                reqjs.GET(requrl.query, request, response); // Run the script's GET function
            }
            else if (request.method == 'POST') // If we have a POST
            {
                // Grab all the POST data
                var fullBody = '';

                request.on('data', function(chunk) {
                    if(fullBody.length > 1e6) // If we're getting a massive amount of data, kill the connection
                    {
                        Log("POST flood attack / faulty client detected. Connection closed.", false, isSecure);
                        request.connection.destroy();
                        return;
                    }
                    fullBody += chunk.toString();
                });

                request.on('end', function() {
                    var postdata = querystring.parse(fullBody); // Parse the POST data
                    if (reqjs.POST) // If the script has a POST function,
                    {
                        reqjs.POST(requrl.query, postdata, request, response); // Call it
                    }
                    else
                    {   // Otherwise, just call the GET function
                        reqjs.GET(requrl.query, request, response);
                    }
                });
            }
        }
        catch(e) // If there's an error..
        {
            response.writeHead(500, {
                'Content-Type': 'text/plain'
            });
            response.write("Error: " + e); // Send it to the browser
            Log("Error: " + e, false, isSecure); // Log it
        }
        response.end(); // Finish the response
    }
    else // If the file is not a JS page,
    {
        fs.readFile("html" + reqfile, function(err, data) { // Read the file in
            if(err) { // If there's an error..
                errortype = err.message.split(",")[0]; // ..get the error's code
                if (errortype == "ENOENT") // File not found
                {
                    response.statusCode = 404;
                    response.end("File not found: " + reqfile); // Send them a 404
                    Log("File not found.", false, isSecure); // Log it
                }
                else if (errortype == "EISDIR") // File is actually a directory
                {   
                    if (path.existsSync("html" + reqfile + "/index.jsp")) // If there's an index.jsp file here..
                    {   // Redirect the browser
                        Log("Found index.jsp", false, isSecure);
                        response.writeHead(301, "Moved Permanently", {
                            "Location" : reqfile + "/index.jsp"
                        });
                        response.end("<a href=\"" + reqfile + "/index.jsp" + "\">Please click here.</a>") 
                        return; // Return, so we don't have to wrap the next section of code in braces
                    }
                    else if (path.existsSync("html" + reqfile + "/index.html")) // Or, if there's an index.html file here..
                    {   // Redirect the browser
                        Log("Found index.html", false, isSecure);
                        response.writeHead(301, "Moved Permanently", {
                            "Location" : reqfile + "/index.html"
                        });
                        response.end("<a href=\"" + reqfile + "/index.html" + "\">Please click here.</a>")
                        return; // Return, so we don't have to wrap the next section of code in braces
                    }
                    // If we don't have those files, list them
                    Log("Listing files in html/"+reqfile, false, isSecure); // Log it

                    response.statusCode = 200; // Use Node.js's standard "OK" header
                    // Write out some HTML
                    response.write("<html><head></head><body>\n");
                    response.write("<h1>Directory listing: " + reqfile + "</h1>\n");
                    response.write("<ul>\n");
                    // List off the files
                    var filelist = fs.readdirSync("html" + reqfile);

                    // For every file..
                    for (element in filelist)
                    {
                        // Compile some HTML
                        var datastr = "";
                        datastr += "<li>";
                        datastr += "<a href=\"" + reqfile + "/" + filelist[element] + "\">";
                        if (filelist[element].endsWith(".jsp") || filelist[element].endsWith(".html"))
                        {   // If it ends in html or js, it's a normal page, so colour it green
                            datastr += "<span style=\"color: green;\">";
                            datastr += filelist[element];
                            datastr += "</span></a>";
                        }
                        else
                        {   // Otherwise, just put it in the list
                            datastr += filelist[element];
                            datastr += "</a>";
                        }

                        datastr += "</li>\n";
                        response.write(datastr); // Write out the HTML and go around again
                    }
                    response.end("</ul></body></html>"); // Finish the response
                }
                else
                {   // There was some other problem when opening the file
                    Log("Could not open file: " + err, false, isSecure); // Log it
                    response.statusCode = 501 // Internal server error code
                    response.end("Could not open file: " + err.message); // Tell the browser
                }
            }
            else
            {   // No problems or anomalies. Serve it!
                var contenttype = ext.getContentType(ext.getExt(reqfile).replace(".", "")); // Get the MIME type
                Log("Content-Type: " + contenttype, false, isSecure); // Log it
                response.writeHead(200, "OK", {
                    'Content-Type': contenttype
//                  'Access-Control-Allow-Origin': 'http://b.localhost:25566',
//                  'Access-Control-Allow-Methods': 'POST, GET',
//                  'Access-Control-Allow-Headers': 'Content-Type'
                });
                response.write(data); // Send the data (TODO: Send in chunks?)
                response.end() // End
            }
        });
    }
}

exports.httpRequest = httpRequest;

And the code for the html page..

<html>

<head>
    <title>JS test A</title>
    <script src="js/jquery.js"></script>
</head>

<body style="margin-left: 30%; margin-right: 30%;">
    <div id="tests" style="float:left; width=40%;">
        <a href="#" id="a">Test A</a>
    </div>

    <div id="output" style="float:right; width=60%;">
        <form id="form">
            <textarea id="output" name="output"></textarea>
        </form>
    </div>

    <script>
        $(document).ready(function(){
            $("a#a").click(function(event){
                text = $("textarea").val();
                $("textarea").val(text + "POST test.\n");
                text = $("textarea").val();
                var http = new XMLHttpRequest();

                jsonobj = {
                    array: {
                        obj1: "obj1",
                        obj2: "obj2"
                    },
                    obj3: "obj3"
                }

                var url = "postTest3.jsp";
                var params = "data="+JSON.stringify(jsonobj);
                http.open("POST", url, true);

                //Send the proper header information along with the request
                http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

                http.onreadystatechange = function() {//Call a function when the state changes.
                    if(http.readyState == 4 && http.status == 200) {
                        $("textarea").val(text + http.responseText);
                    }
                    else
                    {
                        $("textarea").val(text + "Repsponded: " + http.status + "\n");
                    }
                }
                http.send(params);  

            });
        });


    </script>
</body>

</html>

EDIT 4: Additional code

{
                // Grab all the POST data
                var fullBody = '';

                request.on('data', function(chunk) {
                    if(fullBody.length > 1e6) // If we're getting a massive amount of data, kill the connection
                    {
                        Log("POST flood attack / faulty client detected. Connection closed.", false, isSecure);
                        request.connection.destroy();
                        return;
                    }
                    fullBody += chunk.toString();
                });

                request.on('end', function() {
                    var postdata = querystring.parse(fullBody); // Parse the POST data
                    if (reqjs.POST) // If the script has a POST function,
                    {
                        postout = reqjs.POST(requrl.query, postdata, request, response); // Call it
                        if (postout) {
                            inspect(response.write(postout, 'utf8'));
                        }
                    }
                    else
                    {   // Otherwise, just call the GET function
                        reqjs.GET(requrl.query, request, response);
                    }
                });
            }

Does anyone have any ideas on this?

Okay, so, I fixed the problem. Thought I'd share my solution here.

Basically, after adding some inspect() calls, it turned out that because reponse.write() was being carried out asynchronously, and response.end() wasn't, response.end() was being called first. This is why response.write() returned false.

I fixed it by moving the response.end() into my asynchronous blocks.