예제 #1
0
파일: middleware.py 프로젝트: te-je/ohoh
    def handle_debug_request(self, environ, start_response):
        if environ['REQUEST_METHOD'] != 'POST':
            LOG.debug("Request method invalid.")
            start_response('405 Method Not Allowed', [])
            return []

        request_headers = get_headers(environ)
        debug_token = request_headers[self.debug_header]
        LOG.debug("Unpacking context from debug header '%s: %s'",
                  self.debug_header, debug_token)
        obj = self.unpack_header(request_headers[self.debug_header])

        if obj is None:
            LOG.debug("Debug header invalid.")
            start_response("400 Bad Request", [])
            return []

        LOG.debug("Successfully unpacked: %s", obj)

        infile = environ['wsgi.input']
        input_encoding = get_content_charset(request_headers)
        outfile = StringIO()
        debugger = Pdb(stdin=BytesIO(), stdout=outfile)

        LOG.debug("Setting up the debugger.")
        if isinstance(obj, Traceback):
            # Start up the request Pdb debugger
            debugger.setup(None, obj)
            debugger.botframe = obj.tb_frame

        elif isinstance(obj, tuple):
            # It was a state-save of the pdb obj
            lineno, stack, curindex, curframe, cfl, btfm = obj
            debugger.lineno = lineno
            debugger.stack = stack
            debugger.curindex = curindex
            debugger.curframe = curframe
            debugger.curframe_locals = cfl
            debugger.botframe = btfm

        else:
            LOG.debug("Unknown context: %r", obj)
            start_response("500 Internal Server Error", [])
            return []

        # Read the text from the input stream
        n = min(
            int(request_headers.get(
                'content-length', self.max_content_length)),
            self.max_content_length
        )
        LOG.debug("Reading at most %d bytes from client.", n)
        text_bytes = infile.read(n)
        LOG.debug("Converting bytes to text using charset %r",
                  input_encoding)
        text = text_bytes.decode(input_encoding)

        LOG.debug("Sending command to debugger: %r", text)
        stop = debugger.onecmd(text)

        response = outfile.getvalue()
        LOG.debug("Debugger response: %r", response)

        headers = [("Content-Type", "text/plain; charset=utf-8")]

        if stop:
            LOG.debug("Done debugging. Not sending a header.")

        else:
            # Save the state of the debugger
            state = (
                debugger.lineno,
                debugger.stack,
                debugger.curindex,
                debugger.curframe,
                debugger.curframe_locals,
                debugger.botframe
            )
            LOG.debug("Debugger state: %r", state)
            LOG.debug("Packing debugger state into debug header: %s",
                      self.debug_header)
            debug_header = self.pack_header(state)
            LOG.debug("Debug header (%d bytes): %s",
                      len(debug_header), debug_header)
            headers.append((self.debug_header, debug_header))

        start_response("200 OK", headers)
        return [response.encode('utf-8')]