Esempio n. 1
0
def test_response_serialization():
    """Test the serialization for 'response' speech-act works."""
    msg = HttpMessage(
        message_id=2,
        target=1,
        performative=HttpMessage.Performative.RESPONSE,
        version="some_version",
        status_code=1,
        status_text="some_status_text",
        headers="some_headers",
        body=b"some_body",
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert (expected_envelope.protocol_specification_id ==
            actual_envelope.protocol_specification_id)
    assert expected_envelope.message != actual_envelope.message

    actual_msg = HttpMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
Esempio n. 2
0
    async def to_envelope(self, request: web.Request) -> Envelope:
        """
        Convert a webhook request object into an Envelope containing an HttpMessage `from the 'http' Protocol`.

        :param request: the webhook request
        :return: The envelop representing the webhook request
        """
        payload_bytes = await request.read()
        version = str(request.version[0]) + "." + str(request.version[1])

        context = EnvelopeContext(uri=URI("aea/mail/base.py"))
        http_message = HttpMessage(
            performative=HttpMessage.Performative.REQUEST,
            method=request.method,
            url=str(request.url),
            version=version,
            headers=json.dumps(dict(request.headers)),
            bodyy=payload_bytes if payload_bytes is not None else b"",
            dialogue_reference=self._dialogues.
            new_self_initiated_dialogue_reference(),
        )
        http_message.counterparty = self.agent_address
        http_dialogue = self._dialogues.update(http_message)
        assert http_dialogue is not None, "Could not create dialogue."
        envelope = Envelope(
            to=http_message.counterparty,
            sender=http_message.sender,
            protocol_id=http_message.protocol_id,
            context=context,
            message=http_message,
        )
        return envelope
 def _make_response(
     self, request_envelope: Envelope, status_code: int = 200, status_text: str = ""
 ) -> Envelope:
     """Make response envelope."""
     incoming_message = cast(HttpMessage, request_envelope.message)
     incoming_message.is_incoming = True
     incoming_message.counterparty = str(HTTPServerConnection.connection_id)
     dialogue = self._server_dialogues.update(incoming_message)
     assert dialogue is not None
     message = HttpMessage(
         performative=HttpMessage.Performative.RESPONSE,
         dialogue_reference=dialogue.dialogue_label.dialogue_reference,
         target=incoming_message.message_id,
         message_id=incoming_message.message_id + 1,
         version=incoming_message.version,
         headers=incoming_message.headers,
         status_code=status_code,
         status_text=status_text,
         bodyy=incoming_message.bodyy,
     )
     message.counterparty = incoming_message.counterparty
     assert dialogue.update(message) is not None
     response_envelope = Envelope(
         to=message.counterparty,
         sender=message.sender,
         protocol_id=message.protocol_id,
         context=request_envelope.context,
         message=message,
     )
     return response_envelope
Esempio n. 4
0
    async def test_http_dialogue_construct_fail(self):
        """Test dialogue not properly constructed."""
        await self.http_client_connection.connect()

        http_message = HttpMessage(
            dialogue_reference=self.http_dialogs.
            new_self_initiated_dialogue_reference(),
            performative=HttpMessage.Performative.RESPONSE,
            status_code=500,
            headers="",
            status_text="",
            bodyy=b"",
            version="",
        )
        http_message.counterparty = self.connection_address
        http_dialogue = self.http_dialogs.update(http_message)
        http_message.sender = self.agent_address
        assert http_dialogue is None
        envelope = Envelope(
            to=http_message.counterparty,
            sender=http_message.sender,
            protocol_id=http_message.protocol_id,
            message=http_message,
        )
        with patch.object(self.http_client_connection.channel.logger,
                          "warning") as mock_logger:
            await self.http_client_connection.channel._http_request_task(
                envelope)
            mock_logger.assert_any_call(
                AnyStringWith("Could not create dialogue for message="))
Esempio n. 5
0
    async def test_send_envelope_excluded_protocol_fail(self):
        """Test send error if protocol not supported."""
        request_http_message = HttpMessage(
            dialogue_reference=self.http_dialogs.
            new_self_initiated_dialogue_reference(),
            performative=HttpMessage.Performative.REQUEST,
            method="get",
            url="bad url",
            headers="",
            version="",
            bodyy=b"",
        )
        request_http_message.counterparty = self.connection_address
        sending_dialogue = self.http_dialogs.update(request_http_message)
        assert sending_dialogue is not None
        request_envelope = Envelope(
            to=self.connection_address,
            sender=self.agent_address,
            protocol_id=UNKNOWN_PROTOCOL_PUBLIC_ID,
            message=request_http_message,
        )
        await self.http_client_connection.connect()

        with patch.object(
                self.http_client_connection.channel,
                "excluded_protocols",
                new=[UNKNOWN_PROTOCOL_PUBLIC_ID],
        ):
            with pytest.raises(ValueError):
                await self.http_client_connection.send(request_envelope)
Esempio n. 6
0
    async def test_http_send_error(self):
        """Test request fails and send back result with code 600."""
        await self.http_client_connection.connect()

        request_http_message = HttpMessage(
            dialogue_reference=self.http_dialogs.
            new_self_initiated_dialogue_reference(),
            performative=HttpMessage.Performative.REQUEST,
            method="get",
            url="bad url",
            headers="",
            version="",
            bodyy=b"",
        )
        request_http_message.counterparty = self.connection_address
        sending_dialogue = self.http_dialogs.update(request_http_message)
        assert sending_dialogue is not None
        request_envelope = Envelope(
            to=self.connection_address,
            sender=self.agent_address,
            protocol_id=UNKNOWN_PROTOCOL_PUBLIC_ID,
            message=request_http_message,
        )

        connection_response_mock = Mock()
        connection_response_mock.status_code = 200

        await self.http_client_connection.send(envelope=request_envelope)
        # TODO: Consider returning the response from the server in order to be able to assert that the message send!
        envelope = await asyncio.wait_for(
            self.http_client_connection.receive(), timeout=10)
        assert envelope
        assert envelope.message.status_code == 600

        await self.http_client_connection.disconnect()
Esempio n. 7
0
def test_request_serialization():
    """Test the serialization for 'request' speech-act works."""
    msg = HttpMessage(
        performative=HttpMessage.Performative.REQUEST,
        method="some_method",
        url="url",
        version="some_version",
        headers="some_headers",
        body=b"some_body",
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert (expected_envelope.protocol_specification_id ==
            actual_envelope.protocol_specification_id)
    assert expected_envelope.message != actual_envelope.message

    actual_msg = HttpMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
Esempio n. 8
0
    def _handle_get(self, http_msg: HttpMessage,
                    http_dialogue: HttpDialogue) -> None:
        """
        Handle a Http request of verb GET.

        :param http_msg: the http message
        :param http_dialogue: the http dialogue
        :return: None
        """
        http_response = HttpMessage(
            dialogue_reference=http_dialogue.dialogue_label.dialogue_reference,
            target=http_msg.message_id,
            message_id=http_msg.message_id + 1,
            performative=HttpMessage.Performative.RESPONSE,
            version=http_msg.version,
            status_code=200,
            status_text="Success",
            headers=http_msg.headers,
            bodyy=json.dumps({
                "tom": {
                    "type": "cat",
                    "age": 10
                }
            }).encode("utf-8"),
        )
        self.context.logger.info("responding with: {}".format(http_response))
        http_response.counterparty = http_msg.counterparty
        assert http_dialogue.update(http_response)
        self.context.outbox.put_message(message=http_response)
    async def test_connecting_to_aca(self):
        """Test connecting to aca."""
        configuration = ConnectionConfig(
            host=self.aca_admin_address,
            port=self.aca_admin_port,
            connection_id=HTTPClientConnection.connection_id,
        )
        http_client_connection = HTTPClientConnection(
            configuration=configuration, identity=self.aea_identity)
        http_client_connection.loop = asyncio.get_event_loop()

        # Request messages
        request_http_message = HttpMessage(
            dialogue_reference=("1", ""),
            target=0,
            message_id=1,
            performative=HttpMessage.Performative.REQUEST,
            method="GET",
            url="http://{}:{}/status".format(self.aca_admin_address,
                                             self.aca_admin_port),
            headers="",
            version="",
            body=b"",
        )
        request_http_message.to = "ACA"
        request_envelope = Envelope(
            to="ACA",
            sender="AEA",
            protocol_id=HttpMessage.protocol_id,
            message=request_http_message,
        )

        try:
            # connect to ACA
            await http_client_connection.connect()
            assert http_client_connection.is_connected is True

            # send request to ACA
            await http_client_connection.send(envelope=request_envelope)

            # receive response from ACA
            response_envelop = await http_client_connection.receive()

            # check the response
            assert response_envelop.to == self.aea_address
            assert response_envelop.sender == "HTTP Server"
            assert response_envelop.protocol_id == HttpMessage.protocol_id
            decoded_response_message = response_envelop.message
            assert (decoded_response_message.performative ==
                    HttpMessage.Performative.RESPONSE)
            assert decoded_response_message.version == ""
            assert decoded_response_message.status_code == 200
            assert decoded_response_message.status_text == "OK"
            assert decoded_response_message.headers is not None
            assert decoded_response_message.version is not None

        finally:
            # disconnect from ACA
            await http_client_connection.disconnect()
            assert http_client_connection.is_connected is False
Esempio n. 10
0
    async def test_http_dialogue_construct_fail(self):
        """Test dialogue not properly constructed."""
        await self.http_client_connection.connect()

        incorrect_http_message = HttpMessage(
            dialogue_reference=self.http_dialogs.
            new_self_initiated_dialogue_reference(),
            performative=HttpMessage.Performative.RESPONSE,
            status_code=500,
            headers="",
            status_text="",
            body=b"",
            version="",
        )
        incorrect_http_message.to = self.connection_address
        incorrect_http_message.sender = self.agent_address

        # the incorrect message cannot be sent into a dialogue, so this is omitted.

        envelope = Envelope(
            to=incorrect_http_message.to,
            sender=incorrect_http_message.sender,
            message=incorrect_http_message,
        )
        with patch.object(self.http_client_connection.channel.logger,
                          "warning") as mock_logger:
            await self.http_client_connection.channel._http_request_task(
                envelope)
            mock_logger.assert_any_call(
                AnyStringWith("Could not create dialogue for message="))
Esempio n. 11
0
    async def test_post_201(self):
        """Test send get request w/ 200 response."""
        request_task = self.loop.create_task(self.request("post", "/pets",))
        envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20)
        assert envelope
        incoming_message, dialogue = self._get_message_and_dialogue(envelope)
        message = HttpMessage(
            performative=HttpMessage.Performative.RESPONSE,
            dialogue_reference=dialogue.dialogue_label.dialogue_reference,
            target=incoming_message.message_id,
            message_id=incoming_message.message_id + 1,
            version=incoming_message.version,
            headers=incoming_message.headers,
            status_code=201,
            status_text="Created",
            bodyy=b"Response body",
        )
        message.counterparty = incoming_message.counterparty
        assert dialogue.update(message)
        response_envelope = Envelope(
            to=envelope.sender,
            sender=envelope.to,
            protocol_id=envelope.protocol_id,
            context=envelope.context,
            message=message,
        )

        await self.http_connection.send(response_envelope)

        response = await asyncio.wait_for(request_task, timeout=20,)
        assert (
            response.status == 201
            and response.reason == "Created"
            and await response.text() == "Response body"
        )
Esempio n. 12
0
    async def test_server_error_on_send_response(self):
        """Test exception raised on response sending to the client."""
        request_task = self.loop.create_task(self.request("post", "/pets",))
        envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20)
        assert envelope
        incoming_message, dialogue = self._get_message_and_dialogue(envelope)
        message = HttpMessage(
            performative=HttpMessage.Performative.RESPONSE,
            dialogue_reference=dialogue.dialogue_label.dialogue_reference,
            target=incoming_message.message_id,
            message_id=incoming_message.message_id + 1,
            version=incoming_message.version,
            headers=incoming_message.headers,
            status_code=201,
            status_text="Created",
            bodyy=b"Response body",
        )
        message.counterparty = incoming_message.counterparty
        assert dialogue.update(message)
        response_envelope = Envelope(
            to=envelope.sender,
            sender=envelope.to,
            protocol_id=envelope.protocol_id,
            context=envelope.context,
            message=message,
        )

        with patch.object(Response, "from_message", side_effect=Exception("expected")):
            await self.http_connection.send(response_envelope)
            response = await asyncio.wait_for(request_task, timeout=20,)

        assert response and response.status == 500 and response.reason == "Server Error"
