Esempio n. 1
0
    def send_response(self, already_streamed: bool = False):
        """We have either consumed the entire response from the server or the response was set by an addon."""
        assert self.flow.response
        self.flow.response.timestamp_end = time.time()
        yield HttpResponseHook(self.flow)
        self.server_state = self.state_done
        if (yield from self.check_killed(False)):
            return

        if not already_streamed:
            content = self.flow.response.raw_content
            yield SendHttp(ResponseHeaders(self.stream_id, self.flow.response, not content), self.context.client)
            if content:
                yield SendHttp(ResponseData(self.stream_id, content), self.context.client)

        yield SendHttp(ResponseEndOfMessage(self.stream_id), self.context.client)

        if self.flow.response.status_code == 101:
            is_websocket = (
                    self.flow.response.headers.get("upgrade", "").lower() == "websocket"
                    and
                    self.flow.request.headers.get("Sec-WebSocket-Version", "") == "13"
            )
            if is_websocket:
                self.child_layer = websocket.WebsocketLayer(self.context, self.flow)
            else:
                self.child_layer = tcp.TCPLayer(self.context)
            if self.debug:
                yield commands.Log(f"{self.debug}[http] upgrading to {self.child_layer}", "debug")
            yield from self.child_layer.handle_event(events.Start())
            self._handle_event = self.passthrough
            return
Esempio n. 2
0
    def send_response(self, already_streamed: bool = False):
        """We have either consumed the entire response from the server or the response was set by an addon."""
        assert self.flow.response
        self.flow.response.timestamp_end = time.time()

        is_websocket = (self.flow.response.status_code == 101
                        and self.flow.response.headers.get(
                            "upgrade", "").lower() == "websocket"
                        and self.flow.request.headers.get(
                            "Sec-WebSocket-Version",
                            "").encode() == wsproto.handshake.WEBSOCKET_VERSION
                        and self.context.options.websocket)
        if is_websocket:
            # We need to set this before calling the response hook
            # so that addons can determine if a WebSocket connection is following up.
            self.flow.websocket = WebSocketData()

        yield HttpResponseHook(self.flow)
        self.server_state = self.state_done
        if (yield from self.check_killed(False)):
            return

        if not already_streamed:
            content = self.flow.response.raw_content
            done_after_headers = not (content or self.flow.response.trailers)
            yield SendHttp(
                ResponseHeaders(self.stream_id, self.flow.response,
                                done_after_headers), self.context.client)
            if content:
                yield SendHttp(ResponseData(self.stream_id, content),
                               self.context.client)

        if self.flow.response.trailers:
            yield SendHttp(
                ResponseTrailers(self.stream_id, self.flow.response.trailers),
                self.context.client)
        yield SendHttp(ResponseEndOfMessage(self.stream_id),
                       self.context.client)

        if self.flow.response.status_code == 101:
            if is_websocket:
                self.child_layer = websocket.WebsocketLayer(
                    self.context, self.flow)
            elif self.context.options.rawtcp:
                self.child_layer = tcp.TCPLayer(self.context)
            else:
                yield commands.Log(
                    f"Sent HTTP 101 response, but no protocol is enabled to upgrade to.",
                    "warn")
                yield commands.CloseConnection(self.context.client)
                self.client_state = self.server_state = self.state_errored
                return
            if self.debug:
                yield commands.Log(
                    f"{self.debug}[http] upgrading to {self.child_layer}",
                    "debug")
            yield from self.child_layer.handle_event(events.Start())
            self._handle_event = self.passthrough
            return
Esempio n. 3
0
def ws_testdata(tctx):
    tctx.server.address = ("example.com", 80)
    tctx.server.state = ConnectionState.OPEN
    flow = HTTPFlow(tctx.client, tctx.server)
    flow.request = Request.make("GET",
                                "http://example.com/",
                                headers={
                                    "Connection": "upgrade",
                                    "Upgrade": "websocket",
                                    "Sec-WebSocket-Version": "13",
                                })
    flow.response = Response.make(101,
                                  headers={
                                      "Connection": "upgrade",
                                      "Upgrade": "websocket",
                                  })
    return tctx, Playbook(websocket.WebsocketLayer(tctx, flow))