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')]