Esempio n. 13
0
    async def test_http_send_ok(self):
        """Test request is ok cause mocked."""
        await self.http_client_connection.connect()

        request_http_message = HttpMessage(
            dialogue_reference=self.http_dialogs.
            new_self_initiated_dialogue_reference(),
            performative=HttpMessage.Performative.REQUEST,
            method="get",
            url="https://not-a-google.com",
            headers="",
            version="",
            bodyy=b"",
        )
        request_http_message.counterparty = self.connection_address
        sending_dialogue = self.http_dialogs.update(request_http_message)
        assert sending_dialogue is not None
        request_envelope = Envelope(
            to=self.connection_address,
            sender=self.agent_address,
            protocol_id=request_http_message.protocol_id,
            message=request_http_message,
        )

        connection_response_mock = Mock()
        connection_response_mock.status_code = 200

        response_mock = Mock()
        response_mock.status = 200
        response_mock.headers = {"headers": "some header"}
        response_mock.reason = "OK"
        response_mock._body = b"Some content"
        response_mock.read.return_value = asyncio.Future()
        response_mock.read.return_value.set_result("")

        with patch.object(
                aiohttp.ClientSession,
                "request",
                return_value=_MockRequest(response_mock),
        ):
            await self.http_client_connection.send(envelope=request_envelope)
            # TODO: Consider returning the response from the server in order to be able to assert that the message send!
            envelope = await asyncio.wait_for(
                self.http_client_connection.receive(), timeout=10)

        assert envelope is not None and envelope.message is not None
        response = copy.copy(envelope.message)
        response.is_incoming = True
        response.counterparty = envelope.message.sender
        response_dialogue = self.http_dialogs.update(response)
        assert response.status_code == response_mock.status, response.bodyy.decode(
            "utf-8")
        assert sending_dialogue == response_dialogue
        await self.http_client_connection.disconnect()
