michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=8 sts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: const CC = Components.Constructor; michael@0: const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", michael@0: "nsIBinaryInputStream", michael@0: "setInputStream"); michael@0: michael@0: function DEBUG(str) michael@0: { michael@0: // dump("********** " + str + "\n"); michael@0: } michael@0: michael@0: function setOurState(data) { michael@0: x = { data: data, QueryInterface: function(iid) { return this } }; michael@0: x.wrappedJSObject = x; michael@0: setObjectState("beacon-handler", x); michael@0: DEBUG("our state is " + data); michael@0: } michael@0: michael@0: function getOurState() { michael@0: var data; michael@0: getObjectState("beacon-handler", function(x) { michael@0: // x can be null if no one has set any state yet michael@0: if (x) { michael@0: data = x.wrappedJSObject.data; michael@0: } michael@0: }); michael@0: return data; michael@0: } michael@0: michael@0: function handleRequest(request, response) { michael@0: DEBUG("Entered request handler"); michael@0: response.setHeader("Cache-Control", "no-cache", false); michael@0: michael@0: function finishControlResponse(response) { michael@0: DEBUG("********* sending out the control GET response"); michael@0: var data = getState("beaconData"); michael@0: var mimetype = getState("beaconMimetype"); michael@0: DEBUG("GET was sending : " + data + "\n"); michael@0: DEBUG("GET was sending : " + mimetype + "\n"); michael@0: var result = { michael@0: "data": data, michael@0: "mimetype": mimetype, michael@0: }; michael@0: response.write(JSON.stringify(result)); michael@0: setOurState(null); michael@0: } michael@0: michael@0: if (request.method == "GET") { michael@0: DEBUG(" ------------ GET --------------- "); michael@0: response.setHeader("Content-Type", "application/json", false); michael@0: switch (request.queryString) { michael@0: case "getLastBeacon": michael@0: var state = getOurState(); michael@0: if (state === "unblocked") { michael@0: finishControlResponse(response); michael@0: } else { michael@0: DEBUG("GET has arrived, but POST has not, blocking response!"); michael@0: setOurState(response); michael@0: response.processAsync(); michael@0: } michael@0: break; michael@0: default: michael@0: response.setStatusLine(request.httpVersion, 400, "Bad Request"); michael@0: break; michael@0: } michael@0: return; michael@0: } michael@0: michael@0: if (request.method == "POST") { michael@0: DEBUG(" ------------ POST --------------- "); michael@0: var body = new BinaryInputStream(request.bodyInputStream); michael@0: var avail; michael@0: var bytes = []; michael@0: michael@0: while ((avail = body.available()) > 0) { michael@0: Array.prototype.push.apply(bytes, body.readByteArray(avail)); michael@0: } michael@0: michael@0: var data = ""; michael@0: for (var i=0; i < bytes.length; i++) { michael@0: // We are only passing strings at this point. michael@0: if (bytes[i] < 32) continue; michael@0: var charcode = String.fromCharCode(bytes[i]); michael@0: data += charcode; michael@0: } michael@0: michael@0: var mimetype = request.getHeader("Content-Type"); michael@0: michael@0: // check to see if this is form data. michael@0: if (mimetype.indexOf("multipart/form-data") != -1) { michael@0: michael@0: // trim the mime type to make testing easier. michael@0: mimetype = "multipart/form-data"; michael@0: // Extract only the form-data name. michael@0: michael@0: var pattern = /; name=\"(.+)\";/; michael@0: data = data.split(pattern)[1]; michael@0: } michael@0: michael@0: DEBUG("********** POST was sending : " + data + "\n"); michael@0: DEBUG("********** POST was sending : " + mimetype + "\n"); michael@0: setState("beaconData", data); michael@0: setState("beaconMimetype", mimetype); michael@0: michael@0: response.setHeader("Content-Type", "text/plain", false); michael@0: response.write('ok'); michael@0: michael@0: var blockedResponse = getOurState(); michael@0: if (typeof(blockedResponse) == "object" && blockedResponse) { michael@0: DEBUG("GET is already pending, finishing!"); michael@0: finishControlResponse(blockedResponse); michael@0: blockedResponse.finish(); michael@0: } else { michael@0: DEBUG("GET has not arrived, marking it as unblocked"); michael@0: setOurState("unblocked"); michael@0: } michael@0: michael@0: return; michael@0: } michael@0: michael@0: response.setStatusLine(request.httpVersion, 402, "Bad Request"); michael@0: }