Example #1
0
    def decode_response(self, response, data):
        data_len = len(data)

        # decode the header length if we have enough
        if data_len < len_struct_size:
            return None, None
        header_len = unpack_length(data)[0]
        if data_len < header_len + len_struct_size:
            return None, None

        # decode the payload length and see if we have enough
        body_len = unpack_length(data, header_len)[0]
        if data_len < header_len + body_len:
            return None, header_len + body_len - data_len

        # we have enough data, decode it all
        try:
            offset, response.header = bson.codec.decode_document(data, 0)
            offset, response.reply = bson.codec.decode_document(data, offset)
            # unpack primitive values
            # FIXME(msolomon) remove this hack
            response.reply = response.reply.get(WRAPPED_FIELD, response.reply)

            # Return header_len + body_len instead of the offsets returned
            # by the library, should be the same.
            return header_len + body_len, None
        except Exception as e:
            raise gorpc.GoRpcError('decode error', e)
Example #2
0
    def decode_response(self, response, data):
        data_len = len(data)

        # decode the header length if we have enough
        if data_len < len_struct_size:
            return None, None
        header_len = unpack_length(data)[0]
        if data_len < header_len + len_struct_size:
            return None, None

        # decode the payload length and see if we have enough
        body_len = unpack_length(data, header_len)[0]
        if data_len < header_len + body_len:
            return None, header_len + body_len - data_len

        # we have enough data, decode it all
        try:
            offset, response.header = decode_document(data, 0)
            offset, response.reply = decode_document(data, offset)
            # unpack primitive values
            # FIXME(msolomon) remove this hack
            response.reply = response.reply.get(WRAPPED_FIELD, response.reply)

            # the pure-python bson library returns the offset in the buffer
            # the cbson library returns -1 if everything was read
            # so we cannot use the 'offset' variable. Instead use
            # header_len + body_len for the complete length read

            return header_len + body_len, None
        except Exception as e:
            raise gorpc.GoRpcError('decode error', e)
Example #3
0
 def encode_request(self, req):
     try:
         if not isinstance(req.body, dict):
             # hack to handle simple values
             body = {WRAPPED_FIELD: req.body}
         else:
             body = req.body
         return bson.dumps(req.header) + bson.dumps(body)
     except Exception as e:
         raise gorpc.GoRpcError('encode error', e)
Example #4
0
    def __drain_conn_after_streaming_app_error(self):
        """Drains the connection of all incoming streaming packets (ignoring them).

    This is necessary for streaming calls which return application errors inside
    the RPC response (instead of through the usual GoRPC error return).
    This is because GoRPC always expects the last packet to be an error; either
    the usual GoRPC application error return, or a special "end-of-stream" error.

    If an application error is returned with the RPC response, there will still be
    at least one more packet coming, as GoRPC has not seen anything that it
    considers to be an error. If the connection is not drained of this last
    packet, future reads from the wire will be off by one and will return errors.
    """
        next_result = self.client.stream_next()
        if next_result is not None:
            self.client.close()
            raise gorpc.GoRpcError(
                "Connection should only have one packet remaining"
                " after streaming app error in RPC response.")