Esempio n. 14
0
    def decode(obj: bytes) -> Message:
        """
        Decode bytes into a 'Http' message.

        :param obj: the bytes object.
        :return: the 'Http' message.
        """
        message_pb = ProtobufMessage()
        http_pb = http_pb2.HttpMessage()
        message_pb.ParseFromString(obj)
        message_id = message_pb.dialogue_message.message_id
        dialogue_reference = (
            message_pb.dialogue_message.dialogue_starter_reference,
            message_pb.dialogue_message.dialogue_responder_reference,
        )
        target = message_pb.dialogue_message.target

        http_pb.ParseFromString(message_pb.dialogue_message.content)
        performative = http_pb.WhichOneof("performative")
        performative_id = HttpMessage.Performative(str(performative))
        performative_content = dict()  # type: Dict[str, Any]
        if performative_id == HttpMessage.Performative.REQUEST:
            method = http_pb.request.method
            performative_content["method"] = method
            url = http_pb.request.url
            performative_content["url"] = url
            version = http_pb.request.version
            performative_content["version"] = version
            headers = http_pb.request.headers
            performative_content["headers"] = headers
            body = http_pb.request.body
            performative_content["body"] = body
        elif performative_id == HttpMessage.Performative.RESPONSE:
            version = http_pb.response.version
            performative_content["version"] = version
            status_code = http_pb.response.status_code
            performative_content["status_code"] = status_code
            status_text = http_pb.response.status_text
            performative_content["status_text"] = status_text
            headers = http_pb.response.headers
            performative_content["headers"] = headers
            body = http_pb.response.body
            performative_content["body"] = body
        else:
            raise ValueError("Performative not valid: {}.".format(performative_id))

        return HttpMessage(
            message_id=message_id,
            dialogue_reference=dialogue_reference,
            target=target,
            performative=performative,
            **performative_content
        )
