From 885ebcf015c690ab69585ac77004c72d5d80b12c Mon Sep 17 00:00:00 2001 From: Mike Kazantsev Date: Thu, 25 Apr 2013 02:01:08 +0600 Subject: [PATCH 1/2] server.NotaryResponse: add Content-Length header --- server/convergence/NotaryResponse.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/convergence/NotaryResponse.py b/server/convergence/NotaryResponse.py index b802a06..b57527e 100644 --- a/server/convergence/NotaryResponse.py +++ b/server/convergence/NotaryResponse.py @@ -40,9 +40,6 @@ def signResponse(self, response): return json.dumps(response) def sendResponse(self, code, recordRows): - self.request.setHeader("Content-Type", "application/json") - self.request.setResponseCode(code) - fingerprintList = [] if recordRows is not None: @@ -52,9 +49,12 @@ def sendResponse(self, code, recordRows): 'timestamp' : timestamp } fingerprintList.append(fingerprint) + result = self.signResponse({'fingerprintList' : fingerprintList}) - result = {'fingerprintList' : fingerprintList} + self.request.setHeader('Content-Type', 'application/json') + self.request.setHeader('Content-Length', str(len(result))) + self.request.setResponseCode(code) - self.request.write(self.signResponse(result)) + self.request.write(result) self.request.finish() From 0774d2292f8b224247451b3f8e6f3057f9cd640b Mon Sep 17 00:00:00 2001 From: Mike Kazantsev Date: Thu, 25 Apr 2013 02:16:57 +0600 Subject: [PATCH 2/2] client: respect content-length header when reading data from client socket Fixes hangs on connections that don't get closed but have no more response data left. --- client/chrome/content/http/HttpParser.js | 23 ++++++++++++---- .../sockets/ConvergenceClientSocket.js | 27 ++++++++++--------- .../sockets/ConvergenceNotarySocket.js | 6 ++--- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/client/chrome/content/http/HttpParser.js b/client/chrome/content/http/HttpParser.js index 4e6f448..93a8f53 100644 --- a/client/chrome/content/http/HttpParser.js +++ b/client/chrome/content/http/HttpParser.js @@ -71,11 +71,24 @@ HttpParser.prototype.parseResponseCode = function(response) { HttpParser.prototype.readFully = function(socket) { var response = ""; var buf = null; - - while ((buf = socket.readString()) != null) { - response += buf; - dump("Read: " + buf + "\n"); + var length = null; + + while ((buf = socket.readString(length)) != null) { + response += buff; + + // Try to limit reads according to content-length header + if (length != null) length -= buff.length; + else { + var headers_end = response.indexOf('\r\n\r\n'); + if (headers_end != -1) { + var match = /(^|\r\n)content-length:\s+(\d+)\r\n/i + .exec(response.substring(0, headers_end+2)); + if (match) { + length = (headers_end + 4 + parseInt(match[2])) - response.length; + } + } + } } return response; -}; \ No newline at end of file +}; diff --git a/client/chrome/content/sockets/ConvergenceClientSocket.js b/client/chrome/content/sockets/ConvergenceClientSocket.js index 2f89428..2faddc8 100644 --- a/client/chrome/content/sockets/ConvergenceClientSocket.js +++ b/client/chrome/content/sockets/ConvergenceClientSocket.js @@ -129,11 +129,13 @@ ConvergenceClientSocket.prototype.writeBytes = function(buffer, length) { return NSPR.lib.PR_Write(this.fd, buffer, length); }; -ConvergenceClientSocket.prototype.readString = function() { - var buffer = new NSPR.lib.buffer(4096); +ConvergenceClientSocket.prototype.readString = function(length) { + if (length === null) length = 4095; + else if (length <= 0) return null; + var buffer = new NSPR.lib.buffer(length + 1); var read; - while (((read = NSPR.lib.PR_Read(this.fd, buffer, 4095)) == -1) && + while (((read = NSPR.lib.PR_Read(this.fd, buffer, length)) == -1) && (NSPR.lib.PR_GetError() == NSPR.lib.PR_WOULD_BLOCK_ERROR)) { dump("polling on read...\n"); @@ -151,21 +153,20 @@ ConvergenceClientSocket.prototype.readString = function() { }; ConvergenceClientSocket.prototype.readFully = function(length) { - var buffer = new NSPR.lib.buffer(length); - var read; + var response = ""; + var buffer; + var n = length; - while (((read = NSPR.lib.PR_Read(this.fd, buffer, length)) == -1) && - (NSPR.lib.PR_GetError() == NSPR.lib.PR_WOULD_BLOCK_ERROR)) - { - if (!this.waitForInput(-1)) - return null; + while ((buffer = this.readString(n)) != null) { + response += buffer; + n -= buffer.length; } - if (read != length) { + if (response.length != length) { throw "Assertion error on read fully (" + read + ", " + length + ")!"; } - return buffer; + return response; }; ConvergenceClientSocket.prototype.close = function() { @@ -186,4 +187,4 @@ ConvergenceClientSocket.prototype.waitForInput = function(timeoutMillis) { } return true; -}; \ No newline at end of file +}; diff --git a/client/chrome/content/sockets/ConvergenceNotarySocket.js b/client/chrome/content/sockets/ConvergenceNotarySocket.js index e72c5b5..753fd44 100644 --- a/client/chrome/content/sockets/ConvergenceNotarySocket.js +++ b/client/chrome/content/sockets/ConvergenceNotarySocket.js @@ -21,8 +21,8 @@ ConvergenceNotarySocket.prototype.writeBytes = function(buffer, length) { return this.connection.writeBytes(buffer, length); }; -ConvergenceNotarySocket.prototype.readString = function() { - return this.connection.readString(); +ConvergenceNotarySocket.prototype.readString = function(length) { + return this.connection.readString(length); }; ConvergenceNotarySocket.prototype.readFully = function(length) { @@ -31,4 +31,4 @@ ConvergenceNotarySocket.prototype.readFully = function(length) { ConvergenceNotarySocket.prototype.close = function() { return this.connection.close(); -}; \ No newline at end of file +};