示例#1
0
 def handle_info(self, request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming info request."""
     if not self.state.info_supported:
         return HttpResponse(
             "RTSP",
             "1.0",
             400,
             "Bad Request",
             {
                 "CSeq": request.headers["CSeq"],
             },
             b"",
         )
     info = {}
     if self.state.initial_audio_level_supported:
         info["initialVolume"] = self.state.volume
     return HttpResponse(
         "RTSP",
         "1.0",
         200,
         "OK",
         {
             "CSeq": request.headers["CSeq"],
             "content-type": "application/x-apple-binary-plist",
         },
         plistlib.dumps(info),
     )
示例#2
0
 def handle_auth_setup(self,
                       request: HttpRequest) -> Optional[HttpResponse]:
     _LOGGER.debug("Received auth-setup: %s", request)
     # Just check if decent sized payload is there
     if len(request.body) == 1 + 32:  # auth type + public key
         self.state.auth_setup_performed = True
         return HttpResponse("RTSP", "1.0", 200, "OK",
                             {"CSeq": request.headers["CSeq"]}, b"")
     return HttpResponse("RTSP", "1.0", 403, "Forbidden",
                         {"CSeq": request.headers["CSeq"]}, b"")
示例#3
0
 def handle_feedback(self, request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming feedback request."""
     _LOGGER.debug("Received feedback: %s", request)
     self.state.feedback_packets_received += 1
     if not self.state.supports_feedback:
         return HttpResponse(
             "RTSP",
             "1.0",
             501,
             "Not implemented",
             {"CSeq": request.headers["CSeq"]},
             b"",
         )
     return HttpResponse("RTSP", "1.0", 200, "OK",
                         {"CSeq": request.headers["CSeq"]}, b"")
示例#4
0
文件: test_http.py 项目: NebzHB/pyatv
    def _handle_page(request: HttpRequest):
        assert request.protocol == "HTTP"
        assert request.version == "1.1"
        assert request.path == "/resource"
        assert request.method == "GET"

        return HttpResponse("HTTP", "1.1", 200, "OK", {"DummyHeader": "value"}, b"body")
示例#5
0
    def handle_announce(self, request: HttpRequest) -> Optional[HttpResponse]:
        """Handle incoming ANNOUNCE request."""
        _LOGGER.debug("Received ANNOUNCE: %s", request)
        for line in request.body.decode("utf-8").split("\r\n"):
            if line.startswith("o="):
                self.state.remote_address = line.split()[-1]
                break

        return HttpResponse("RTSP", "1.0", 200, "OK",
                            {"CSeq": request.headers["CSeq"]}, b"")
示例#6
0
 def handle_set_parameter(self,
                          request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming SET_PARAMETER request."""
     _LOGGER.debug("Received SET_PARAMETER: %s", request)
     if request.headers["Content-Type"] == "application/x-dmap-tagged":
         tags = parser.parse(request.body, lookup_tag)
         self.state.metadata.title = parser.first(tags, "mlit", "minm")
         self.state.metadata.artist = parser.first(tags, "mlit", "asar")
         self.state.metadata.album = parser.first(tags, "mlit", "asal")
     return HttpResponse("RTSP", "1.0", 200, "OK",
                         {"CSeq": request.headers["CSeq"]}, b"")
示例#7
0
    def _impl(self, request: HttpRequest, *args, **kwargs):
        # No password required
        if not self.state.password:
            return method(self, request, *args, **kwargs)

        # Send a challenge
        if not self.state.nonce:
            nonce = self.state.nonce = "".join(
                random.choices(string.ascii_letters + string.digits, k=32))
            return HttpResponse(
                "RTSP",
                "1.0",
                401,
                "Unauthorized",
                {
                    "CSeq": request.headers["CSeq"],
                    "WWW-Authenticate":
                    f'Digest realm="{REALM}", nonce="{nonce}"',
                },
                b"",
            )

        # Verify the authentication payload send by the client
        payload_data = request.headers.get("Authorization", "").split('"')
        if len(payload_data) == 11:
            uri = request.path
            user = payload_data[1]
            actual_response = payload_data[9]
            nonce = self.state.nonce
            pwd = self.state.password
            ha1 = md5(f"{user}:{REALM}:{pwd}".encode("utf-8")).hexdigest()
            ha2 = md5(f"{request.method}:{uri}".encode("utf-8")).hexdigest()
            expected_response = md5(
                f"{ha1}:{nonce}:{ha2}".encode("utf-8")).hexdigest()

            if actual_response == expected_response:
                return method(self, request, *args, **kwargs)

        # Password verification failed
        return HttpResponse("RTSP", "1.0", 401, "Unauthorized",
                            {"CSeq": request.headers["CSeq"]}, b"")
示例#8
0
 def handle_set_parameter(self,
                          request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming SET_PARAMETER request."""
     _LOGGER.debug("Received SET_PARAMETER: %s", request)
     if request.headers["Content-Type"] == "application/x-dmap-tagged":
         tags = parser.parse(request.body, lookup_tag)
         self.state.metadata.title = parser.first(tags, "mlit", "minm")
         self.state.metadata.artist = parser.first(tags, "mlit", "asar")
         self.state.metadata.album = parser.first(tags, "mlit", "asal")
     elif request.body.startswith("volume:"):
         self.state.volume = float(request.body.split(" ", maxsplit=1)[1])
         _LOGGER.debug("Changing volume to %f", self.state.volume)
     else:
         return HttpResponse(
             "RTSP",
             "1.0",
             501,
             "Not implemented",
             {"CSeq": request.headers["CSeq"]},
             b"",
         )
     return HttpResponse("RTSP", "1.0", 200, "OK",
                         {"CSeq": request.headers["CSeq"]}, b"")
示例#9
0
 def handle_setup(self, request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming SETUP request."""
     _LOGGER.debug("Received SETUP: %s", request)
     _, options = parse_transport(request.headers["Transport"])
     self.state.control_port = int(options["control_port"])
     headers = {
         "Transport": ("RTP/AVP/UDP;unicast;mode=record;"
                       f"server_port={self._audio_receiver.port};"
                       f"control_port={self._control_server.port};"
                       f"timing_port={self._timing_server.port}"),
         "Session":
         "1",
         "CSeq":
         request.headers["CSeq"],
     }
     return HttpResponse("RTSP", "1.0", 200, "OK", headers, b"")
示例#10
0
 def handle_record(self, request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming RECORD request."""
     _LOGGER.debug("Received RECORD: %s", request)
     return HttpResponse("RTSP", "1.0", 200, "OK",
                         {"CSeq": request.headers["CSeq"]}, b"")
示例#11
0
 def handle_feedback(self, request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming feedback request."""
     _LOGGER.debug("Received feedback: %s", request)
     return HttpResponse("RTSP", "1.0", 200, "OK",
                         {"CSeq": request.headers["CSeq"]}, b"")
示例#12
0
 def bar(self, request: HttpRequest) -> Optional[HttpResponse]:
     return HttpResponse("HTTP", "1.1", 123, "dummy", {}, request.body)
示例#13
0
 def foo(self, request: HttpRequest) -> Optional[HttpResponse]:
     return HttpResponse("HTTP", "1.1", 200, "foo", {}, request.body)
示例#14
0
 def handle_teardown(self, request: HttpRequest) -> Optional[HttpResponse]:
     """Handle incoming TEARDOWN request."""
     self.state.teardown_called = True
     return HttpResponse("RTSP", "1.0", 200, "OK",
                         {"CSeq": request.headers["CSeq"]}, b"")
示例#15
0
 def _impl(self, request: HttpRequest, *args, **kwargs):
     if self.state.auth_required and not self.state.auth_setup_performed:
         return HttpResponse("RTSP", "1.0", 403, "Forbidden",
                             {"CSeq": request.headers["CSeq"]}, b"")
     return method(self, request, *args, **kwargs)