Esempio n. 15
0
 def _admin_post(self, path: str, content: Dict = None) -> None:
     # Request message & envelope
     request_http_message = HttpMessage(
         performative=HttpMessage.Performative.REQUEST,
         method="POST",
         url=self.admin_url + path,
         headers="",
         version="",
         bodyy=b""
         if content is None else json.dumps(content).encode("utf-8"),
     )
     request_http_message.counterparty = self.admin_url
     self.context.outbox.put_message(message=request_http_message)
Esempio n. 16
0
    async def test_channel_cancel_tasks_on_disconnect(self):
        """Test requests tasks cancelled on disconnect."""
        await self.http_client_connection.connect()

        request_http_message = HttpMessage(
            dialogue_reference=self.http_dialogs.
            new_self_initiated_dialogue_reference(),
            performative=HttpMessage.Performative.REQUEST,
            method="get",
            url="https://not-a-google.com",
            headers="",
            version="",
            bodyy=b"",
        )
        request_http_message.counterparty = self.connection_address
        sending_dialogue = self.http_dialogs.update(request_http_message)
        assert sending_dialogue is not None
        request_envelope = Envelope(
            to=self.connection_address,
            sender=self.agent_address,
            protocol_id=UNKNOWN_PROTOCOL_PUBLIC_ID,
            message=request_http_message,
        )

        connection_response_mock = Mock()
        connection_response_mock.status_code = 200

        response_mock = Mock()
        response_mock.status = 200
        response_mock.headers = {"headers": "some header"}
        response_mock.reason = "OK"
        response_mock._body = b"Some content"
        response_mock.read.return_value = asyncio.Future()

        with patch.object(
                aiohttp.ClientSession,
                "request",
                return_value=_MockRequest(response_mock),
        ):
            await self.http_client_connection.send(envelope=request_envelope)

            assert self.http_client_connection.channel._tasks
            task = list(self.http_client_connection.channel._tasks)[0]
            assert not task.done()
        await self.http_client_connection.disconnect()

        assert not self.http_client_connection.channel._tasks
        assert task.done()
        with pytest.raises(CancelledError):
            await task
 def create(self) -> HttpMessage:
     """Make initial http request."""
     message = HttpMessage(
         dialogue_reference=HttpDialogues.
         new_self_initiated_dialogue_reference(),
         performative=HttpMessage.Performative.REQUEST,
         method="get",
         url="some url",
         headers="",
         version="",
         body=b"",
     )
     message.sender = self.random_string
     message.to = self.addr
     return message
