Beispiel #1
0
 def test_deserialize_error_response_field_not_found(self):
     with self.assertRaises(UPnPError) as e:
         deserialize_soap_post_response(self.post_response,
                                        self.method + 'derp',
                                        service_id=self.st.decode())
     self.assertTrue(
         str(e.exception).startswith(
             'unknown response fields for GetExternalIPAddressderp'))
Beispiel #2
0
 def test_raise_from_error_response(self):
     raised = False
     try:
         deserialize_soap_post_response(self.error_response,
                                        self.method,
                                        service_id=self.st.decode())
     except UPnPError as err:
         raised = True
         self.assertTrue(str(err) == 'SpecifiedArrayIndexInvalid')
     self.assertTrue(raised)
Beispiel #3
0
 def test_raise_from_error_response_without_error_description(self):
     raised = False
     expected = 'Failed to decode error response: {"faultcode": "s:Client", "faultstring": "UPnPError", "detail": {"UPnPError": {"errorCode": "713"}}}'
     try:
         deserialize_soap_post_response(self.error_response_no_description,
                                        self.method,
                                        service_id=self.st.decode())
     except UPnPError as err:
         raised = True
         self.assertTrue(str(err) == expected)
     self.assertTrue(raised)
Beispiel #4
0
 def test_deserialize_blank_response(self):
     # TODO: these seem like they should error... this test will break and have to be updated
     self.assertDictEqual({},
                          deserialize_soap_post_response(
                              self.blank_response,
                              self.method,
                              service_id=self.st.decode()))
     self.assertDictEqual({},
                          deserialize_soap_post_response(
                              self.blank_response_body,
                              self.method,
                              service_id=self.st.decode()))
Beispiel #5
0
 def test_soap_env_namespace_response(self):
     # tp link devices use `SOAP-ENV` namespace rather than the normal `s`
     response = b'HTTP/1.1 200 OK\r\nCONNECTION: close\r\nSERVER: ipos/7.0 UPnP/1.0 TL-WR940N/TL-WR941ND/3.0\r\nCONTENT-LENGTH: 404\r\nCONTENT-TYPE: text/xml; charset="utf-8"\r\n\r\n<?xml version="1.0"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">\n<SOAP-ENV:Body>\n<u:GetExternalIPAddressResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewExternalIPAddress>100.100.100.100</NewExternalIPAddress></u:GetExternalIPAddressResponse></SOAP-ENV:Body>\n</SOAP-ENV:Envelope>\n'
     self.assertDictEqual(
         deserialize_soap_post_response(response, 'GetExternalIPAddress',
                                        self.st.decode()),
         {'NewExternalIPAddress': '100.100.100.100'})
Beispiel #6
0
async def scpd_post(
    control_url: str,
    address: str,
    port: int,
    method: str,
    param_names: list,
    service_id: bytes,
    loop: typing.Optional[asyncio.AbstractEventLoop] = None,
    **kwargs: typing.Dict[str, typing.Any]
) -> typing.Tuple[typing.Dict, bytes, typing.Optional[Exception]]:
    loop = loop or asyncio.get_event_loop()
    finished: 'asyncio.Future[typing.Tuple[bytes, bytes, int, bytes]]' = loop.create_future(
    )
    packet = serialize_soap_post(method, param_names, service_id,
                                 address.encode(), control_url.encode(),
                                 **kwargs)
    proto_factory: typing.Callable[[], SCPDHTTPClientProtocol] = lambda:\
        SCPDHTTPClientProtocol(packet, finished, soap_method=method, soap_service_id=service_id.decode())
    try:
        connect_tup: typing.Tuple[
            asyncio.BaseTransport,
            asyncio.BaseProtocol] = await loop.create_connection(
                proto_factory, address, port)
    except ConnectionError as err:
        return {}, b'', UPnPError(f"{err.__class__.__name__}({str(err)})")
    protocol = connect_tup[1]
    transport = connect_tup[0]
    assert isinstance(protocol, SCPDHTTPClientProtocol)

    try:
        wait_task: typing.Awaitable[typing.Tuple[bytes, bytes, int,
                                                 bytes]] = asyncio.wait_for(
                                                     finished, 1.0, loop=loop)
        raw_response, body, response_code, response_msg = await wait_task
    except asyncio.TimeoutError:
        return {}, b'', UPnPError("Timeout")
    except UPnPError as err:
        return {}, protocol.response_buff, err
    finally:
        transport.close()
    try:
        return (deserialize_soap_post_response(body, method,
                                               service_id.decode()),
                raw_response, None)
    except Exception as err:
        return {}, raw_response, UPnPError(err)
Beispiel #7
0
async def scpd_post(
        control_url: str,
        address: str,
        port: int,
        method: str,
        param_names: list,
        service_id: bytes,
        loop=None,
        **kwargs
) -> typing.Tuple[typing.Dict, bytes, typing.Optional[Exception]]:
    loop = loop or asyncio.get_event_loop_policy().get_event_loop()
    finished: asyncio.Future = asyncio.Future()
    packet = serialize_soap_post(method, param_names, service_id,
                                 address.encode(), control_url.encode(),
                                 **kwargs)
    transport, protocol = await loop.create_connection(
        lambda: SCPDHTTPClientProtocol(
            packet,
            finished,
            soap_method=method,
            soap_service_id=service_id.decode(),
        ), address, port)
    assert isinstance(protocol, SCPDHTTPClientProtocol)
    try:
        body, response_code, response_msg = await asyncio.wait_for(
            finished, 1.0)
    except asyncio.TimeoutError:
        return {}, b'', UPnPError("Timeout")
    except UPnPError as err:
        return {}, protocol.response_buff, err
    finally:
        transport.close()
    try:
        return (deserialize_soap_post_response(body, method,
                                               service_id.decode()), body,
                None)
    except (ElementTree.ParseError, UPnPError) as err:
        return {}, body, UPnPError(err)
Beispiel #8
0
 def test_deserialize_post_response(self):
     self.assertDictEqual(
         deserialize_soap_post_response(self.post_response,
                                        self.method,
                                        service_id=self.st.decode()),
         {'NewExternalIPAddress': '11.22.33.44'})