コード例 #1
0
    def __call__(self, method, args):
        try:
            self._client.putrequest('POST', self._uri.path)
            for header in self._headers:
                self._client.putheader(*header)

            request = encode_object(
                Call(method,
                     args,
                     overload=self._overload,
                     version=self.version))
            self._client.putheader("Content-Length", str(len(request)))
            self._client.endheaders()
            self._client.send(six.binary_type(request))

            response = self._client.getresponse()
            if response.status != 200:
                raise ProtocolError(self._uri.geturl(), response.status,
                                    response.reason)

            length = response.getheader('Content-Length', -1)
            if length == '0':
                raise ProtocolError(self._uri.geturl(), 'FATAL:',
                                    'Server sent zero-length response')

            reply = self._parser.parse_stream(
                BufferedReader(response, buffer_size=self._buffer_size))
            self._client.close()

            if isinstance(reply.value, Fault):
                raise self._error_factory(reply.value)
            else:
                return reply.value
        except:
            self._client.close()
            raise
コード例 #2
0
ファイル: parser.py プロジェクト: foreflight/python-hessian
    def parse_stream(self, stream):
        self._result = None

        if hasattr(stream, 'read') and hasattr(stream.read, '__call__'):
            self._stream = stream
        else:
            raise TypeError(
                'Stream parser can only handle objects supporting read()')

        while True:
            code = self._read(1)

            if not self._result:
                if code == b'H' and not self.version:
                    if self._result:
                        raise ParseError('Encountered duplicate type header')
                    self.read_version()

                elif not self.version and code == b'c':
                    self.read_version()
                    self._result = Call(version=self.version)

                elif self.version == 2 and code == b'R':
                    self._result = Reply(version=self.version)

                elif self.version == 2 and code == b'C':
                    method_name = self.read_object()
                    self._result = Call(method=method_name,
                                        version=self.version)

                elif not self._result and code == b'r':
                    self.read_version()
                    self._result = Reply(version=self.version)

                elif self.version == 2 and not self._result and code == b'F':
                    self._result = Reply(value=self._adapter._read_fault(),
                                         version=self.version)
                    break
                else:
                    raise ParseError("Invalid Hessian message marker: %r" %
                                     (code, ))
            else:
                if self.version == 1 and code == b'H':
                    key, value = self._read_keyval()
                    self._result.headers[key] = value

                elif self.version == 1 and code == b'm':
                    if not isinstance(self._result, Call):
                        raise ParseError(
                            'Encountered illegal method name within reply')

                    if self._result.method:
                        raise ParseError(
                            'Encountered duplicate method name definition')

                    self._result.method = self._read(
                        unpack('>H', self._read(2))[0])
                    continue

                elif self.version == 1 and code == b'f':
                    if not isinstance(self._result, Reply):
                        raise ParseError(
                            'Encountered illegal fault within call')

                    if self._result.value:
                        raise ParseError(
                            'Encountered illegal extra object within reply')

                    self._result.value = self._adapter._read_fault()
                    break

                elif self.version == 1 and code == b'z':
                    break

                else:
                    if isinstance(self._result, Call):
                        if self.version == 2:
                            num_args = self.read_object(code)
                            for i in range(0, num_args):
                                self._result.args.append(self.read_object())
                            break
                        else:
                            self._result.args.append(self.read_object(code))
                    else:
                        if self._result.value:
                            raise ParseError(
                                'Encountered illegal extra object within reply'
                            )

                        self._result.value = self.read_object(code)
                        if self.version == 2:
                            break

        # have to hit a 'z' to land here, TODO derefs?
        return self._result