Esempio n. 18
0
    def to_envelope(
        self,
        connection_id: PublicId,
        http_request_message: HttpMessage,
        http_response: requests.models.Response,
    ) -> Envelope:
        """
        Convert an HTTP response object (from the 'requests' library) into an Envelope containing an HttpMessage (from the 'http' Protocol).

        :param connection_id: the connection id
        :param http_request_message: the message of the http request envelop
        :param http_response: the http response object
        """

        context = EnvelopeContext(connection_id=connection_id)
        http_message = HttpMessage(
            dialogue_reference=http_request_message.dialogue_reference,
            target=http_request_message.target,
            message_id=http_request_message.message_id,
            performative=HttpMessage.Performative.RESPONSE,
            status_code=http_response.status_code,
            headers=json.dumps(dict(http_response.headers)),
            status_text=http_response.reason,
            bodyy=http_response.content
            if http_response.content is not None else b"",
            version="",
        )
        envelope = Envelope(
            to=self.agent_address,
            sender="HTTP Server",
            protocol_id=PublicId.from_str("fetchai/http:0.1.0"),
            context=context,
            message=HttpSerializer().encode(http_message),
        )
        return envelope
Esempio n. 19
0
 async def agent_processing(http_connection) -> bool:
     # we block here to give it some time for the envelope to make it to the queue
     await asyncio.sleep(1)
     envelope = await http_connection.receive()
     if envelope is not None:
         incoming_message = cast(
             HttpMessage,
             HttpSerializer().decode(envelope.message))
         message = HttpMessage(
             performative=HttpMessage.Performative.RESPONSE,
             dialogue_reference=("", ""),
             target=incoming_message.message_id,
             message_id=incoming_message.message_id + 1,
             version=incoming_message.version,
             headers=incoming_message.headers,
             status_code=201,
             status_text="Created",
             bodyy=b"Response body",
         )
         response_envelope = Envelope(
             to=envelope.sender,
             sender=envelope.to,
             protocol_id=envelope.protocol_id,
             context=envelope.context,
             message=HttpSerializer().encode(message),
         )
         await http_connection.send(response_envelope)
         is_exiting_correctly = True
     else:
         is_exiting_correctly = False
     return is_exiting_correctly
