Example #1
0
 def __call__(self, environ, start_response):
     method = environ["REQUEST_METHOD"]
     uri = urllib_parse.quote(from_wsgi_str(environ.get("SCRIPT_NAME", "")))
     uri += urllib_parse.quote(from_wsgi_str(environ.get("PATH_INFO", "")))
     if environ.get("QUERY_STRING"):
         uri += "?" + environ["QUERY_STRING"]
     headers = httputil.HTTPHeaders()
     if environ.get("CONTENT_TYPE"):
         headers["Content-Type"] = environ["CONTENT_TYPE"]
     if environ.get("CONTENT_LENGTH"):
         headers["Content-Length"] = environ["CONTENT_LENGTH"]
     for key in environ:
         if key.startswith("HTTP_"):
             headers[key[5:].replace("_", "-")] = environ[key]
     if headers.get("Content-Length"):
         body = environ["wsgi.input"].read(int(headers["Content-Length"]))
     else:
         body = b""
     protocol = environ["wsgi.url_scheme"]
     remote_ip = environ.get("REMOTE_ADDR", "")
     if environ.get("HTTP_HOST"):
         host = environ["HTTP_HOST"]
     else:
         host = environ["SERVER_NAME"]
     connection = _WSGIConnection(method, start_response,
                                  _WSGIRequestContext(remote_ip, protocol))
     request = httputil.HTTPServerRequest(method,
                                          uri,
                                          "HTTP/1.1",
                                          headers=headers,
                                          body=body,
                                          host=host,
                                          connection=connection)
     request._parse_body()
     self.application(request)
     if connection._error:
         raise connection._error
     if not connection._finished:
         raise Exception("request did not finish synchronously")
     return connection._write_buffer
Example #2
0
    def headers_received(
        self,
        start_line: Union[httputil.RequestStartLine, httputil.ResponseStartLine],
        headers: httputil.HTTPHeaders,
    ) -> Optional[Awaitable[None]]:
        assert isinstance(start_line, httputil.RequestStartLine)
        request = httputil.HTTPServerRequest(
            connection=self.request_conn,
            server_connection=self.server_conn,
            start_line=start_line,
            headers=headers,
        )

        self.delegate = self.router.find_handler(request)
        if self.delegate is None:
            app_log.debug(
                "Delegate for %s %s request not found",
                start_line.method,
                start_line.path,
            )
            self.delegate = _DefaultMessageDelegate(self.request_conn)

        return self.delegate.headers_received(start_line, headers)
Example #3
0
 def headers_received(self, start_line, headers):
     self.request = httputil.HTTPServerRequest(
         connection=self.connection, start_line=start_line,
         headers=headers)
Example #4
0
def main(argv=None):
    parser = build_parser()
    args = parser.parse_args(argv)

    if args.browser and args.server:
        parser.error("options --browser and --server are mutually exclusive")

    filename = os.path.abspath(args.filename)
    if not os.path.exists(filename):
        parser.error('the path %s does not exist' % filename)

    if not os.path.isdir(filename):
        try:
            open(filename)
        except IOError as e:
            parser.error('the file %s could not be opened: %s' %
                         (filename, str(e)))

        try:
            Stats(filename)
        except Exception:
            parser.error(
                ('The file %s is not a valid profile. ' % filename) +
                'Generate profiles using: \n\n'
                '\tpython -m cProfile -o my_program.prof my_program.py\n\n'
                'Note that snakeviz must be run under the same '
                'version of Python as was used to create the profile.\n')

    filename_ = filename
    filename = quote(filename, safe='')

    hostname = args.hostname
    port = args.port
    f = args.filenametosave
    #print(f)
    if f != "None":
        from tornado import web, httputil
        finished = web.RequestHandler.finish
        web.RequestHandler.finish = lambda self, html: setattr(
            self, "httt", html)
        w = web.RequestHandler(
            web.Application(**settings),
            httputil.HTTPServerRequest(uri="", connection=rien()))
        from .main import VizHandler
        html = VizHandler.get(w, filename_, templ="viz.html")
        html = w.httt.decode("utf-8").replace(
            "/static",
            "https://cdn.jsdelivr.net/gh/lucasiscovici/snakeviz2/snakeviz_study/static"
        )
        file = open(f, "w")
        #write then close file
        file.write(html)
        file.close()
        web.RequestHandler.finish = finished
        return 0

    if not 0 <= port <= 65535:
        parser.error('invalid port number %d: use a port between 0 and 65535' %
                     port)

    # Go ahead and import the tornado app and start it; we do an inline import
    # here to avoid the extra overhead when just running the cli for --help and
    # the like
    from .main import app
    import tornado.ioloop

    # As seen in IPython:
    # https://github.com/ipython/ipython/blob/8be7f9abd97eafb493817371d70101d28640919c/IPython/html/notebookapp.py
    # See the IPython license at:
    # https://github.com/ipython/ipython/blob/master/COPYING.rst.
    for p in random_ports(port, 10):
        try:
            app.listen(p, address=hostname)
        except socket.error as e:
            print('Port {0} in use, trying another.'.format(p))
        else:
            port = p
            break
    else:
        print('No available port found.')
        return 1

    url = "http://{0}:{1}/snakeviz/{2}".format(hostname, port, filename)
    print(('snakeviz web server started on %s:%d; enter Ctrl-C to exit' %
           (hostname, port)))
    print(url)

    if not args.server:
        try:
            browser = webbrowser.get(args.browser)
        except webbrowser.Error as e:
            parser.error('no web browser found: %s' % e)

        # Launch the browser in a separate thread to avoid blocking the
        # ioloop from starting
        def bt():
            browser.open(url, new=2)

        threading.Thread(target=bt).start()

    try:
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        # TODO: Cheap KeyboardInterrupt handler for now; iPython has some nicer
        # stuff for handling SIGINT and SIGTERM that might be worth borrowing
        tornado.ioloop.IOLoop.instance().stop()
        print('\nBye!')

    return 0