diff -r c1dce8630555 -r 8b07adc3cb87 RefactoringRope/JsonClient.py --- a/RefactoringRope/JsonClient.py Thu Oct 05 19:24:14 2017 +0200 +++ b/RefactoringRope/JsonClient.py Fri Oct 06 18:39:09 2017 +0200 @@ -69,33 +69,34 @@ containing the associated data @rtype tuple of (str, dict) """ - line = self.__connection.recv(1024 * 1024, socket.MSG_PEEK) - # 1MB buffer - - eol = line.find(b'\n') - - if eol >= 0: - size = eol + 1 - - # Now we know how big the line is, read it for real. - line = self.__connection.recv(size).decode( - 'utf8', 'backslashreplace') - try: - commandDict = json.loads(line.strip()) - except (TypeError, ValueError) as err: - self.sendJson("ClientException", { - "ExceptionType": "ProtocolError", - "ExceptionValue": str(err), - "ProtocolData": line.strip(), - }) + # step 1: receive the data + # The JSON RPC string is prefixed by a 9 character long length field. + length = self.__connection.recv(9) + length = int(length) + data = b'' + while len(data) < length: + newData = self.__connection.recv(length - len(data)) + if not newData: return None, None - - method = commandDict["method"] - params = commandDict["params"] - - return method, params + data += newData - return None, None + # step 2: decode and convert the data + line = data.decode( + 'utf8', 'backslashreplace') + try: + commandDict = json.loads(line.strip()) + except (TypeError, ValueError) as err: + self.sendJson("ClientException", { + "ExceptionType": "ProtocolError", + "ExceptionValue": str(err), + "ProtocolData": line.strip(), + }) + return None, None + + method = commandDict["method"] + params = commandDict["params"] + + return method, params def handleCall(self, method, params): """