Esempio n. 20
0
 async def test_send_connection_send(self):
     """Test send connection error."""
     client_id = "to_key"
     message = HttpMessage(
         performative=HttpMessage.Performative.RESPONSE,
         dialogue_reference=("", ""),
         target=1,
         message_id=2,
         headers="",
         version="",
         status_code=200,
         status_text="Success",
         bodyy=b"",
     )
     envelope = Envelope(
         to=client_id,
         sender="from_key",
         protocol_id=self.protocol_id,
         message=HttpSerializer().encode(message),
     )
     self.http_connection.channel.pending_request_ids.add("to_key")
     await self.http_connection.send(envelope)
     assert (self.http_connection.channel.dispatch_ready_envelopes.get(
         client_id) == envelope)
     assert self.http_connection.channel.pending_request_ids == set()
     # clean up:
     self.http_connection.channel.dispatch_ready_envelopes = (
         {})  # type: Dict[str, Envelope]
Esempio n. 21
0
    async def test_send_envelope_restricted_to_protocols_fail(self):
        """Test fail on send if envelope protocol not supported."""
        message = HttpMessage(
            performative=HttpMessage.Performative.RESPONSE,
            dialogue_reference=("", ""),
            target=1,
            message_id=2,
            version="1.0",
            headers="",
            status_code=200,
            status_text="Success",
            bodyy=b"Response body",
        )
        envelope = Envelope(
            to="receiver",
            sender="sender",
            protocol_id=UNKNOWN_PROTOCOL_PUBLIC_ID,
            message=message,
        )

        with patch.object(
            self.http_connection.channel,
            "restricted_to_protocols",
            new=[HTTP_PROTOCOL_PUBLIC_ID],
        ):
            with pytest.raises(ValueError):
                await self.http_connection.send(envelope)
Esempio n. 22
0
    def _handle_get(self, http_msg: HttpMessage) -> None:
        """
        Handle a Http request of verb GET.

        :param http_msg: the http message
        :return: None
        """
        http_response = HttpMessage(
            dialogue_reference=http_msg.dialogue_reference,
            target=http_msg.message_id,
            message_id=http_msg.message_id + 1,
            performative=HttpMessage.Performative.RESPONSE,
            version=http_msg.version,
            status_code=200,
            status_text="Success",
            headers=http_msg.headers,
            bodyy=json.dumps({
                "tom": {
                    "type": "cat",
                    "age": 10
                }
            }).encode("utf-8"),
        )
        self.context.logger.info("[{}] responding with: {}".format(
            self.context.agent_name, http_response))
        self.context.outbox.put_message(
            sender=self.context.agent_address,
            to=http_msg.counterparty,
            protocol_id=http_response.protocol_id,
            message=HttpSerializer().encode(http_response),
        )
Esempio n. 23
0
    def from_message(cls, http_message: HttpMessage) -> "Response":
        """
        Turn an envelope into a response.

        :param http_message: the http_message
        :return: the response
        """
        if http_message.performative == HttpMessage.Performative.RESPONSE:

            if http_message.is_set("headers") and http_message.headers:
                headers: Optional[dict] = dict(
                    email.message_from_string(http_message.headers).items()
                )
            else:
                headers = None

            response = cls(
                status=http_message.status_code,
                reason=http_message.status_text,
                body=http_message.body,
                headers=headers,
            )
        else:  # pragma: nocover
            response = cls(status=SERVER_ERROR, text="Server error")
        return response
Esempio n. 24
0
    async def test_send(self):
        """Test the connect functionality of the webhook connection."""
        await self.webhook_connection.connect()
        assert self.webhook_connection.is_connected is True

        http_message = HttpMessage(
            dialogue_reference=("", ""),
            target=0,
            message_id=1,
            performative=HttpMessage.Performative.REQUEST,
            method="get",
            url="/",
            headers="",
            bodyy="",
            version="",
        )
        envelope = Envelope(
            to="addr",
            sender="my_id",
            protocol_id=PublicId.from_str("fetchai/http:0.4.0"),
            message=http_message,
        )
        with patch.object(self.webhook_connection.logger, "warning") as mock_logger:
            await self.webhook_connection.send(envelope)
            await asyncio.sleep(0.01)
            mock_logger.assert_any_call(
                RegexComparator(
                    "Dropping envelope=.* as sending via the webhook is not possible!"
                )
            )
Esempio n. 25
0
    def to_envelope(self, connection_id: PublicId, agent_address: str) -> Envelope:
        """
        Process incoming API request by packaging into Envelope and sending it in-queue.

        The Envelope's message body contains the "performative", "path", "params", and "payload".

        :param http_method: the http method
        :param url: the url
        :param param: the parameter
        :param body: the body
        """
        uri = URI(self.full_url_pattern)
        context = EnvelopeContext(connection_id=connection_id, uri=uri)
        http_message = HttpMessage(
            dialogue_reference=("", ""),
            target=0,
            message_id=1,
            performative=HttpMessage.Performative.REQUEST,
            method=self.method,
            url=self.full_url_pattern,
            headers=self.parameters.header.as_string(),
            bodyy=self.body.encode() if self.body is not None else b"",
            version="",
        )
        envelope = Envelope(
            to=agent_address,
            sender=self.id,
            protocol_id=PublicId.from_str("fetchai/http:0.1.0"),
            context=context,
            message=HttpSerializer().encode(http_message),
        )
        return envelope
Esempio n. 26
0
    async def to_envelope(self, request: web.Request) -> Envelope:
        """
        Convert a webhook request object into an Envelope containing an HttpMessage `from the 'http' Protocol`.

        :param request: the webhook request
        :return: The envelop representing the webhook request
        """
        payload_bytes = await request.read()
        version = str(request.version[0]) + "." + str(request.version[1])

        context = EnvelopeContext(uri=URI("aea/mail/base.py"))
        http_message = HttpMessage(
            performative=HttpMessage.Performative.REQUEST,
            method=request.method,
            url=str(request.url),
            version=version,
            headers=json.dumps(dict(request.headers)),
            bodyy=payload_bytes if payload_bytes is not None else b"",
        )
        envelope = Envelope(
            to=self.agent_address,
            sender=request.remote,
            protocol_id=PublicId.from_str("fetchai/http:0.3.0"),
            context=context,
            message=http_message,
        )
        return envelope
Esempio n. 27
0
    async def test_bad_performative_get_server_error(self):
        """Test send get request w/ 200 response."""
        request_task = self.loop.create_task(self.request("get", "/pets"))
        envelope = await asyncio.wait_for(self.http_connection.receive(),
                                          timeout=20)
        assert envelope
        incoming_message = cast(HttpMessage, envelope.message)
        message = HttpMessage(
            performative=HttpMessage.Performative.REQUEST,
            dialogue_reference=("", ""),
            target=incoming_message.message_id,
            message_id=incoming_message.message_id + 1,
            version=incoming_message.version,
            headers=incoming_message.headers,
            status_code=200,
            status_text="Success",
            bodyy=b"Response body",
        )
        response_envelope = Envelope(
            to=envelope.sender,
            sender=envelope.to,
            protocol_id=envelope.protocol_id,
            context=envelope.context,
            message=message,
        )
        await self.http_connection.send(response_envelope)

        response = await asyncio.wait_for(
            request_task,
            timeout=20,
        )

        assert response.status == 500 and await response.text(
        ) == "Server error"
Esempio n. 28
0
    async def _perform_http_request(
            self, request_http_message: HttpMessage) -> ClientResponse:
        """
        Perform http request and return response.

        :param request_http_message: HttpMessage with http request constructed.

        :return: aiohttp.ClientResponse
        """
        try:
            if request_http_message.is_set(
                    "headers") and request_http_message.headers:
                headers: Optional[dict] = dict(
                    email.message_from_string(
                        request_http_message.headers).items())
            else:
                headers = None
            async with aiohttp.ClientSession() as session:
                async with session.request(
                        method=request_http_message.method,
                        url=request_http_message.url,
                        headers=headers,
                        data=request_http_message.body,
                        ssl=ssl_context,
                ) as resp:
                    await resp.read()
                return resp
        except Exception:  # pragma: nocover # pylint: disable=broad-except
            self.logger.exception(
                f"Exception raised during http call: {request_http_message.method} {request_http_message.url}"
            )
            raise
Esempio n. 29
0
    async def test_send_envelope_excluded_protocol_fail(self):
        """Test send error if protocol not supported."""
        request_http_message = HttpMessage(
            dialogue_reference=("", ""),
            target=0,
            message_id=1,
            performative=HttpMessage.Performative.REQUEST,
            method="get",
            url="bad url",
            headers="",
            version="",
            bodyy=b"",
        )
        request_envelope = Envelope(
            to="receiver",
            sender="sender",
            protocol_id=UNKNOWN_PROTOCOL_PUBLIC_ID,
            message=request_http_message,
        )
        await self.http_client_connection.connect()

        with patch.object(
                self.http_client_connection.channel,
                "excluded_protocols",
                new=[UNKNOWN_PROTOCOL_PUBLIC_ID],
        ):
            with pytest.raises(ValueError):
                await self.http_client_connection.send(request_envelope)
Esempio n. 30
0
 def _make_response(self,
                    request_envelope: Envelope,
                    status_code: int = 200,
                    status_text: str = "") -> Envelope:
     """Make response envelope."""
     incoming_message = cast(HttpMessage, request_envelope.message)
     message = HttpMessage(
         performative=HttpMessage.Performative.RESPONSE,
         dialogue_reference=("", ""),
         target=incoming_message.message_id,
         message_id=incoming_message.message_id + 1,
         version=incoming_message.version,
         headers=incoming_message.headers,
         status_code=status_code,
         status_text=status_text,
         bodyy=incoming_message.bodyy,
     )
     response_envelope = Envelope(
         to=request_envelope.sender,
         sender=request_envelope.to,
         protocol_id=request_envelope.protocol_id,
         context=request_envelope.context,
         message=message,
     )
     return response_envelope