dvadf
/home/homerdlh/public_html/wp-includes/html-api/10/wsgiref.tar
handlers.py000064400000052245151543516720006737 0ustar00"""Base classes for server/gateway implementations"""

from .util import FileWrapper, guess_scheme, is_hop_by_hop
from .headers import Headers

import sys, os, time

__all__ = [
    'BaseHandler', 'SimpleHandler', 'BaseCGIHandler', 'CGIHandler',
    'IISCGIHandler', 'read_environ'
]

# Weekday and month names for HTTP date/time formatting; always English!
_weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
_monthname = [None, # Dummy so we can use 1-based month numbers
              "Jan", "Feb", "Mar", "Apr", "May", "Jun",
              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

def format_date_time(timestamp):
    year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
    return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
        _weekdayname[wd], day, _monthname[month], year, hh, mm, ss
    )

_is_request = {
    'SCRIPT_NAME', 'PATH_INFO', 'QUERY_STRING', 'REQUEST_METHOD', 'AUTH_TYPE',
    'CONTENT_TYPE', 'CONTENT_LENGTH', 'HTTPS', 'REMOTE_USER', 'REMOTE_IDENT',
}.__contains__

def _needs_transcode(k):
    return _is_request(k) or k.startswith('HTTP_') or k.startswith('SSL_') \
        or (k.startswith('REDIRECT_') and _needs_transcode(k[9:]))

def read_environ():
    """Read environment, fixing HTTP variables"""
    enc = sys.getfilesystemencoding()
    esc = 'surrogateescape'
    try:
        ''.encode('utf-8', esc)
    except LookupError:
        esc = 'replace'
    environ = {}

    # Take the basic environment from native-unicode os.environ. Attempt to
    # fix up the variables that come from the HTTP request to compensate for
    # the bytes->unicode decoding step that will already have taken place.
    for k, v in os.environ.items():
        if _needs_transcode(k):

            # On win32, the os.environ is natively Unicode. Different servers
            # decode the request bytes using different encodings.
            if sys.platform == 'win32':
                software = os.environ.get('SERVER_SOFTWARE', '').lower()

                # On IIS, the HTTP request will be decoded as UTF-8 as long
                # as the input is a valid UTF-8 sequence. Otherwise it is
                # decoded using the system code page (mbcs), with no way to
                # detect this has happened. Because UTF-8 is the more likely
                # encoding, and mbcs is inherently unreliable (an mbcs string
                # that happens to be valid UTF-8 will not be decoded as mbcs)
                # always recreate the original bytes as UTF-8.
                if software.startswith('microsoft-iis/'):
                    v = v.encode('utf-8').decode('iso-8859-1')

                # Apache mod_cgi writes bytes-as-unicode (as if ISO-8859-1) direct
                # to the Unicode environ. No modification needed.
                elif software.startswith('apache/'):
                    pass

                # Python 3's http.server.CGIHTTPRequestHandler decodes
                # using the urllib.unquote default of UTF-8, amongst other
                # issues.
                elif (
                    software.startswith('simplehttp/')
                    and 'python/3' in software
                ):
                    v = v.encode('utf-8').decode('iso-8859-1')

                # For other servers, guess that they have written bytes to
                # the environ using stdio byte-oriented interfaces, ending up
                # with the system code page.
                else:
                    v = v.encode(enc, 'replace').decode('iso-8859-1')

            # Recover bytes from unicode environ, using surrogate escapes
            # where available (Python 3.1+).
            else:
                v = v.encode(enc, esc).decode('iso-8859-1')

        environ[k] = v
    return environ


class BaseHandler:
    """Manage the invocation of a WSGI application"""

    # Configuration parameters; can override per-subclass or per-instance
    wsgi_version = (1,0)
    wsgi_multithread = True
    wsgi_multiprocess = True
    wsgi_run_once = False

    origin_server = True    # We are transmitting direct to client
    http_version  = "1.0"   # Version that should be used for response
    server_software = None  # String name of server software, if any

    # os_environ is used to supply configuration from the OS environment:
    # by default it's a copy of 'os.environ' as of import time, but you can
    # override this in e.g. your __init__ method.
    os_environ= read_environ()

    # Collaborator classes
    wsgi_file_wrapper = FileWrapper     # set to None to disable
    headers_class = Headers             # must be a Headers-like class

    # Error handling (also per-subclass or per-instance)
    traceback_limit = None  # Print entire traceback to self.get_stderr()
    error_status = "500 Internal Server Error"
    error_headers = [('Content-Type','text/plain')]
    error_body = b"A server error occurred.  Please contact the administrator."

    # State variables (don't mess with these)
    status = result = None
    headers_sent = False
    headers = None
    bytes_sent = 0

    def run(self, application):
        """Invoke the application"""
        # Note to self: don't move the close()!  Asynchronous servers shouldn't
        # call close() from finish_response(), so if you close() anywhere but
        # the double-error branch here, you'll break asynchronous servers by
        # prematurely closing.  Async servers must return from 'run()' without
        # closing if there might still be output to iterate over.
        try:
            self.setup_environ()
            self.result = application(self.environ, self.start_response)
            self.finish_response()
        except (ConnectionAbortedError, BrokenPipeError, ConnectionResetError):
            # We expect the client to close the connection abruptly from time
            # to time.
            return
        except:
            try:
                self.handle_error()
            except:
                # If we get an error handling an error, just give up already!
                self.close()
                raise   # ...and let the actual server figure it out.


    def setup_environ(self):
        """Set up the environment for one request"""

        env = self.environ = self.os_environ.copy()
        self.add_cgi_vars()

        env['wsgi.input']        = self.get_stdin()
        env['wsgi.errors']       = self.get_stderr()
        env['wsgi.version']      = self.wsgi_version
        env['wsgi.run_once']     = self.wsgi_run_once
        env['wsgi.url_scheme']   = self.get_scheme()
        env['wsgi.multithread']  = self.wsgi_multithread
        env['wsgi.multiprocess'] = self.wsgi_multiprocess

        if self.wsgi_file_wrapper is not None:
            env['wsgi.file_wrapper'] = self.wsgi_file_wrapper

        if self.origin_server and self.server_software:
            env.setdefault('SERVER_SOFTWARE',self.server_software)


    def finish_response(self):
        """Send any iterable data, then close self and the iterable

        Subclasses intended for use in asynchronous servers will
        want to redefine this method, such that it sets up callbacks
        in the event loop to iterate over the data, and to call
        'self.close()' once the response is finished.
        """
        try:
            if not self.result_is_file() or not self.sendfile():
                for data in self.result:
                    self.write(data)
                self.finish_content()
        except:
            # Call close() on the iterable returned by the WSGI application
            # in case of an exception.
            if hasattr(self.result, 'close'):
                self.result.close()
            raise
        else:
            # We only call close() when no exception is raised, because it
            # will set status, result, headers, and environ fields to None.
            # See bpo-29183 for more details.
            self.close()


    def get_scheme(self):
        """Return the URL scheme being used"""
        return guess_scheme(self.environ)


    def set_content_length(self):
        """Compute Content-Length or switch to chunked encoding if possible"""
        try:
            blocks = len(self.result)
        except (TypeError,AttributeError,NotImplementedError):
            pass
        else:
            if blocks==1:
                self.headers['Content-Length'] = str(self.bytes_sent)
                return
        # XXX Try for chunked encoding if origin server and client is 1.1


    def cleanup_headers(self):
        """Make any necessary header changes or defaults

        Subclasses can extend this to add other defaults.
        """
        if 'Content-Length' not in self.headers:
            self.set_content_length()

    def start_response(self, status, headers,exc_info=None):
        """'start_response()' callable as specified by PEP 3333"""

        if exc_info:
            try:
                if self.headers_sent:
                    # Re-raise original exception if headers sent
                    raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
            finally:
                exc_info = None        # avoid dangling circular ref
        elif self.headers is not None:
            raise AssertionError("Headers already set!")

        self.status = status
        self.headers = self.headers_class(headers)
        status = self._convert_string_type(status, "Status")
        assert len(status)>=4,"Status must be at least 4 characters"
        assert status[:3].isdigit(), "Status message must begin w/3-digit code"
        assert status[3]==" ", "Status message must have a space after code"

        if __debug__:
            for name, val in headers:
                name = self._convert_string_type(name, "Header name")
                val = self._convert_string_type(val, "Header value")
                assert not is_hop_by_hop(name),\
                       f"Hop-by-hop header, '{name}: {val}', not allowed"

        return self.write

    def _convert_string_type(self, value, title):
        """Convert/check value type."""
        if type(value) is str:
            return value
        raise AssertionError(
            "{0} must be of type str (got {1})".format(title, repr(value))
        )

    def send_preamble(self):
        """Transmit version/status/date/server, via self._write()"""
        if self.origin_server:
            if self.client_is_modern():
                self._write(('HTTP/%s %s\r\n' % (self.http_version,self.status)).encode('iso-8859-1'))
                if 'Date' not in self.headers:
                    self._write(
                        ('Date: %s\r\n' % format_date_time(time.time())).encode('iso-8859-1')
                    )
                if self.server_software and 'Server' not in self.headers:
                    self._write(('Server: %s\r\n' % self.server_software).encode('iso-8859-1'))
        else:
            self._write(('Status: %s\r\n' % self.status).encode('iso-8859-1'))

    def write(self, data):
        """'write()' callable as specified by PEP 3333"""

        assert type(data) is bytes, \
            "write() argument must be a bytes instance"

        if not self.status:
            raise AssertionError("write() before start_response()")

        elif not self.headers_sent:
            # Before the first output, send the stored headers
            self.bytes_sent = len(data)    # make sure we know content-length
            self.send_headers()
        else:
            self.bytes_sent += len(data)

        # XXX check Content-Length and truncate if too many bytes written?
        self._write(data)
        self._flush()


    def sendfile(self):
        """Platform-specific file transmission

        Override this method in subclasses to support platform-specific
        file transmission.  It is only called if the application's
        return iterable ('self.result') is an instance of
        'self.wsgi_file_wrapper'.

        This method should return a true value if it was able to actually
        transmit the wrapped file-like object using a platform-specific
        approach.  It should return a false value if normal iteration
        should be used instead.  An exception can be raised to indicate
        that transmission was attempted, but failed.

        NOTE: this method should call 'self.send_headers()' if
        'self.headers_sent' is false and it is going to attempt direct
        transmission of the file.
        """
        return False   # No platform-specific transmission by default


    def finish_content(self):
        """Ensure headers and content have both been sent"""
        if not self.headers_sent:
            # Only zero Content-Length if not set by the application (so
            # that HEAD requests can be satisfied properly, see #3839)
            self.headers.setdefault('Content-Length', "0")
            self.send_headers()
        else:
            pass # XXX check if content-length was too short?

    def close(self):
        """Close the iterable (if needed) and reset all instance vars

        Subclasses may want to also drop the client connection.
        """
        try:
            if hasattr(self.result,'close'):
                self.result.close()
        finally:
            self.result = self.headers = self.status = self.environ = None
            self.bytes_sent = 0; self.headers_sent = False


    def send_headers(self):
        """Transmit headers to the client, via self._write()"""
        self.cleanup_headers()
        self.headers_sent = True
        if not self.origin_server or self.client_is_modern():
            self.send_preamble()
            self._write(bytes(self.headers))


    def result_is_file(self):
        """True if 'self.result' is an instance of 'self.wsgi_file_wrapper'"""
        wrapper = self.wsgi_file_wrapper
        return wrapper is not None and isinstance(self.result,wrapper)


    def client_is_modern(self):
        """True if client can accept status and headers"""
        return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'


    def log_exception(self,exc_info):
        """Log the 'exc_info' tuple in the server log

        Subclasses may override to retarget the output or change its format.
        """
        try:
            from traceback import print_exception
            stderr = self.get_stderr()
            print_exception(
                exc_info[0], exc_info[1], exc_info[2],
                self.traceback_limit, stderr
            )
            stderr.flush()
        finally:
            exc_info = None

    def handle_error(self):
        """Log current error, and send error output to client if possible"""
        self.log_exception(sys.exc_info())
        if not self.headers_sent:
            self.result = self.error_output(self.environ, self.start_response)
            self.finish_response()
        # XXX else: attempt advanced recovery techniques for HTML or text?

    def error_output(self, environ, start_response):
        """WSGI mini-app to create error output

        By default, this just uses the 'error_status', 'error_headers',
        and 'error_body' attributes to generate an output page.  It can
        be overridden in a subclass to dynamically generate diagnostics,
        choose an appropriate message for the user's preferred language, etc.

        Note, however, that it's not recommended from a security perspective to
        spit out diagnostics to any old user; ideally, you should have to do
        something special to enable diagnostic output, which is why we don't
        include any here!
        """
        start_response(self.error_status,self.error_headers[:],sys.exc_info())
        return [self.error_body]


    # Pure abstract methods; *must* be overridden in subclasses

    def _write(self,data):
        """Override in subclass to buffer data for send to client

        It's okay if this method actually transmits the data; BaseHandler
        just separates write and flush operations for greater efficiency
        when the underlying system actually has such a distinction.
        """
        raise NotImplementedError

    def _flush(self):
        """Override in subclass to force sending of recent '_write()' calls

        It's okay if this method is a no-op (i.e., if '_write()' actually
        sends the data.
        """
        raise NotImplementedError

    def get_stdin(self):
        """Override in subclass to return suitable 'wsgi.input'"""
        raise NotImplementedError

    def get_stderr(self):
        """Override in subclass to return suitable 'wsgi.errors'"""
        raise NotImplementedError

    def add_cgi_vars(self):
        """Override in subclass to insert CGI variables in 'self.environ'"""
        raise NotImplementedError


class SimpleHandler(BaseHandler):
    """Handler that's just initialized with streams, environment, etc.

    This handler subclass is intended for synchronous HTTP/1.0 origin servers,
    and handles sending the entire response output, given the correct inputs.

    Usage::

        handler = SimpleHandler(
            inp,out,err,env, multithread=False, multiprocess=True
        )
        handler.run(app)"""

    def __init__(self,stdin,stdout,stderr,environ,
        multithread=True, multiprocess=False
    ):
        self.stdin = stdin
        self.stdout = stdout
        self.stderr = stderr
        self.base_env = environ
        self.wsgi_multithread = multithread
        self.wsgi_multiprocess = multiprocess

    def get_stdin(self):
        return self.stdin

    def get_stderr(self):
        return self.stderr

    def add_cgi_vars(self):
        self.environ.update(self.base_env)

    def _write(self,data):
        result = self.stdout.write(data)
        if result is None or result == len(data):
            return
        from warnings import warn
        warn("SimpleHandler.stdout.write() should not do partial writes",
            DeprecationWarning)
        while True:
            data = data[result:]
            if not data:
                break
            result = self.stdout.write(data)

    def _flush(self):
        self.stdout.flush()
        self._flush = self.stdout.flush


class BaseCGIHandler(SimpleHandler):

    """CGI-like systems using input/output/error streams and environ mapping

    Usage::

        handler = BaseCGIHandler(inp,out,err,env)
        handler.run(app)

    This handler class is useful for gateway protocols like ReadyExec and
    FastCGI, that have usable input/output/error streams and an environment
    mapping.  It's also the base class for CGIHandler, which just uses
    sys.stdin, os.environ, and so on.

    The constructor also takes keyword arguments 'multithread' and
    'multiprocess' (defaulting to 'True' and 'False' respectively) to control
    the configuration sent to the application.  It sets 'origin_server' to
    False (to enable CGI-like output), and assumes that 'wsgi.run_once' is
    False.
    """

    origin_server = False


class CGIHandler(BaseCGIHandler):

    """CGI-based invocation via sys.stdin/stdout/stderr and os.environ

    Usage::

        CGIHandler().run(app)

    The difference between this class and BaseCGIHandler is that it always
    uses 'wsgi.run_once' of 'True', 'wsgi.multithread' of 'False', and
    'wsgi.multiprocess' of 'True'.  It does not take any initialization
    parameters, but always uses 'sys.stdin', 'os.environ', and friends.

    If you need to override any of these parameters, use BaseCGIHandler
    instead.
    """

    wsgi_run_once = True
    # Do not allow os.environ to leak between requests in Google App Engine
    # and other multi-run CGI use cases.  This is not easily testable.
    # See http://bugs.python.org/issue7250
    os_environ = {}

    def __init__(self):
        BaseCGIHandler.__init__(
            self, sys.stdin.buffer, sys.stdout.buffer, sys.stderr,
            read_environ(), multithread=False, multiprocess=True
        )


class IISCGIHandler(BaseCGIHandler):
    """CGI-based invocation with workaround for IIS path bug

    This handler should be used in preference to CGIHandler when deploying on
    Microsoft IIS without having set the config allowPathInfo option (IIS>=7)
    or metabase allowPathInfoForScriptMappings (IIS<7).
    """
    wsgi_run_once = True
    os_environ = {}

    # By default, IIS gives a PATH_INFO that duplicates the SCRIPT_NAME at
    # the front, causing problems for WSGI applications that wish to implement
    # routing. This handler strips any such duplicated path.

    # IIS can be configured to pass the correct PATH_INFO, but this causes
    # another bug where PATH_TRANSLATED is wrong. Luckily this variable is
    # rarely used and is not guaranteed by WSGI. On IIS<7, though, the
    # setting can only be made on a vhost level, affecting all other script
    # mappings, many of which break when exposed to the PATH_TRANSLATED bug.
    # For this reason IIS<7 is almost never deployed with the fix. (Even IIS7
    # rarely uses it because there is still no UI for it.)

    # There is no way for CGI code to tell whether the option was set, so a
    # separate handler class is provided.
    def __init__(self):
        environ= read_environ()
        path = environ.get('PATH_INFO', '')
        script = environ.get('SCRIPT_NAME', '')
        if (path+'/').startswith(script+'/'):
            environ['PATH_INFO'] = path[len(script):]
        BaseCGIHandler.__init__(
            self, sys.stdin.buffer, sys.stdout.buffer, sys.stderr,
            environ, multithread=False, multiprocess=True
        )
simple_server.py000064400000012063151543516720010010 0ustar00"""BaseHTTPServer that implements the Python WSGI protocol (PEP 3333)

This is both an example of how WSGI can be implemented, and a basis for running
simple web applications on a local machine, such as might be done when testing
or debugging an application.  It has not been reviewed for security issues,
however, and we strongly recommend that you use a "real" web server for
production use.

For example usage, see the 'if __name__=="__main__"' block at the end of the
module.  See also the BaseHTTPServer module docs for other API information.
"""

from http.server import BaseHTTPRequestHandler, HTTPServer
import sys
import urllib.parse
from wsgiref.handlers import SimpleHandler
from platform import python_implementation

__version__ = "0.2"
__all__ = ['WSGIServer', 'WSGIRequestHandler', 'demo_app', 'make_server']


server_version = "WSGIServer/" + __version__
sys_version = python_implementation() + "/" + sys.version.split()[0]
software_version = server_version + ' ' + sys_version


class ServerHandler(SimpleHandler):

    server_software = software_version

    def close(self):
        try:
            self.request_handler.log_request(
                self.status.split(' ',1)[0], self.bytes_sent
            )
        finally:
            SimpleHandler.close(self)



class WSGIServer(HTTPServer):

    """BaseHTTPServer that implements the Python WSGI protocol"""

    application = None

    def server_bind(self):
        """Override server_bind to store the server name."""
        HTTPServer.server_bind(self)
        self.setup_environ()

    def setup_environ(self):
        # Set up base environment
        env = self.base_environ = {}
        env['SERVER_NAME'] = self.server_name
        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
        env['SERVER_PORT'] = str(self.server_port)
        env['REMOTE_HOST']=''
        env['CONTENT_LENGTH']=''
        env['SCRIPT_NAME'] = ''

    def get_app(self):
        return self.application

    def set_app(self,application):
        self.application = application



class WSGIRequestHandler(BaseHTTPRequestHandler):

    server_version = "WSGIServer/" + __version__

    def get_environ(self):
        env = self.server.base_environ.copy()
        env['SERVER_PROTOCOL'] = self.request_version
        env['SERVER_SOFTWARE'] = self.server_version
        env['REQUEST_METHOD'] = self.command
        if '?' in self.path:
            path,query = self.path.split('?',1)
        else:
            path,query = self.path,''

        env['PATH_INFO'] = urllib.parse.unquote(path, 'iso-8859-1')
        env['QUERY_STRING'] = query

        host = self.address_string()
        if host != self.client_address[0]:
            env['REMOTE_HOST'] = host
        env['REMOTE_ADDR'] = self.client_address[0]

        if self.headers.get('content-type') is None:
            env['CONTENT_TYPE'] = self.headers.get_content_type()
        else:
            env['CONTENT_TYPE'] = self.headers['content-type']

        length = self.headers.get('content-length')
        if length:
            env['CONTENT_LENGTH'] = length

        for k, v in self.headers.items():
            k=k.replace('-','_').upper(); v=v.strip()
            if k in env:
                continue                    # skip content length, type,etc.
            if 'HTTP_'+k in env:
                env['HTTP_'+k] += ','+v     # comma-separate multiple headers
            else:
                env['HTTP_'+k] = v
        return env

    def get_stderr(self):
        return sys.stderr

    def handle(self):
        """Handle a single HTTP request"""

        self.raw_requestline = self.rfile.readline(65537)
        if len(self.raw_requestline) > 65536:
            self.requestline = ''
            self.request_version = ''
            self.command = ''
            self.send_error(414)
            return

        if not self.parse_request(): # An error code has been sent, just exit
            return

        handler = ServerHandler(
            self.rfile, self.wfile, self.get_stderr(), self.get_environ(),
            multithread=False,
        )
        handler.request_handler = self      # backpointer for logging
        handler.run(self.server.get_app())



def demo_app(environ,start_response):
    from io import StringIO
    stdout = StringIO()
    print("Hello world!", file=stdout)
    print(file=stdout)
    h = sorted(environ.items())
    for k,v in h:
        print(k,'=',repr(v), file=stdout)
    start_response("200 OK", [('Content-Type','text/plain; charset=utf-8')])
    return [stdout.getvalue().encode("utf-8")]


def make_server(
    host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler
):
    """Create a new WSGI server listening on `host` and `port` for `app`"""
    server = server_class((host, port), handler_class)
    server.set_app(app)
    return server


if __name__ == '__main__':
    with make_server('', 8000, demo_app) as httpd:
        sa = httpd.socket.getsockname()
        print("Serving HTTP on", sa[0], "port", sa[1], "...")
        import webbrowser
        webbrowser.open('http://localhost:8000/xyz?abc')
        httpd.handle_request()  # serve one request, then exit
__pycache__/validate.cpython-310.opt-2.pyc000064400000025351151543516720014225 0ustar00o

���h�:�@s�	dgZddlZddlZddlZe�d�Ze�d�ZGdd�de�Zdd�Z	d	d
�Z
dd�ZGdd
�d
�ZGdd�d�Z
Gdd�d�ZGdd�d�ZGdd�d�Zdd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�ZdS)&�	validator�Nz^[a-zA-Z][a-zA-Z0-9\-_]*$z[\000-\037]c@seZdZdS)�WSGIWarningN)�__name__�
__module__�__qualname__�rr�7/opt/alt/python310/lib64/python3.10/wsgiref/validate.pyrysrcGs|st|��dS�N)�AssertionError)Zcond�argsrrr�assert_~s�rcCs$t|�tur|Std�|t|����)Nz!{0} must be of type str (got {1}))�type�strr
�format�repr)�value�titlerrr�check_string_type�s
�rcs	�fdd�}|S)Ncs�tt|�dkd�t|d�|\}�t|�g���fdd�}t|d�|d<t|d�|d<�||�}t|duo=|dkd	�t|�t|��S)
N�zTwo arguments required�No keyword arguments allowedcs�tt|�dkpt|�dkd|f�t|d�|d}|d}t|�dkr+|d}nd}t|�t|�t||�t|���d�t�|��S)Nr�zInvalid number of arguments: %srr�)r�len�check_status�
check_headers�check_content_type�check_exc_info�append�WriteWrapper)r�kw�status�headers�exc_info�Zstart_responseZstart_response_startedrr�start_response_wrapper�s�


z;validator.<locals>.lint_app.<locals>.start_response_wrapper�
wsgi.input�wsgi.errorsFz>The application must return an iterator, if only an empty list)rr�
check_environ�InputWrapper�ErrorWrapper�check_iterator�IteratorWrapper)rr�environr$�iterator��applicationr#r�lint_app�s
�
zvalidator.<locals>.lint_appr)r/r0rr.rr�s
)c@s<eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
S)r(cC�
||_dSr	)�input)�self�
wsgi_inputrrr�__init__��
zInputWrapper.__init__cGs0tt|�dk�|jj|�}tt|�tu�|S�Nr)rrr2�readr
�bytes�r3r�vrrrr8��zInputWrapper.readcGs0tt|�dk�|jj|�}tt|�tu�|Sr7)rrr2�readliner
r9r:rrrr=�r<zInputWrapper.readlinecGsJtt|�dk�|jj|�}tt|�tu�|D]
}tt|�tu�q|Sr7)rrr2�	readlinesr
�listr9)r3r�lines�linerrrr>�szInputWrapper.readlinesccs�	|��}|s
dS|Vqr	)r=)r3rArrr�__iter__�s��zInputWrapper.__iter__cC�tdd�dS)Nrz input.close() must not be called�r�r3rrr�close��zInputWrapper.closeN)	rrrr5r8r=r>rBrFrrrrr(�sr(c@�4eZdZdd�Zdd�Zdd�Zdd�Zd	d
�ZdS)r)cCr1r	)�errors)r3�wsgi_errorsrrrr5�r6zErrorWrapper.__init__cCs tt|�tu�|j�|�dSr	)rr
rrI�write�r3�srrrrK�szErrorWrapper.writecCs|j��dSr	)rI�flushrErrrrN�rGzErrorWrapper.flushcCs|D]}|�|�qdSr	)rK)r3�seqrArrr�
writelines�s�zErrorWrapper.writelinescCrC)Nrz!errors.close() must not be calledrDrErrrrF�rGzErrorWrapper.closeN)rrrr5rKrNrPrFrrrrr)�sr)c@�eZdZdd�Zdd�ZdS)rcCr1r	)�writer)r3Zwsgi_writerrrrr5�r6zWriteWrapper.__init__cCstt|�tu�|�|�dSr	)rr
r9rRrLrrr�__call__�szWriteWrapper.__call__N)rrrr5rSrrrrr��rc@rQ)�PartialIteratorWrappercCr1r	�r-)r3�
wsgi_iteratorrrrr5r6zPartialIteratorWrapper.__init__cCst|jd�Sr	)r+r-rErrrrBszPartialIteratorWrapper.__iter__N)rrrr5rBrrrrrU�rTrUc@rH)r+cCs ||_t|�|_d|_||_dS)NF)�original_iterator�iterr-�closed�check_start_response)r3rWr[rrrr5	s

zIteratorWrapper.__init__cCs|Sr	rrErrrrBszIteratorWrapper.__iter__cCsTt|jd�t|j�}t|�turtdd|f�|jdur(t|jd�d|_|S)NzIterator read after closedFz$Iterator yielded non-bytestring (%r)zjThe application returns and we started iterating over its body, but start_response has not yet been called)rrZ�nextr-r
r9r[)r3r;rrr�__next__s�

�zIteratorWrapper.__next__cCs$d|_t|jd�r|j��dSdS)NTrF)rZ�hasattrrXrFrErrrrFs�zIteratorWrapper.closecCs"|js	tj�d�t|jd�dS)Nz/Iterator garbage collected without being closed)rZ�sys�stderrrKrrErrr�__del__#s��zIteratorWrapper.__del__N)rrrr5rBr]rFrarrrrr+sr+cCs�tt|�tudt|�|f�dD]}t||vd|f�qdD]}t||vd||dd�f�q d|vr<t�dt�|��D]}d	|vrGq@tt||�tud
|t||�||f�q@tt|d�tud|df�t|d
dvd|d
�t	|d�t
|d�|ddvr�t�d|dt�t|�d�p�|d�d�d|d�t|�d�p�|d�d�d|d�|�d�r�tt
|d�dkd|d�|�d�s�td|vd�t|�d�dkd�dS)Nz:Environment is not of the right type: %r (environment: %r))	�REQUEST_METHODZSERVER_NAMEZSERVER_PORT�wsgi.versionr%r&zwsgi.multithreadzwsgi.multiprocessz
wsgi.run_oncez$Environment missing required key: %r)ZHTTP_CONTENT_TYPEZHTTP_CONTENT_LENGTHz8Environment should not have the key: %s (use %s instead)�ZQUERY_STRINGz�QUERY_STRING is not in the WSGI environment; the cgi module will use sys.argv when this variable is missing, so application errors are more likely�.z9Environmental variable %s is not a string: %r (value: %r)rcz#wsgi.version should be a tuple (%r)zwsgi.url_scheme)ZhttpZhttpszwsgi.url_scheme unknown: %rr%r&rb)ZGETZHEADZPOSTZOPTIONSZPATCHZPUTZDELETEZTRACEzUnknown REQUEST_METHOD: %rZSCRIPT_NAME�/z$SCRIPT_NAME doesn't start with /: %rZ	PATH_INFOz"PATH_INFO doesn't start with /: %rZCONTENT_LENGTHrzInvalid CONTENT_LENGTH: %rzgOne of SCRIPT_NAME or PATH_INFO are required (PATH_INFO should at least be '/' if SCRIPT_NAME is empty)zOSCRIPT_NAME cannot be '/'; it should instead be '', and PATH_INFO should be '/')rr
�dict�warnings�warnr�keysr�tuple�check_input�check_errors�get�
startswith�int)r,�keyrrrr'*sx
���������
�
�
�
�

�
��r'cC�&dD]}tt||�d||f�qdS)N)r8r=r>rBz-wsgi.input (%r) doesn't have the attribute %s�rr^)r4�attrrrrrlk�
���rlcCrr)N)rNrKrPz.wsgi.errors (%r) doesn't have the attribute %srs)rJrtrrrrmqrurmcCszt|d�}|�dd�d}tt|�dkd|�t|�}t|dkd|�t|�dks1|dd	kr;t�d
|t�dSdS)N�Statusrrrz)Status codes must be three characters: %r�dzStatus code is invalid: %r�� zjThe status string (%r) should be a three-digit integer followed by a single space and a status explanation)r�splitrrrprhrir)r Zstatus_codeZ
status_intrrrrws
����rcCstt|�tud|t|�f�|D]n}tt|�tud|t|�f�tt|�dk�|\}}t|d�}t|d�}t|��dkd|�td|voKd	|vd
|�tt�|�d|�t|�	d�of|�	d
�d|�t
�|�rtdd|t
�|��d�f�qdS)Nz%Headers (%r) must be of type list: %rz1Individual headers (%r) must be of type tuple: %rr�Header namezHeader valuer zyThe Status header cannot be used; it conflicts with CGI script, and HTTP status is not given through headers (value: %r).�
�:z,Header names may not contain ':' or '\n': %rzBad header name: %r�-�_z#Names may not end in '-' or '_': %rrz#Bad header value: %r (bad char: %r))rr
r?rkrr�lower�	header_re�search�endswith�bad_header_value_re�group)r!�item�namerrrrr�sB
��
��

����
���rcCs�t|d�}t|�dd�d�}d}|D]\}}t|d�}|��dkr0||vr)dStdd|�q||vr>tdd|�dSdS)	Nrvrr)��i0r{zcontent-typezJContent-Type header found in a %s response, which must not return content.z,No Content-Type header found in headers (%s))rrprzr�r)r r!�codeZNO_MESSAGE_BODYr�rrrrr�s

���rcCs*t|dup
t|�tud|t|�f�dS)Nz exc_info (%r) is not a tuple: %r)rr
rk)r"rrrr�s�rcCstt|ttf�d�dS)NzwYou should not return a string as your application iterator, instead return a single-item list containing a bytestring.)r�
isinstancerr9rVrrrr*�s�r*)�__all__�rer_rh�compiler�r��Warningrrrrr(r)rrUr+r'rlrmrrrrr*rrrr�<module>s0j

7#		#A__pycache__/validate.cpython-310.opt-1.pyc000064400000034422151543516720014223 0ustar00o

���h�:�@s�dZdgZddlZddlZddlZe�d�Ze�d�ZGdd�de�Z	dd	�Z
d
d�Zdd�ZGd
d�d�Z
Gdd�d�ZGdd�d�ZGdd�d�ZGdd�d�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�ZdS)'a&
Middleware to check for obedience to the WSGI specification.

Some of the things this checks:

* Signature of the application and start_response (including that
  keyword arguments are not used).

* Environment checks:

  - Environment is a dictionary (and not a subclass).

  - That all the required keys are in the environment: REQUEST_METHOD,
    SERVER_NAME, SERVER_PORT, wsgi.version, wsgi.input, wsgi.errors,
    wsgi.multithread, wsgi.multiprocess, wsgi.run_once

  - That HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH are not in the
    environment (these headers should appear as CONTENT_LENGTH and
    CONTENT_TYPE).

  - Warns if QUERY_STRING is missing, as the cgi module acts
    unpredictably in that case.

  - That CGI-style variables (that don't contain a .) have
    (non-unicode) string values

  - That wsgi.version is a tuple

  - That wsgi.url_scheme is 'http' or 'https' (@@: is this too
    restrictive?)

  - Warns if the REQUEST_METHOD is not known (@@: probably too
    restrictive).

  - That SCRIPT_NAME and PATH_INFO are empty or start with /

  - That at least one of SCRIPT_NAME or PATH_INFO are set.

  - That CONTENT_LENGTH is a positive integer.

  - That SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should
    be '/').

  - That wsgi.input has the methods read, readline, readlines, and
    __iter__

  - That wsgi.errors has the methods flush, write, writelines

* The status is a string, contains a space, starts with an integer,
  and that integer is in range (> 100).

* That the headers is a list (not a subclass, not another kind of
  sequence).

* That the items of the headers are tuples of strings.

* That there is no 'status' header (that is used in CGI, but not in
  WSGI).

* That the headers don't contain newlines or colons, end in _ or -, or
  contain characters codes below 037.

* That Content-Type is given if there is content (CGI often has a
  default content type, but WSGI does not).

* That no Content-Type is given when there is no content (@@: is this
  too restrictive?)

* That the exc_info argument to start_response is a tuple or None.

* That all calls to the writer are with strings, and no other methods
  on the writer are accessed.

* That wsgi.input is used properly:

  - .read() is called with exactly one argument

  - That it returns a string

  - That readline, readlines, and __iter__ return strings

  - That .close() is not called

  - No other methods are provided

* That wsgi.errors is used properly:

  - .write() and .writelines() is called with a string

  - That .close() is not called, and no other methods are provided.

* The response iterator:

  - That it is not a string (it should be a list of a single string; a
    string will work, but perform horribly).

  - That .__next__() returns a string

  - That the iterator is not iterated over until start_response has
    been called (that can signal either a server or application
    error).

  - That .close() is called (doesn't raise exception, only prints to
    sys.stderr, because we only know it isn't called when the object
    is garbage collected).
�	validator�Nz^[a-zA-Z][a-zA-Z0-9\-_]*$z[\000-\037]c@seZdZdZdS)�WSGIWarningz:
    Raised in response to WSGI-spec-related warnings
    N)�__name__�
__module__�__qualname__�__doc__�rr�7/opt/alt/python310/lib64/python3.10/wsgiref/validate.pyrysrcGs|st|��dS�N)�AssertionError)Zcond�argsrrr	�assert_~s�r
cCs$t|�tur|Std�|t|����)Nz!{0} must be of type str (got {1}))�type�strr�format�repr)�value�titlerrr	�check_string_type�s
�rcs�fdd�}|S)a�
    When applied between a WSGI server and a WSGI application, this
    middleware will check for WSGI compliance on a number of levels.
    This middleware does not modify the request or response in any
    way, but will raise an AssertionError if anything seems off
    (except for a failure to close the application iterator, which
    will be printed to stderr -- there's no way to raise an exception
    at that point).
    cs�tt|�dkd�t|d�|\}�t|�g���fdd�}t|d�|d<t|d�|d<�||�}t|duo=|dkd	�t|�t|��S)
N�zTwo arguments required�No keyword arguments allowedcs�tt|�dkpt|�dkd|f�t|d�|d}|d}t|�dkr+|d}nd}t|�t|�t||�t|���d�t�|��S)Nr�zInvalid number of arguments: %srr�)r
�len�check_status�
check_headers�check_content_type�check_exc_info�append�WriteWrapper)r�kw�status�headers�exc_info�Zstart_responseZstart_response_startedrr	�start_response_wrapper�s�


z;validator.<locals>.lint_app.<locals>.start_response_wrapper�
wsgi.input�wsgi.errorsFz>The application must return an iterator, if only an empty list)r
r�
check_environ�InputWrapper�ErrorWrapper�check_iterator�IteratorWrapper)rr �environr%�iterator��applicationr$r	�lint_app�s
�
zvalidator.<locals>.lint_appr)r0r1rr/r	r�s)c@s<eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
S)r)cC�
||_dSr
)�input)�self�
wsgi_inputrrr	�__init__��
zInputWrapper.__init__cGs0tt|�dk�|jj|�}tt|�tu�|S�Nr)r
rr3�readr�bytes�r4r�vrrr	r9��zInputWrapper.readcGs0tt|�dk�|jj|�}tt|�tu�|Sr8)r
rr3�readlinerr:r;rrr	r>�r=zInputWrapper.readlinecGsJtt|�dk�|jj|�}tt|�tu�|D]
}tt|�tu�q|Sr8)r
rr3�	readlinesr�listr:)r4r�lines�linerrr	r?�szInputWrapper.readlinesccs�	|��}|s
dS|Vqr
)r>)r4rBrrr	�__iter__�s��zInputWrapper.__iter__cC�tdd�dS)Nrz input.close() must not be called�r
�r4rrr	�close��zInputWrapper.closeN)	rrrr6r9r>r?rCrGrrrr	r)�sr)c@�4eZdZdd�Zdd�Zdd�Zdd�Zd	d
�ZdS)r*cCr2r
)�errors)r4�wsgi_errorsrrr	r6�r7zErrorWrapper.__init__cCs tt|�tu�|j�|�dSr
)r
rrrJ�write�r4�srrr	rL�szErrorWrapper.writecCs|j��dSr
)rJ�flushrFrrr	rO�rHzErrorWrapper.flushcCs|D]}|�|�qdSr
)rL)r4�seqrBrrr	�
writelines�s�zErrorWrapper.writelinescCrD)Nrz!errors.close() must not be calledrErFrrr	rG�rHzErrorWrapper.closeN)rrrr6rLrOrQrGrrrr	r*�sr*c@�eZdZdd�Zdd�ZdS)rcCr2r
)�writer)r4Zwsgi_writerrrr	r6�r7zWriteWrapper.__init__cCstt|�tu�|�|�dSr
)r
rr:rSrMrrr	�__call__�szWriteWrapper.__call__N)rrrr6rTrrrr	r��rc@rR)�PartialIteratorWrappercCr2r
�r.)r4�
wsgi_iteratorrrr	r6r7zPartialIteratorWrapper.__init__cCst|jd�Sr
)r,r.rFrrr	rCszPartialIteratorWrapper.__iter__N)rrrr6rCrrrr	rV�rUrVc@rI)r,cCs ||_t|�|_d|_||_dS)NF)�original_iterator�iterr.�closed�check_start_response)r4rXr\rrr	r6	s

zIteratorWrapper.__init__cCs|Sr
rrFrrr	rCszIteratorWrapper.__iter__cCsTt|jd�t|j�}t|�turtdd|f�|jdur(t|jd�d|_|S)NzIterator read after closedFz$Iterator yielded non-bytestring (%r)zjThe application returns and we started iterating over its body, but start_response has not yet been called)r
r[�nextr.rr:r\)r4r<rrr	�__next__s�

�zIteratorWrapper.__next__cCs$d|_t|jd�r|j��dSdS)NTrG)r[�hasattrrYrGrFrrr	rGs�zIteratorWrapper.closecCs"|js	tj�d�t|jd�dS)Nz/Iterator garbage collected without being closed)r[�sys�stderrrLr
rFrrr	�__del__#s��zIteratorWrapper.__del__N)rrrr6rCr^rGrbrrrr	r,sr,cCs�tt|�tudt|�|f�dD]}t||vd|f�qdD]}t||vd||dd�f�q d|vr<t�dt�|��D]}d	|vrGq@tt||�tud
|t||�||f�q@tt|d�tud|df�t|d
dvd|d
�t	|d�t
|d�|ddvr�t�d|dt�t|�d�p�|d�d�d|d�t|�d�p�|d�d�d|d�|�d�r�tt
|d�dkd|d�|�d�s�td|vd�t|�d�dkd�dS)Nz:Environment is not of the right type: %r (environment: %r))	�REQUEST_METHODZSERVER_NAMEZSERVER_PORT�wsgi.versionr&r'zwsgi.multithreadzwsgi.multiprocessz
wsgi.run_oncez$Environment missing required key: %r)ZHTTP_CONTENT_TYPEZHTTP_CONTENT_LENGTHz8Environment should not have the key: %s (use %s instead)�ZQUERY_STRINGz�QUERY_STRING is not in the WSGI environment; the cgi module will use sys.argv when this variable is missing, so application errors are more likely�.z9Environmental variable %s is not a string: %r (value: %r)rdz#wsgi.version should be a tuple (%r)zwsgi.url_scheme)ZhttpZhttpszwsgi.url_scheme unknown: %rr&r'rc)ZGETZHEADZPOSTZOPTIONSZPATCHZPUTZDELETEZTRACEzUnknown REQUEST_METHOD: %rZSCRIPT_NAME�/z$SCRIPT_NAME doesn't start with /: %rZ	PATH_INFOz"PATH_INFO doesn't start with /: %rZCONTENT_LENGTHrzInvalid CONTENT_LENGTH: %rzgOne of SCRIPT_NAME or PATH_INFO are required (PATH_INFO should at least be '/' if SCRIPT_NAME is empty)zOSCRIPT_NAME cannot be '/'; it should instead be '', and PATH_INFO should be '/')r
r�dict�warnings�warnr�keysr�tuple�check_input�check_errors�get�
startswith�int)r-�keyrrr	r(*sx
���������
�
�
�
�

�
��r(cC�&dD]}tt||�d||f�qdS)N)r9r>r?rCz-wsgi.input (%r) doesn't have the attribute %s�r
r_)r5�attrrrr	rmk�
���rmcCrs)N)rOrLrQz.wsgi.errors (%r) doesn't have the attribute %srt)rKrurrr	rnqrvrncCszt|d�}|�dd�d}tt|�dkd|�t|�}t|dkd|�t|�dks1|dd	kr;t�d
|t�dSdS)N�Statusrrrz)Status codes must be three characters: %r�dzStatus code is invalid: %r�� zjThe status string (%r) should be a three-digit integer followed by a single space and a status explanation)r�splitr
rrqrirjr)r!Zstatus_codeZ
status_intrrr	rws
����rcCstt|�tud|t|�f�|D]n}tt|�tud|t|�f�tt|�dk�|\}}t|d�}t|d�}t|��dkd|�td|voKd	|vd
|�tt�|�d|�t|�	d�of|�	d
�d|�t
�|�rtdd|t
�|��d�f�qdS)Nz%Headers (%r) must be of type list: %rz1Individual headers (%r) must be of type tuple: %rr�Header namezHeader valuer!zyThe Status header cannot be used; it conflicts with CGI script, and HTTP status is not given through headers (value: %r).�
�:z,Header names may not contain ':' or '\n': %rzBad header name: %r�-�_z#Names may not end in '-' or '_': %rrz#Bad header value: %r (bad char: %r))r
rr@rlrr�lower�	header_re�search�endswith�bad_header_value_re�group)r"�item�namerrrr	r�sB
��
��

����
���rcCs�t|d�}t|�dd�d�}d}|D]\}}t|d�}|��dkr0||vr)dStdd|�q||vr>tdd|�dSdS)	Nrwrr)��i0r|zcontent-typezJContent-Type header found in a %s response, which must not return content.z,No Content-Type header found in headers (%s))rrqr{r�r
)r!r"�codeZNO_MESSAGE_BODYr�rrrr	r�s

���rcCs*t|dup
t|�tud|t|�f�dS)Nz exc_info (%r) is not a tuple: %r)r
rrl)r#rrr	r�s�rcCstt|ttf�d�dS)NzwYou should not return a string as your application iterator, instead return a single-item list containing a bytestring.)r
�
isinstancerr:rWrrr	r+�s�r+)r�__all__�rer`ri�compiler�r��Warningrr
rrr)r*rrVr,r(rmrnrrrrr+rrrr	�<module>s0j

7#		#A__pycache__/headers.cpython-310.opt-2.pyc000064400000010655151543516720014050 0ustar00o

���hn�@s0	ddlZe�d�Zddd�ZGdd�d�ZdS)	�Nz[ \(\)<>@,;:\\"/\[\]\?=]�cCsT	|dur(t|�dkr(|st�|�r"|�dd��dd�}d||fSd||fS|S)Nr�\z\\�"z\"z%s="%s"z%s=%s)�len�	tspecials�search�replace)Zparam�valueZquote�r
�6/opt/alt/python310/lib64/python3.10/wsgiref/headers.py�_formatparam
src@s�eZdZ	d$dd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
d$dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�ZdS)%�HeadersNcCs.|dur|ng}t|�turtd��||_dS)Nz+Headers must be a list of name/value tuples)�type�list�	TypeError�_headers�_convert_string_type)�selfZheaders�k�vr
r
r�__init__s
zHeaders.__init__cCs$	t|�tur	|Std�t|����)Nz1Header names/values must be of type str (got {0}))r�str�AssertionError�format�repr)rr	r
r
rr)s
�zHeaders._convert_string_typecCs	t|j�S�N)rr�rr
r
r�__len__0s
zHeaders.__len__cCs(	||=|j�|�|�|�|�f�dSr)r�appendr)r�name�valr
r
r�__setitem__4s
�zHeaders.__setitem__cs2	|�������fdd�|jD�|jdd�<dS)Ncs g|]}|d���kr|�qS)r��lower��.0Zkv�rr
r�
<listcomp>@s z'Headers.__delitem__.<locals>.<listcomp>�rr#r�rrr
r&r�__delitem__:s"zHeaders.__delitem__cCs	|�|�Sr��getr)r
r
r�__getitem__Bs
zHeaders.__getitem__cCs	|�|�duSrr+r)r
r
r�__contains__MszHeaders.__contains__cs$	|�������fdd�|jD�S)Ncs$g|]}|d���kr|d�qS)rrr"r$r&r
rr'[s$z#Headers.get_all.<locals>.<listcomp>r(r)r
r&r�get_allRszHeaders.get_allcCs8	|�|���}|jD]\}}|��|kr|Sq|Srr()rr�defaultrrr
r
rr,^s�zHeaders.getcC�	dd�|jD�S)NcSsg|]\}}|�qSr
r
�r%rrr
r
rr'o�z Headers.keys.<locals>.<listcomp>�rrr
r
r�keysg�zHeaders.keyscCr1)NcSsg|]\}}|�qSr
r
r2r
r
rr'yr3z"Headers.values.<locals>.<listcomp>r4rr
r
r�valuesqr6zHeaders.valuescCs	|jdd�Srr4rr
r
r�items{sz
Headers.itemscCsd|jj|jfS)Nz%s(%r))�	__class__�__name__rrr
r
r�__repr__�szHeaders.__repr__cCs 	d�dd�|jD�ddg�S)Nz
cSsg|]}d|�qS)z%s: %sr
r$r
r
rr'�r3z#Headers.__str__.<locals>.<listcomp>�)�joinrrr
r
r�__str__�szHeaders.__str__cCst|��d�S)Nz
iso-8859-1)r�encoderr
r
r�	__bytes__�szHeaders.__bytes__cCs8	|�|�}|dur|j�|�|�|�|�f�|S|Sr)r,rrr)rrr	�resultr
r
r�
setdefault�s
�zHeaders.setdefaultcKs�	g}|dur|�|�}|�|�|��D](\}}|�|�}|dur,|�|�dd��q|�|�}|�t|�dd�|��q|j�|�|�d�|�f�dS)N�_�-z; )rrr8rrrr=)r�_nameZ_valueZ_params�partsrrr
r
r�
add_header�s



 zHeaders.add_headerr)r:�
__module__�__qualname__rrrr!r*r-r.r/r,r5r7r8r;r>r@rBrGr
r
r
rr
s&


	



r
)Nr)�re�compilerrr
r
r
r
r�<module>s
	

__pycache__/__init__.cpython-310.opt-2.pyc000064400000000224151543516720014163 0ustar00o

���hK�@sdS)N�rrr�7/opt/alt/python310/lib64/python3.10/wsgiref/__init__.py�<module>s__pycache__/__init__.cpython-310.pyc000064400000001347151543516720013232 0ustar00o

���hK�@sdZdS)aDwsgiref -- a WSGI (PEP 3333) Reference Library

Current Contents:

* util -- Miscellaneous useful functions and wrappers

* headers -- Manage response headers

* handlers -- base classes for server/gateway implementations

* simple_server -- a simple BaseHTTPServer that supports WSGI

* validate -- validation wrapper that sits between an app and a server
  to detect errors in either

To-Do:

* cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard)

* cgi_wrapper -- Run CGI apps under WSGI

* router -- a simple middleware component that handles URL traversal
N)�__doc__�rr�7/opt/alt/python310/lib64/python3.10/wsgiref/__init__.py�<module>s__pycache__/__init__.cpython-310.opt-1.pyc000064400000001347151543516720014171 0ustar00o

���hK�@sdZdS)aDwsgiref -- a WSGI (PEP 3333) Reference Library

Current Contents:

* util -- Miscellaneous useful functions and wrappers

* headers -- Manage response headers

* handlers -- base classes for server/gateway implementations

* simple_server -- a simple BaseHTTPServer that supports WSGI

* validate -- validation wrapper that sits between an app and a server
  to detect errors in either

To-Do:

* cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard)

* cgi_wrapper -- Run CGI apps under WSGI

* router -- a simple middleware component that handles URL traversal
N)�__doc__�rr�7/opt/alt/python310/lib64/python3.10/wsgiref/__init__.py�<module>s__pycache__/util.cpython-310.opt-1.pyc000064400000012457151543516720013413 0ustar00o

���h��@sbdZddlZgd�ZGdd�d�Zdd�Zdd	�Zddd�Zd
d�Zdd�Zhd�j	Z
dd�ZdS)z$Miscellaneous WSGI-related Utilities�N)�FileWrapper�guess_scheme�application_uri�request_uri�shift_path_info�setup_testing_defaultsc@s2eZdZdZddd�Zdd�Zdd�Zd	d
�ZdS)
rz1Wrapper to convert file-like objects to iterables� cCs&||_||_t|d�r|j|_dSdS)N�close)�filelike�blksize�hasattrr	)�selfr
r�r�3/opt/alt/python310/lib64/python3.10/wsgiref/util.py�__init__s

�zFileWrapper.__init__cCs2ddl}|jdtdd�|j�|j�}|r|St�)NrzXFileWrapper's __getitem__ method ignores 'key' parameter. Use iterator protocol instead.�)�
stacklevel)�warnings�warn�DeprecationWarningr
�readr�
IndexError)r
�keyr�datarrr�__getitem__s�zFileWrapper.__getitem__cCs|S�Nr)r
rrr�__iter__!szFileWrapper.__iter__cCs|j�|j�}|r|St�r)r
rr�
StopIteration)r
rrrr�__next__$szFileWrapper.__next__N)r)�__name__�
__module__�__qualname__�__doc__rrrrrrrrrs

rcCs|�d�dvr	dSdS)zMReturn a guess for whether 'wsgi.url_scheme' should be 'http' or 'https'
    ZHTTPS)ZyesZon�1�https�http)�get)�environrrrr*srcCs�|dd}ddlm}|�d�r||d7}n)||d7}|ddkr3|dd	kr2|d
|d7}n|ddkrA|d
|d7}|||�d�pId
dd�7}|S)z@Return the application's base URI (no PATH_INFO or QUERY_STRING)�wsgi.url_schemez://r��quote�	HTTP_HOST�SERVER_NAMEr$�SERVER_PORT�443�:�80�SCRIPT_NAME�/�latin1)�encoding)�urllib.parser*r&)r'�urlr*rrrr2s
�rTcCspt|�}ddlm}||�dd�ddd�}|�d�s#||d	d
�7}n||7}|r6|�d�r6|d|d7}|S)
zBReturn the full request URI, optionally including the query stringrr)�	PATH_INFO�z/;=,r3)Zsafer4r1�NZQUERY_STRING�?)rr5r*r&)r'Z
include_queryr6r*�	path_inforrrrFs
rcCs�|�dd�}|s
dS|�d�}dd�|dd�D�|dd�<|d}|d=|�d	d�}t�|d|�}|�d�r?|dd�}|sJ|�d�sJ|d7}||d	<d�|�|d<|d
kr[d}|S)aZShift a name from PATH_INFO to SCRIPT_NAME, returning it

    If there are no remaining path segments in PATH_INFO, return None.
    Note: 'environ' is modified in-place; use a copy if you need to keep
    the original PATH_INFO or SCRIPT_NAME.

    Note: when PATH_INFO is just a '/', this returns '' and appends a trailing
    '/' to SCRIPT_NAME, even though empty path segments are normally ignored,
    and SCRIPT_NAME doesn't normally end in a '/'.  This is intentional
    behavior, to ensure that an application can tell the difference between
    '/x' and '/x/' when traversing to objects.
    r7r8Nr2cSsg|]
}|r|dkr|�qS)�.r)�.0�prrr�
<listcomp>esz#shift_path_info.<locals>.<listcomp>r9���r1r<)r&�split�	posixpath�normpath�endswith�join)r'r;�
path_parts�nameZscript_namerrrrSs$


rcCs|�dd�|�dd�|�d|d�|�dd�d|vr.d	|vr.|�dd
�|�d	d�|�dd
�|�dd�|�dd�|�dd�ddlm}m}|�d|��|�d|��|�dt|��|ddkrr|�dd�dS|ddkr�|�dd�dSdS)a:Update 'environ' with trivial defaults for testing purposes

    This adds various parameters required for WSGI, including HTTP_HOST,
    SERVER_NAME, SERVER_PORT, REQUEST_METHOD, SCRIPT_NAME, PATH_INFO,
    and all of the wsgi.* variables.  It only supplies default values,
    and does not replace any existing settings for these variables.

    This routine is intended to make it easier for unit tests of WSGI
    servers and applications to set up dummy environments.  It should *not*
    be used by actual WSGI servers or applications, since the data is fake!
    r,z	127.0.0.1ZSERVER_PROTOCOLzHTTP/1.0r+ZREQUEST_METHODZGETr1r7r8r2zwsgi.version)r9rz
wsgi.run_oncerzwsgi.multithreadzwsgi.multiprocess)�StringIO�BytesIOz
wsgi.inputzwsgi.errorsr(r%r-r0r$r.N)�
setdefault�iorHrIr)r'rHrIrrrr|s(
�r>zproxy-authenticateZupgradeztransfer-encodingz
keep-alive�teZtrailerszproxy-authorizationZ
connectioncCst|���S)z?Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header)�_hoppish�lower)Zheader_namerrr�
is_hop_by_hop�srO)T)r"rB�__all__rrrrrr�__contains__rMrOrrrr�<module>s

)(�__pycache__/headers.cpython-310.opt-1.pyc000064400000017007151543516720014045 0ustar00o

���hn�@s2dZddlZe�d�Zd	dd�ZGdd�d�ZdS)
z�Manage HTTP Response Headers

Much of this module is red-handedly pilfered from email.message in the stdlib,
so portions are Copyright (C) 2001,2002 Python Software Foundation, and were
written by Barry Warsaw.
�Nz[ \(\)<>@,;:\\"/\[\]\?=]�cCsR|dur't|�dkr'|st�|�r!|�dd��dd�}d||fSd||fS|S)	z~Convenience function to format and return a key=value pair.

    This will quote the value if needed or if quote is true.
    Nr�\z\\�"z\"z%s="%s"z%s=%s)�len�	tspecials�search�replace)Zparam�valueZquote�r
�6/opt/alt/python310/lib64/python3.10/wsgiref/headers.py�_formatparam
src@s�eZdZdZd%dd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zd%dd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�ZdS)&�Headersz,Manage a collection of HTTP response headersNcCs.|dur|ng}t|�turtd��||_dS)Nz+Headers must be a list of name/value tuples)�type�list�	TypeError�_headers�_convert_string_type)�selfZheaders�k�vr
r
r�__init__s
zHeaders.__init__cCs"t|�tur|Std�t|����)zConvert/check value type.z1Header names/values must be of type str (got {0}))r�str�AssertionError�format�repr)rr	r
r
rr)s

�zHeaders._convert_string_typecCs
t|j�S)z9Return the total number of headers, including duplicates.)rr�rr
r
r�__len__0s
zHeaders.__len__cCs&||=|j�|�|�|�|�f�dS)zSet the value of a header.N)r�appendr)r�name�valr
r
r�__setitem__4s�zHeaders.__setitem__cs0|�������fdd�|jD�|jdd�<dS)zyDelete all occurrences of a header, if present.

        Does *not* raise an exception if the header is missing.
        cs g|]}|d���kr|�qS)r��lower��.0Zkv�rr
r�
<listcomp>@s z'Headers.__delitem__.<locals>.<listcomp>N�rr"r�rrr
r%r�__delitem__:s"zHeaders.__delitem__cCs
|�|�S)aHGet the first header value for 'name'

        Return None if the header is missing instead of raising an exception.

        Note that if the header appeared multiple times, the first exactly which
        occurrence gets returned is undefined.  Use getall() to get all
        the values matching a header field name.
        ��getr(r
r
r�__getitem__Bs
	zHeaders.__getitem__cCs|�|�duS)z/Return true if the message contains the header.Nr*r(r
r
r�__contains__MszHeaders.__contains__cs"|�������fdd�|jD�S)aqReturn a list of all the values for the named field.

        These will be sorted in the order they appeared in the original header
        list or were added to this instance, and may contain duplicates.  Any
        fields deleted and re-inserted are always appended to the header list.
        If no fields exist with the given name, returns an empty list.
        cs$g|]}|d���kr|d�qS)rrr!r#r%r
rr&[s$z#Headers.get_all.<locals>.<listcomp>r'r(r
r%r�get_allRszHeaders.get_allcCs6|�|���}|jD]\}}|��|kr|Sq
|S)z:Get the first header value for 'name', or return 'default'r')rr�defaultrrr
r
rr+^s�zHeaders.getcC�dd�|jD�S)a*Return a list of all the header field names.

        These will be sorted in the order they appeared in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        cSsg|]\}}|�qSr
r
�r$rrr
r
rr&o�z Headers.keys.<locals>.<listcomp>�rrr
r
r�keysg�zHeaders.keyscCr0)a!Return a list of all header values.

        These will be sorted in the order they appeared in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        cSsg|]\}}|�qSr
r
r1r
r
rr&yr2z"Headers.values.<locals>.<listcomp>r3rr
r
r�valuesqr5zHeaders.valuescCs|jdd�S)aGet all the header fields and values.

        These will be sorted in the order they were in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        Nr3rr
r
r�items{sz
Headers.itemscCsd|jj|jfS)Nz%s(%r))�	__class__�__name__rrr
r
r�__repr__�szHeaders.__repr__cCsd�dd�|jD�ddg�S)zkstr() returns the formatted headers, complete with end line,
        suitable for direct HTTP transmission.z
cSsg|]}d|�qS)z%s: %sr
r#r
r
rr&�r2z#Headers.__str__.<locals>.<listcomp>�)�joinrrr
r
r�__str__�szHeaders.__str__cCst|��d�S)Nz
iso-8859-1)r�encoderr
r
r�	__bytes__�szHeaders.__bytes__cCs6|�|�}|dur|j�|�|�|�|�f�|S|S)z�Return first matching header value for 'name', or 'value'

        If there is no header named 'name', add a new header with name 'name'
        and value 'value'.N)r+rrr)rrr	�resultr
r
r�
setdefault�s
�zHeaders.setdefaultcKs�g}|dur|�|�}|�|�|��D](\}}|�|�}|dur+|�|�dd��q|�|�}|�t|�dd�|��q|j�|�|�d�|�f�dS)afExtended header setting.

        _name is the header field to add.  keyword arguments can be used to set
        additional parameters for the header field, with underscores converted
        to dashes.  Normally the parameter will be added as key="value" unless
        value is None, in which case only the key will be added.

        Example:

        h.add_header('content-disposition', 'attachment', filename='bud.gif')

        Note that unlike the corresponding 'email.message' method, this does
        *not* handle '(charset, language, value)' tuples: all values must be
        strings or None.
        N�_�-z; )rrr7rrrr<)r�_nameZ_valueZ_params�partsrrr
r
r�
add_header�s



 zHeaders.add_header)N)r9�
__module__�__qualname__�__doc__rrrr r)r,r-r.r+r4r6r7r:r=r?rArFr
r
r
rr
s&


	



r
)Nr)rI�re�compilerrr
r
r
r
r�<module>s
	

__pycache__/util.cpython-310.pyc000064400000012457151543516720012454 0ustar00o

���h��@sbdZddlZgd�ZGdd�d�Zdd�Zdd	�Zddd�Zd
d�Zdd�Zhd�j	Z
dd�ZdS)z$Miscellaneous WSGI-related Utilities�N)�FileWrapper�guess_scheme�application_uri�request_uri�shift_path_info�setup_testing_defaultsc@s2eZdZdZddd�Zdd�Zdd�Zd	d
�ZdS)
rz1Wrapper to convert file-like objects to iterables� cCs&||_||_t|d�r|j|_dSdS)N�close)�filelike�blksize�hasattrr	)�selfr
r�r�3/opt/alt/python310/lib64/python3.10/wsgiref/util.py�__init__s

�zFileWrapper.__init__cCs2ddl}|jdtdd�|j�|j�}|r|St�)NrzXFileWrapper's __getitem__ method ignores 'key' parameter. Use iterator protocol instead.�)�
stacklevel)�warnings�warn�DeprecationWarningr
�readr�
IndexError)r
�keyr�datarrr�__getitem__s�zFileWrapper.__getitem__cCs|S�Nr)r
rrr�__iter__!szFileWrapper.__iter__cCs|j�|j�}|r|St�r)r
rr�
StopIteration)r
rrrr�__next__$szFileWrapper.__next__N)r)�__name__�
__module__�__qualname__�__doc__rrrrrrrrrs

rcCs|�d�dvr	dSdS)zMReturn a guess for whether 'wsgi.url_scheme' should be 'http' or 'https'
    ZHTTPS)ZyesZon�1�https�http)�get)�environrrrr*srcCs�|dd}ddlm}|�d�r||d7}n)||d7}|ddkr3|dd	kr2|d
|d7}n|ddkrA|d
|d7}|||�d�pId
dd�7}|S)z@Return the application's base URI (no PATH_INFO or QUERY_STRING)�wsgi.url_schemez://r��quote�	HTTP_HOST�SERVER_NAMEr$�SERVER_PORT�443�:�80�SCRIPT_NAME�/�latin1)�encoding)�urllib.parser*r&)r'�urlr*rrrr2s
�rTcCspt|�}ddlm}||�dd�ddd�}|�d�s#||d	d
�7}n||7}|r6|�d�r6|d|d7}|S)
zBReturn the full request URI, optionally including the query stringrr)�	PATH_INFO�z/;=,r3)Zsafer4r1�NZQUERY_STRING�?)rr5r*r&)r'Z
include_queryr6r*�	path_inforrrrFs
rcCs�|�dd�}|s
dS|�d�}dd�|dd�D�|dd�<|d}|d=|�d	d�}t�|d|�}|�d�r?|dd�}|sJ|�d�sJ|d7}||d	<d�|�|d<|d
kr[d}|S)aZShift a name from PATH_INFO to SCRIPT_NAME, returning it

    If there are no remaining path segments in PATH_INFO, return None.
    Note: 'environ' is modified in-place; use a copy if you need to keep
    the original PATH_INFO or SCRIPT_NAME.

    Note: when PATH_INFO is just a '/', this returns '' and appends a trailing
    '/' to SCRIPT_NAME, even though empty path segments are normally ignored,
    and SCRIPT_NAME doesn't normally end in a '/'.  This is intentional
    behavior, to ensure that an application can tell the difference between
    '/x' and '/x/' when traversing to objects.
    r7r8Nr2cSsg|]
}|r|dkr|�qS)�.r)�.0�prrr�
<listcomp>esz#shift_path_info.<locals>.<listcomp>r9���r1r<)r&�split�	posixpath�normpath�endswith�join)r'r;�
path_parts�nameZscript_namerrrrSs$


rcCs|�dd�|�dd�|�d|d�|�dd�d|vr.d	|vr.|�dd
�|�d	d�|�dd
�|�dd�|�dd�|�dd�ddlm}m}|�d|��|�d|��|�dt|��|ddkrr|�dd�dS|ddkr�|�dd�dSdS)a:Update 'environ' with trivial defaults for testing purposes

    This adds various parameters required for WSGI, including HTTP_HOST,
    SERVER_NAME, SERVER_PORT, REQUEST_METHOD, SCRIPT_NAME, PATH_INFO,
    and all of the wsgi.* variables.  It only supplies default values,
    and does not replace any existing settings for these variables.

    This routine is intended to make it easier for unit tests of WSGI
    servers and applications to set up dummy environments.  It should *not*
    be used by actual WSGI servers or applications, since the data is fake!
    r,z	127.0.0.1ZSERVER_PROTOCOLzHTTP/1.0r+ZREQUEST_METHODZGETr1r7r8r2zwsgi.version)r9rz
wsgi.run_oncerzwsgi.multithreadzwsgi.multiprocess)�StringIO�BytesIOz
wsgi.inputzwsgi.errorsr(r%r-r0r$r.N)�
setdefault�iorHrIr)r'rHrIrrrr|s(
�r>zproxy-authenticateZupgradeztransfer-encodingz
keep-alive�teZtrailerszproxy-authorizationZ
connectioncCst|���S)z?Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header)�_hoppish�lower)Zheader_namerrr�
is_hop_by_hop�srO)T)r"rB�__all__rrrrrr�__contains__rMrOrrrr�<module>s

)(�__pycache__/simple_server.cpython-310.opt-2.pyc000064400000010731151543516720015307 0ustar00o

���h3�@s2	ddlmZmZddlZddlZddlmZddlm	Z	dZ
gd�Zde
Ze	�dej
��dZed	eZGd
d�de�ZGdd
�d
e�ZGdd�de�Zdd�Zeefdd�Zedkr�edde��'Zej��Zededdedd�ddlZe�d�e��Wd�dS1s�wYdSdS)�)�BaseHTTPRequestHandler�
HTTPServerN)�
SimpleHandler)�python_implementationz0.2)�
WSGIServer�WSGIRequestHandler�demo_app�make_server�WSGIServer/�/� c@seZdZeZdd�ZdS)�
ServerHandlerc	Cs<z|j�|j�dd�d|j�Wt�|�dSt�|�w)Nr�r)�request_handlerZlog_requestZstatus�splitZ
bytes_sentr�close��self�r�</opt/alt/python310/lib64/python3.10/wsgiref/simple_server.pyr s
�zServerHandler.closeN)�__name__�
__module__�__qualname__�software_versionZserver_softwarerrrrrr
sr
c@s2eZdZ	dZdd�Zdd�Zdd�Zdd	�ZdS)
rNcCs	t�|�|��dS�N)r�server_bind�
setup_environrrrrr0s
zWSGIServer.server_bindcCsFi}|_|j|d<d|d<t|j�|d<d|d<d|d<d|d<dS)	NZSERVER_NAMEzCGI/1.1ZGATEWAY_INTERFACEZSERVER_PORT��REMOTE_HOST�CONTENT_LENGTHZSCRIPT_NAME)�base_environZserver_name�strZserver_port)r�envrrrr5s

zWSGIServer.setup_environcCs|jSr��applicationrrrr�get_app?�zWSGIServer.get_appcCs
||_dSrr#)rr$rrr�set_appBs
zWSGIServer.set_app)rrrr$rrr%r'rrrrr*s
rc@s,eZdZdeZdd�Zdd�Zdd�ZdS)	rr
cCsL|jj��}|j|d<|j|d<|j|d<d|jvr$|j�dd�\}}n|jd}}tj	�
|d�|d<||d	<|��}||jd
krF||d<|jd
|d<|j
�d
�dur]|j
��|d<n|j
d
|d<|j
�d�}|rp||d<|j
��D].\}}|�dd���}|��}||vr�qud||vr�|d|d|7<qu||d|<qu|S)NZSERVER_PROTOCOLZSERVER_SOFTWAREZREQUEST_METHOD�?rrz
iso-8859-1Z	PATH_INFOZQUERY_STRINGrrZREMOTE_ADDRzcontent-typeZCONTENT_TYPEzcontent-lengthr�-�_ZHTTP_�,)�serverr �copy�request_version�server_version�command�pathr�urllib�parseZunquoteZaddress_stringZclient_addressZheaders�getZget_content_type�items�replace�upper�strip)rr"r1Zquery�hostZlength�k�vrrr�get_environKs6



zWSGIRequestHandler.get_environcCstjSr)�sys�stderrrrrr�
get_stderrpr&zWSGIRequestHandler.get_stderrcCs�	|j�d�|_t|j�dkrd|_d|_d|_|�d�dS|��s%dSt	|j|j
|��|��dd�}||_
|�|j���dS)Niiri�F)Zmultithread)Zrfile�readlineZraw_requestline�lenZrequestliner.r0Z
send_errorZ
parse_requestr
Zwfiler?r<r�runr,r%)rZhandlerrrr�handless 
�zWSGIRequestHandler.handleN)rrr�__version__r/r<r?rCrrrrrGs
%rcCsrddlm}|�}td|d�t|d�t|���}|D]\}}t|dt|�|d�q|ddg�|���d�gS)	Nr)�StringIOzHello world!)�file�=z200 OK)zContent-Typeztext/plain; charset=utf-8zutf-8)�iorE�print�sortedr5�repr�getvalue�encode)�environZstart_responserE�stdout�hr:r;rrrr�s
rcCs	|||f|�}|�|�|Sr)r')r9�portZappZserver_classZ
handler_classr,rrrr	�s
r	�__main__ri@zServing HTTP onrQrz...zhttp://localhost:8000/xyz?abc)Zhttp.serverrrr=Zurllib.parser2Zwsgiref.handlersr�platformrrD�__all__r/�versionr�sys_versionrr
rrrr	rZhttpdZsocketZgetsocknameZsarIZ
webbrowser�openZhandle_requestrrrr�<module>s4C
�	


"��__pycache__/handlers.cpython-310.pyc000064400000040036151543516720013271 0ustar00o

���h�T�@s�dZddlmZmZmZddlmZddlZddlZddl	Z	gd�Z
gd�Zgd�Zd	d
�Z
hd�jZdd
�Zdd�ZGdd�d�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZdS)z/Base classes for server/gateway implementations�)�FileWrapper�guess_scheme�
is_hop_by_hop)�Headers�N)�BaseHandler�
SimpleHandler�BaseCGIHandler�
CGIHandler�
IISCGIHandler�read_environ)ZMonZTueZWedZThuZFriZSatZSun)
NZJanZFebZMarZAprZMayZJunZJulZAugZSepZOctZNovZDecc
	Cs:t�|�\	}}}}}}}}}	dt||t|||||fS)Nz#%s, %02d %3s %4d %02d:%02d:%02d GMT)�time�gmtime�_weekdayname�
_monthname)
Z	timestampZyearZmonthZdayZhhZmmZssZwd�y�z�r�7/opt/alt/python310/lib64/python3.10/wsgiref/handlers.py�format_date_times�r>
ZCONTENT_TYPE�	PATH_INFOZCONTENT_LENGTHZREMOTE_USERZREQUEST_METHODZHTTPS�SCRIPT_NAMEZ	AUTH_TYPEZQUERY_STRINGZREMOTE_IDENTcCs6t|�p|�d�p|�d�p|�d�ot|dd��S)NZHTTP_ZSSL_Z	REDIRECT_�	)�_is_request�
startswith�_needs_transcode)�krrrrs�rcCs�t��}d}zd�d|�Wntyd}Ynwi}tj��D]S\}}t|�rptjdkrgtj�	dd��
�}|�d�rE|�d��d�}n+|�d	�rKn%|�d
�r]d|vr]|�d��d�}n|�|d��d�}n	|�||��d�}|||<q!|S)z'Read environment, fixing HTTP variables�surrogateescape�zutf-8�replaceZwin32�SERVER_SOFTWAREzmicrosoft-iis/�
iso-8859-1zapache/zsimplehttp/zpython/3)
�sys�getfilesystemencoding�encode�LookupError�os�environ�itemsr�platform�get�lowerr�decode)�encZescr'r�vZsoftwarerrrr"s0�

	
�
rc@s"eZdZdZdZdZdZdZdZdZ	dZ
e�Ze
ZeZdZdZdgZd	ZdZZdZdZd
Zdd�Zd
d�Zdd�Zdd�Zdd�Zdd�Zd;dd�Z dd�Z!dd�Z"dd�Z#dd �Z$d!d"�Z%d#d$�Z&d%d&�Z'd'd(�Z(d)d*�Z)d+d,�Z*d-d.�Z+d/d0�Z,d1d2�Z-d3d4�Z.d5d6�Z/d7d8�Z0d9d:�Z1dS)<rz+Manage the invocation of a WSGI application)rrTFz1.0Nz500 Internal Server Error)zContent-Typez
text/plains;A server error occurred.  Please contact the administrator.rc
Cshz|��||j|j�|_|��WdStttfy YdSz|��WYdS|�	��)zInvoke the applicationN)
�
setup_environr'�start_response�result�finish_response�ConnectionAbortedError�BrokenPipeError�ConnectionResetError�handle_error�close)�selfZapplicationrrr�run�szBaseHandler.runcCs�|j��}|_|��|��|d<|��|d<|j|d<|j|d<|��|d<|j	|d<|j
|d<|jdur<|j|d	<|jrK|j
rM|�d
|j
�dSdSdS)z&Set up the environment for one requestz
wsgi.inputzwsgi.errorszwsgi.versionz
wsgi.run_oncezwsgi.url_schemezwsgi.multithreadzwsgi.multiprocessNzwsgi.file_wrapperr )�
os_environ�copyr'�add_cgi_vars�	get_stdin�
get_stderr�wsgi_version�
wsgi_run_once�
get_scheme�wsgi_multithread�wsgi_multiprocess�wsgi_file_wrapper�
origin_server�server_software�
setdefault)r8�envrrrr/�s





�zBaseHandler.setup_environcCs^z|��r	|��s|jD]}|�|�q|��Wnt|jd�r(|j���|��dS)a>Send any iterable data, then close self and the iterable

        Subclasses intended for use in asynchronous servers will
        want to redefine this method, such that it sets up callbacks
        in the event loop to iterate over the data, and to call
        'self.close()' once the response is finished.
        r7N)�result_is_file�sendfiler1�write�finish_content�hasattrr7�r8�datarrrr2�s
�
zBaseHandler.finish_responsecCs
t|j�S)z Return the URL scheme being used)rr'�r8rrrrA�s
zBaseHandler.get_schemec
CsJzt|j�}Wn
tttfyYdSw|dkr#t|j�|jd<dSdS)z@Compute Content-Length or switch to chunked encoding if possibler�Content-LengthN)�lenr1�	TypeError�AttributeError�NotImplementedError�str�
bytes_sent�headers)r8Zblocksrrr�set_content_length�s��zBaseHandler.set_content_lengthcCsd|jvr|��dSdS)zqMake any necessary header changes or defaults

        Subclasses can extend this to add other defaults.
        rQN)rXrYrPrrr�cleanup_headers�s
�zBaseHandler.cleanup_headerscCs�|rz|jr|d|d��|d��Wd}nd}w|jdur#td��||_|�|�|_|�|d�}t|�dks<Jd��|dd	���sHJd
��|d	dksRJd��	|D]\}}|�|d�}|�|d�}t	|�rtJd|�d|�d���qU|j
S)z4'start_response()' callable as specified by PEP 3333rr�NzHeaders already set!ZStatus�z$Status must be at least 4 characters�z(Status message must begin w/3-digit code� z+Status message must have a space after codeTzHeader namezHeader valuezHop-by-hop header, 'z: z', not allowed)�headers_sent�with_tracebackrX�AssertionError�status�
headers_class�_convert_string_typerR�isdigitrrK)r8rbrX�exc_info�name�valrrrr0�s,�

�zBaseHandler.start_responsecCs$t|�tur|Std�|t|����)zConvert/check value type.z!{0} must be of type str (got {1}))�typerVra�format�repr)r8�value�titlerrrrd�s
�z BaseHandler._convert_string_typecCs�|jrC|��r=|�d|j|jf�d��d|jvr(|�dtt����d��|j	r?d|jvrA|�d|j	�d��dSdSdSdS|�d|j�d��dS)	z6Transmit version/status/date/server, via self._write()zHTTP/%s %s
r!ZDatez
Date: %s
ZServerzServer: %s
zStatus: %s
N)
rE�client_is_modern�_write�http_versionrbr$rXrr
rFrPrrr�
send_preambles
��zBaseHandler.send_preamblecCsdt|�tus
Jd��|jstd��|jst|�|_|��n	|jt|�7_|�|�|�	�dS)z+'write()' callable as specified by PEP 3333z)write() argument must be a bytes instancezwrite() before start_response()N)
ri�bytesrbrar_rRrW�send_headersro�_flushrNrrrrKs�


zBaseHandler.writecCsdS)aPlatform-specific file transmission

        Override this method in subclasses to support platform-specific
        file transmission.  It is only called if the application's
        return iterable ('self.result') is an instance of
        'self.wsgi_file_wrapper'.

        This method should return a true value if it was able to actually
        transmit the wrapped file-like object using a platform-specific
        approach.  It should return a false value if normal iteration
        should be used instead.  An exception can be raised to indicate
        that transmission was attempted, but failed.

        NOTE: this method should call 'self.send_headers()' if
        'self.headers_sent' is false and it is going to attempt direct
        transmission of the file.
        FrrPrrrrJ)szBaseHandler.sendfilecCs&|js|j�dd�|��dS	dS)z.Ensure headers and content have both been sentrQ�0N)r_rXrGrsrPrrrrL>szBaseHandler.finish_contentc	Cs�z5t|jd�r!|j��Wd|_|_|_|_d|_d|_dSWd|_|_|_|_d|_d|_dSd|_|_|_|_d|_d|_w)z�Close the iterable (if needed) and reset all instance vars

        Subclasses may want to also drop the client connection.
        r7NrF)rMr1r7rXrbr'rWr_rPrrrr7Hs��zBaseHandler.closecCs<|��d|_|jr|��r|��|�t|j��dSdS)z1Transmit headers to the client, via self._write()TN)rZr_rErnrqrorrrXrPrrrrsUs�zBaseHandler.send_headerscCs|j}|duot|j|�S)z@True if 'self.result' is an instance of 'self.wsgi_file_wrapper'N)rD�
isinstancer1)r8�wrapperrrrrI^szBaseHandler.result_is_filecCs|jd��dkS)z,True if client can accept status and headersZSERVER_PROTOCOLzHTTP/0.9)r'�upperrPrrrrndszBaseHandler.client_is_moderncCsLz"ddlm}|��}||d|d|d|j|�|��Wd}dSd}w)z�Log the 'exc_info' tuple in the server log

        Subclasses may override to retarget the output or change its format.
        r)�print_exceptionrr[N)�	tracebackryr>�traceback_limit�flush)r8rfry�stderrrrr�
log_exceptionis�
zBaseHandler.log_exceptioncCs6|�t���|js|�|j|j�|_|��dSdS)z>Log current error, and send error output to client if possibleN)	r~r"rfr_�error_outputr'r0r1r2rPrrrr6ys
�zBaseHandler.handle_errorcCs$||j|jdd�t���|jgS)aZWSGI mini-app to create error output

        By default, this just uses the 'error_status', 'error_headers',
        and 'error_body' attributes to generate an output page.  It can
        be overridden in a subclass to dynamically generate diagnostics,
        choose an appropriate message for the user's preferred language, etc.

        Note, however, that it's not recommended from a security perspective to
        spit out diagnostics to any old user; ideally, you should have to do
        something special to enable diagnostic output, which is why we don't
        include any here!
        N)�error_status�
error_headersr"rf�
error_body)r8r'r0rrrr�s
zBaseHandler.error_outputcC�t�)aOverride in subclass to buffer data for send to client

        It's okay if this method actually transmits the data; BaseHandler
        just separates write and flush operations for greater efficiency
        when the underlying system actually has such a distinction.
        �rUrNrrrro�szBaseHandler._writecCr�)z�Override in subclass to force sending of recent '_write()' calls

        It's okay if this method is a no-op (i.e., if '_write()' actually
        sends the data.
        r�rPrrrrt�szBaseHandler._flushcCr�)z4Override in subclass to return suitable 'wsgi.input'r�rPrrrr=��zBaseHandler.get_stdincCr�)z5Override in subclass to return suitable 'wsgi.errors'r�rPrrrr>�r�zBaseHandler.get_stderrcCr�)z>Override in subclass to insert CGI variables in 'self.environ'r�rPrrrr<�r�zBaseHandler.add_cgi_vars�N)2�__name__�
__module__�__qualname__�__doc__r?rBrCr@rErprFrr:rrDrrcr{r�r�r�rbr1r_rXrWr9r/r2rArYrZr0rdrqrKrJrLr7rsrIrnr~r6rrortr=r>r<rrrrr^sX


		rc@sDeZdZdZ	ddd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dS)raqHandler that's just initialized with streams, environment, etc.

    This handler subclass is intended for synchronous HTTP/1.0 origin servers,
    and handles sending the entire response output, given the correct inputs.

    Usage::

        handler = SimpleHandler(
            inp,out,err,env, multithread=False, multiprocess=True
        )
        handler.run(app)TFcCs(||_||_||_||_||_||_dSr�)�stdin�stdoutr}�base_envrBrC)r8r�r�r}r'�multithread�multiprocessrrr�__init__�s
zSimpleHandler.__init__cC�|jSr�)r�rPrrrr=��zSimpleHandler.get_stdincCr�r�)r}rPrrrr>�r�zSimpleHandler.get_stderrcCs|j�|j�dSr�)r'�updater�rPrrrr<�szSimpleHandler.add_cgi_varscCs^|j�|�}|dus|t|�krdSddlm}|dt�	||d�}|s(dS|j�|�}q)Nr)�warnz9SimpleHandler.stdout.write() should not do partial writes)r�rKrR�warningsr��DeprecationWarning)r8rOr1r�rrrro�s��zSimpleHandler._writecCs|j��|jj|_dSr�)r�r|rtrPrrrrt�s
zSimpleHandler._flushN)TF)
r�r�r�r�r�r=r>r<rortrrrrr�s
�

rc@seZdZdZdZdS)r	a�CGI-like systems using input/output/error streams and environ mapping

    Usage::

        handler = BaseCGIHandler(inp,out,err,env)
        handler.run(app)

    This handler class is useful for gateway protocols like ReadyExec and
    FastCGI, that have usable input/output/error streams and an environment
    mapping.  It's also the base class for CGIHandler, which just uses
    sys.stdin, os.environ, and so on.

    The constructor also takes keyword arguments 'multithread' and
    'multiprocess' (defaulting to 'True' and 'False' respectively) to control
    the configuration sent to the application.  It sets 'origin_server' to
    False (to enable CGI-like output), and assumes that 'wsgi.run_once' is
    False.
    FN)r�r�r�r�rErrrrr	�sr	c@� eZdZdZdZiZdd�ZdS)r
a�CGI-based invocation via sys.stdin/stdout/stderr and os.environ

    Usage::

        CGIHandler().run(app)

    The difference between this class and BaseCGIHandler is that it always
    uses 'wsgi.run_once' of 'True', 'wsgi.multithread' of 'False', and
    'wsgi.multiprocess' of 'True'.  It does not take any initialization
    parameters, but always uses 'sys.stdin', 'os.environ', and friends.

    If you need to override any of these parameters, use BaseCGIHandler
    instead.
    Tc	Cs(tj|tjjtjjtjt�ddd�dS)NFT�r�r�)r	r�r"r��bufferr�r}rrPrrrr�s
�zCGIHandler.__init__N�r�r�r�r�r@r:r�rrrrr
�s
r
c@r�)raCGI-based invocation with workaround for IIS path bug

    This handler should be used in preference to CGIHandler when deploying on
    Microsoft IIS without having set the config allowPathInfo option (IIS>=7)
    or metabase allowPathInfoForScriptMappings (IIS<7).
    Tc	Csjt�}|�dd�}|�dd�}|d�|d�r"|t|�d�|d<tj|tjjtj	jtj
|ddd�dS)Nrrr�/FTr�)rr*rrRr	r�r"r�r�r�r})r8r'�pathZscriptrrrr�2s
�zIISCGIHandler.__init__Nr�rrrrrs
r)r��utilrrrrXrr"r&r
�__all__rrr�__contains__rrrrrr	r
rrrrr�<module>s(�<V2__pycache__/handlers.cpython-310.opt-2.pyc000064400000024655151543516720014242 0ustar00o

���h�T�@s�	ddlmZmZmZddlmZddlZddlZddlZgd�Z	gd�Z
gd�Zdd	�Zhd
�j
Zdd�Zd
d�ZGdd�d�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZdS)�)�FileWrapper�guess_scheme�
is_hop_by_hop)�Headers�N)�BaseHandler�
SimpleHandler�BaseCGIHandler�
CGIHandler�
IISCGIHandler�read_environ)ZMonZTueZWedZThuZFriZSatZSun)
NZJanZFebZMarZAprZMayZJunZJulZAugZSepZOctZNovZDecc
	Cs:t�|�\	}}}}}}}}}	dt||t|||||fS)Nz#%s, %02d %3s %4d %02d:%02d:%02d GMT)�time�gmtime�_weekdayname�
_monthname)
Z	timestampZyearZmonthZdayZhhZmmZssZwd�y�z�r�7/opt/alt/python310/lib64/python3.10/wsgiref/handlers.py�format_date_times�r>
ZCONTENT_TYPE�	PATH_INFOZCONTENT_LENGTHZREMOTE_USERZREQUEST_METHODZHTTPS�SCRIPT_NAMEZ	AUTH_TYPEZQUERY_STRINGZREMOTE_IDENTcCs6t|�p|�d�p|�d�p|�d�ot|dd��S)NZHTTP_ZSSL_Z	REDIRECT_�	)�_is_request�
startswith�_needs_transcode)�krrrrs�rcCs�	t��}d}zd�d|�Wntyd}Ynwi}tj��D]S\}}t|�rqtjdkrhtj�	dd��
�}|�d�rF|�d��d�}n+|�d	�rLn%|�d
�r^d|vr^|�d��d�}n|�|d��d�}n	|�||��d�}|||<q"|S)N�surrogateescape�zutf-8�replaceZwin32�SERVER_SOFTWAREzmicrosoft-iis/�
iso-8859-1zapache/zsimplehttp/zpython/3)
�sys�getfilesystemencoding�encode�LookupError�os�environ�itemsr�platform�get�lowerr�decode)�encZescr'r�vZsoftwarerrrr"s2�

	
�
rc@s eZdZ	dZdZdZdZdZdZdZ	e
�ZeZ
eZdZdZdgZdZdZZdZdZd	Zd
d�Zdd
�Zdd�Zdd�Zdd�Zdd�Zd:dd�Zdd�Z dd�Z!dd�Z"dd�Z#d d!�Z$d"d#�Z%d$d%�Z&d&d'�Z'd(d)�Z(d*d+�Z)d,d-�Z*d.d/�Z+d0d1�Z,d2d3�Z-d4d5�Z.d6d7�Z/d8d9�Z0dS);r)rrTFz1.0Nz500 Internal Server Error)zContent-Typez
text/plains;A server error occurred.  Please contact the administrator.rc
Csj	z|��||j|j�|_|��WdStttfy!YdSz|��WYdS|�	���N)
�
setup_environr'�start_response�result�finish_response�ConnectionAbortedError�BrokenPipeError�ConnectionResetError�handle_error�close)�selfZapplicationrrr�run�szBaseHandler.runcCs�	|j��}|_|��|��|d<|��|d<|j|d<|j|d<|��|d<|j	|d<|j
|d<|jdur=|j|d<|jrL|j
rN|�d	|j
�dSdSdS)
Nz
wsgi.inputzwsgi.errorszwsgi.versionz
wsgi.run_oncezwsgi.url_schemezwsgi.multithreadzwsgi.multiprocesszwsgi.file_wrapperr )�
os_environ�copyr'�add_cgi_vars�	get_stdin�
get_stderr�wsgi_version�
wsgi_run_once�
get_scheme�wsgi_multithread�wsgi_multiprocess�wsgi_file_wrapper�
origin_server�server_software�
setdefault)r9�envrrrr0�s





�zBaseHandler.setup_environcCs`	z|��r
|��s|jD]}|�|�q
|��Wnt|jd�r)|j���|��dS)Nr8)�result_is_file�sendfiler2�write�finish_content�hasattrr8�r9�datarrrr3�s
�
zBaseHandler.finish_responsecCs	t|j�Sr/)rr'�r9rrrrB�s
zBaseHandler.get_schemec
CsL	zt|j�}Wn
tttfyYdSw|dkr$t|j�|jd<dSdS)Nr�Content-Length)�lenr2�	TypeError�AttributeError�NotImplementedError�str�
bytes_sent�headers)r9Zblocksrrr�set_content_length�s��zBaseHandler.set_content_lengthcCs	d|jvr|��dSdS)NrR)rYrZrQrrr�cleanup_headers�s
�zBaseHandler.cleanup_headerscCsn	|rz|jr|d|d��|d��Wd}nd}w|jdur$td��||_|�|�|_|�|d�}	|jS)Nrr�zHeaders already set!ZStatus)�headers_sent�with_tracebackrY�AssertionError�status�
headers_class�_convert_string_typerL)r9r`rY�exc_info�name�valrrrr1�s�
zBaseHandler.start_responsecCs&	t|�tur	|Std�|t|����)Nz!{0} must be of type str (got {1}))�typerWr_�format�repr)r9�value�titlerrrrb�s�z BaseHandler._convert_string_typecCs�	|jrD|��r>|�d|j|jf�d��d|jvr)|�dtt����d��|j	r@d|jvrB|�d|j	�d��dSdSdSdS|�d|j�d��dS)NzHTTP/%s %s
r!ZDatez
Date: %s
ZServerzServer: %s
zStatus: %s
)
rF�client_is_modern�_write�http_versionr`r$rYrr
rGrQrrr�
send_preambles
��zBaseHandler.send_preamblecCsR	|jstd��|jst|�|_|��n	|jt|�7_|�|�|��dS)Nzwrite() before start_response())r`r_r]rSrX�send_headersrl�_flushrOrrrrLs


zBaseHandler.writecCs	dS)NFrrQrrrrK)szBaseHandler.sendfilecCs(	|js|j�dd�|��dS	dS)NrR�0)r]rYrHrorQrrrrM>s
zBaseHandler.finish_contentc	Cs�	z5t|jd�r"|j��Wd|_|_|_|_d|_d|_dSWd|_|_|_|_d|_d|_dSd|_|_|_|_d|_d|_w)Nr8rF)rNr2r8rYr`r'rXr]rQrrrr8Hs��zBaseHandler.closecCs>	|��d|_|jr|��r|��|�t|j��dSdS)NT)r[r]rFrkrnrl�bytesrYrQrrrroUs�zBaseHandler.send_headerscCs	|j}|duo
t|j|�Sr/)rE�
isinstancer2)r9�wrapperrrrrJ^szBaseHandler.result_is_filecCs	|jd��dkS)NZSERVER_PROTOCOLzHTTP/0.9)r'�upperrQrrrrkdszBaseHandler.client_is_moderncCsN	z"ddlm}|��}||d|d|d|j|�|��Wd}dSd}w)Nr)�print_exceptionrr\)�	tracebackrvr?�traceback_limit�flush)r9rcrv�stderrrrr�
log_exceptionis�
zBaseHandler.log_exceptioncCs8	|�t���|js|�|j|j�|_|��dSdSr/)	r{r"rcr]�error_outputr'r1r2r3rQrrrr7ys�zBaseHandler.handle_errorcCs&	||j|jdd�t���|jgSr/)�error_status�
error_headersr"rc�
error_body)r9r'r1rrrr|�szBaseHandler.error_outputcC�	t�r/�rVrOrrrrl�szBaseHandler._writecCr�r/r�rQrrrrp�szBaseHandler._flushcCr�r/r�rQrrrr>��zBaseHandler.get_stdincCr�r/r�rQrrrr?�r�zBaseHandler.get_stderrcCr�r/r�rQrrrr=�r�zBaseHandler.add_cgi_varsr/)1�__name__�
__module__�__qualname__r@rCrDrArFrmrGrr;rrErrarxr}r~rr`r2r]rYrXr:r0r3rBrZr[r1rbrnrLrKrMr8rorJrkr{r7r|rlrpr>r?r=rrrrr^sX


		rc@sBeZdZ		ddd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�ZdS)rTFcCs(||_||_||_||_||_||_dSr/)�stdin�stdoutrz�base_envrCrD)r9r�r�rzr'�multithread�multiprocessrrr�__init__�s
zSimpleHandler.__init__cC�|jSr/)r�rQrrrr>��zSimpleHandler.get_stdincCr�r/)rzrQrrrr?�r�zSimpleHandler.get_stderrcCs|j�|j�dSr/)r'�updater�rQrrrr=�szSimpleHandler.add_cgi_varscCs^|j�|�}|dus|t|�krdSddlm}|dt�	||d�}|s(dS|j�|�}q)Nr)�warnz9SimpleHandler.stdout.write() should not do partial writes)r�rLrS�warningsr��DeprecationWarning)r9rPr2r�rrrrl�s��zSimpleHandler._writecCs|j��|jj|_dSr/)r�ryrprQrrrrp�s
zSimpleHandler._flushN)TF)	r�r�r�r�r>r?r=rlrprrrrr�s
�

rc@seZdZ	dZdS)r	FN)r�r�r�rFrrrrr	�sr	c@�eZdZ	dZiZdd�ZdS)r
Tc	Cs(tj|tjjtjjtjt�ddd�dS)NFT�r�r�)r	r�r"r��bufferr�rzrrQrrrr�s
�zCGIHandler.__init__N�r�r�r�rAr;r�rrrrr
�s
r
c@r�)rTc	Csjt�}|�dd�}|�dd�}|d�|d�r"|t|�d�|d<tj|tjjtj	jtj
|ddd�dS)Nrrr�/FTr�)rr*rrSr	r�r"r�r�r�rz)r9r'�pathZscriptrrrr�2s
�zIISCGIHandler.__init__Nr�rrrrrs
r)�utilrrrrYrr"r&r
�__all__rrr�__contains__rrrrrr	r
rrrrr�<module>s(�<V2__pycache__/simple_server.cpython-310.opt-1.pyc000064400000012312151543516720015303 0ustar00o

���h3�@s4dZddlmZmZddlZddlZddlmZddl	m
Z
dZgd�ZdeZ
e
�d	ej��dZe
d
eZGdd�de�ZGd
d�de�ZGdd�de�Zdd�Zeefdd�Zedkr�edde��'Zej��Zededdedd�ddlZe�d�e��Wd�dS1s�wYdSdS)a!BaseHTTPServer that implements the Python WSGI protocol (PEP 3333)

This is both an example of how WSGI can be implemented, and a basis for running
simple web applications on a local machine, such as might be done when testing
or debugging an application.  It has not been reviewed for security issues,
however, and we strongly recommend that you use a "real" web server for
production use.

For example usage, see the 'if __name__=="__main__"' block at the end of the
module.  See also the BaseHTTPServer module docs for other API information.
�)�BaseHTTPRequestHandler�
HTTPServerN)�
SimpleHandler)�python_implementationz0.2)�
WSGIServer�WSGIRequestHandler�demo_app�make_server�WSGIServer/�/� c@seZdZeZdd�ZdS)�
ServerHandlerc	Cs<z|j�|j�dd�d|j�Wt�|�dSt�|�w)Nr�r)�request_handlerZlog_requestZstatus�splitZ
bytes_sentr�close��self�r�</opt/alt/python310/lib64/python3.10/wsgiref/simple_server.pyr s
�zServerHandler.closeN)�__name__�
__module__�__qualname__�software_versionZserver_softwarerrrrrr
sr
c@s4eZdZdZdZdd�Zdd�Zdd�Zd	d
�ZdS)rz7BaseHTTPServer that implements the Python WSGI protocolNcCst�|�|��dS)z.Override server_bind to store the server name.N)r�server_bind�
setup_environrrrrr0s
zWSGIServer.server_bindcCsFi}|_|j|d<d|d<t|j�|d<d|d<d|d<d|d<dS)	NZSERVER_NAMEzCGI/1.1ZGATEWAY_INTERFACEZSERVER_PORT��REMOTE_HOST�CONTENT_LENGTHZSCRIPT_NAME)�base_environZserver_name�strZserver_port)r�envrrrr5s

zWSGIServer.setup_environcCs|jS�N��applicationrrrr�get_app?�zWSGIServer.get_appcCs
||_dSr"r#)rr$rrr�set_appBs
zWSGIServer.set_app)	rrr�__doc__r$rrr%r'rrrrr*s
rc@s,eZdZdeZdd�Zdd�Zdd�ZdS)	rr
cCsL|jj��}|j|d<|j|d<|j|d<d|jvr$|j�dd�\}}n|jd}}tj	�
|d�|d<||d	<|��}||jd
krF||d<|jd
|d<|j
�d
�dur]|j
��|d<n|j
d
|d<|j
�d�}|rp||d<|j
��D].\}}|�dd���}|��}||vr�qud||vr�|d|d|7<qu||d|<qu|S)NZSERVER_PROTOCOLZSERVER_SOFTWAREZREQUEST_METHOD�?rrz
iso-8859-1Z	PATH_INFOZQUERY_STRINGrrZREMOTE_ADDRzcontent-typeZCONTENT_TYPEzcontent-lengthr�-�_ZHTTP_�,)�serverr�copy�request_version�server_version�command�pathr�urllib�parseZunquoteZaddress_stringZclient_addressZheaders�getZget_content_type�items�replace�upper�strip)rr!r2Zquery�hostZlength�k�vrrr�get_environKs6



zWSGIRequestHandler.get_environcCstjSr")�sys�stderrrrrr�
get_stderrpr&zWSGIRequestHandler.get_stderrcCs�|j�d�|_t|j�dkrd|_d|_d|_|�d�dS|��s$dSt	|j|j
|��|��dd�}||_
|�|j���dS)zHandle a single HTTP requestiiri�NF)Zmultithread)Zrfile�readlineZraw_requestline�lenZrequestliner/r1Z
send_errorZ
parse_requestr
Zwfiler@r=r�runr-r%)rZhandlerrrr�handless
�zWSGIRequestHandler.handleN)rrr�__version__r0r=r@rDrrrrrGs
%rcCsrddlm}|�}td|d�t|d�t|���}|D]\}}t|dt|�|d�q|ddg�|���d�gS)	Nr)�StringIOzHello world!)�file�=z200 OK)zContent-Typeztext/plain; charset=utf-8zutf-8)�iorF�print�sortedr6�repr�getvalue�encode)�environZstart_responserF�stdout�hr;r<rrrr�s
rcCs|||f|�}|�|�|S)zACreate a new WSGI server listening on `host` and `port` for `app`)r')r:�portZappZserver_classZ
handler_classr-rrrr	�s
r	�__main__ri@zServing HTTP onrRrz...zhttp://localhost:8000/xyz?abc) r(Zhttp.serverrrr>Zurllib.parser3Zwsgiref.handlersr�platformrrE�__all__r0�versionr�sys_versionrr
rrrr	rZhttpdZsocketZgetsocknameZsarJZ
webbrowser�openZhandle_requestrrrr�<module>s4C
�	


"��__pycache__/headers.cpython-310.pyc000064400000017063151543516720013110 0ustar00o

���hn�@s2dZddlZe�d�Zd	dd�ZGdd�d�ZdS)
z�Manage HTTP Response Headers

Much of this module is red-handedly pilfered from email.message in the stdlib,
so portions are Copyright (C) 2001,2002 Python Software Foundation, and were
written by Barry Warsaw.
�Nz[ \(\)<>@,;:\\"/\[\]\?=]�cCsR|dur't|�dkr'|st�|�r!|�dd��dd�}d||fSd||fS|S)	z~Convenience function to format and return a key=value pair.

    This will quote the value if needed or if quote is true.
    Nr�\z\\�"z\"z%s="%s"z%s=%s)�len�	tspecials�search�replace)Zparam�valueZquote�r
�6/opt/alt/python310/lib64/python3.10/wsgiref/headers.py�_formatparam
src@s�eZdZdZd%dd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zd%dd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�ZdS)&�Headersz,Manage a collection of HTTP response headersNcCsR|dur|ng}t|�turtd��||_	|D]\}}|�|�|�|�qdS)Nz+Headers must be a list of name/value tuples)�type�list�	TypeError�_headers�_convert_string_type)�selfZheaders�k�vr
r
r�__init__s
�zHeaders.__init__cCs"t|�tur|Std�t|����)zConvert/check value type.z1Header names/values must be of type str (got {0}))r�str�AssertionError�format�repr)rr	r
r
rr)s

�zHeaders._convert_string_typecCs
t|j�S)z9Return the total number of headers, including duplicates.)rr�rr
r
r�__len__0s
zHeaders.__len__cCs&||=|j�|�|�|�|�f�dS)zSet the value of a header.N)r�appendr)r�name�valr
r
r�__setitem__4s�zHeaders.__setitem__cs0|�������fdd�|jD�|jdd�<dS)zyDelete all occurrences of a header, if present.

        Does *not* raise an exception if the header is missing.
        cs g|]}|d���kr|�qS)r��lower��.0Zkv�rr
r�
<listcomp>@s z'Headers.__delitem__.<locals>.<listcomp>N�rr"r�rrr
r%r�__delitem__:s"zHeaders.__delitem__cCs
|�|�S)aHGet the first header value for 'name'

        Return None if the header is missing instead of raising an exception.

        Note that if the header appeared multiple times, the first exactly which
        occurrence gets returned is undefined.  Use getall() to get all
        the values matching a header field name.
        ��getr(r
r
r�__getitem__Bs
	zHeaders.__getitem__cCs|�|�duS)z/Return true if the message contains the header.Nr*r(r
r
r�__contains__MszHeaders.__contains__cs"|�������fdd�|jD�S)aqReturn a list of all the values for the named field.

        These will be sorted in the order they appeared in the original header
        list or were added to this instance, and may contain duplicates.  Any
        fields deleted and re-inserted are always appended to the header list.
        If no fields exist with the given name, returns an empty list.
        cs$g|]}|d���kr|d�qS)rrr!r#r%r
rr&[s$z#Headers.get_all.<locals>.<listcomp>r'r(r
r%r�get_allRszHeaders.get_allcCs6|�|���}|jD]\}}|��|kr|Sq
|S)z:Get the first header value for 'name', or return 'default'r')rr�defaultrrr
r
rr+^s�zHeaders.getcC�dd�|jD�S)a*Return a list of all the header field names.

        These will be sorted in the order they appeared in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        cSsg|]\}}|�qSr
r
�r$rrr
r
rr&o�z Headers.keys.<locals>.<listcomp>�rrr
r
r�keysg�zHeaders.keyscCr0)a!Return a list of all header values.

        These will be sorted in the order they appeared in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        cSsg|]\}}|�qSr
r
r1r
r
rr&yr2z"Headers.values.<locals>.<listcomp>r3rr
r
r�valuesqr5zHeaders.valuescCs|jdd�S)aGet all the header fields and values.

        These will be sorted in the order they were in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        Nr3rr
r
r�items{sz
Headers.itemscCsd|jj|jfS)Nz%s(%r))�	__class__�__name__rrr
r
r�__repr__�szHeaders.__repr__cCsd�dd�|jD�ddg�S)zkstr() returns the formatted headers, complete with end line,
        suitable for direct HTTP transmission.z
cSsg|]}d|�qS)z%s: %sr
r#r
r
rr&�r2z#Headers.__str__.<locals>.<listcomp>�)�joinrrr
r
r�__str__�szHeaders.__str__cCst|��d�S)Nz
iso-8859-1)r�encoderr
r
r�	__bytes__�szHeaders.__bytes__cCs6|�|�}|dur|j�|�|�|�|�f�|S|S)z�Return first matching header value for 'name', or 'value'

        If there is no header named 'name', add a new header with name 'name'
        and value 'value'.N)r+rrr)rrr	�resultr
r
r�
setdefault�s
�zHeaders.setdefaultcKs�g}|dur|�|�}|�|�|��D](\}}|�|�}|dur+|�|�dd��q|�|�}|�t|�dd�|��q|j�|�|�d�|�f�dS)afExtended header setting.

        _name is the header field to add.  keyword arguments can be used to set
        additional parameters for the header field, with underscores converted
        to dashes.  Normally the parameter will be added as key="value" unless
        value is None, in which case only the key will be added.

        Example:

        h.add_header('content-disposition', 'attachment', filename='bud.gif')

        Note that unlike the corresponding 'email.message' method, this does
        *not* handle '(charset, language, value)' tuples: all values must be
        strings or None.
        N�_�-z; )rrr7rrrr<)r�_nameZ_valueZ_params�partsrrr
r
r�
add_header�s



 zHeaders.add_header)N)r9�
__module__�__qualname__�__doc__rrrr r)r,r-r.r+r4r6r7r:r=r?rArFr
r
r
rr
s&


	



r
)Nr)rI�re�compilerrr
r
r
r
r�<module>s
	

__pycache__/util.cpython-310.opt-2.pyc000064400000007455151543516720013416 0ustar00o

���h��@s`	ddlZgd�ZGdd�d�Zdd�Zdd�Zdd
d�Zdd
�Zdd�Zhd�jZ	dd�Z
dS)�N)�FileWrapper�guess_scheme�application_uri�request_uri�shift_path_info�setup_testing_defaultsc@s0eZdZ	ddd�Zdd�Zdd�Zdd	�Zd
S)r� cCs&||_||_t|d�r|j|_dSdS)N�close)�filelike�blksize�hasattrr	)�selfr
r�r�3/opt/alt/python310/lib64/python3.10/wsgiref/util.py�__init__s

�zFileWrapper.__init__cCs2ddl}|jdtdd�|j�|j�}|r|St�)NrzXFileWrapper's __getitem__ method ignores 'key' parameter. Use iterator protocol instead.�)�
stacklevel)�warnings�warn�DeprecationWarningr
�readr�
IndexError)r
�keyr�datarrr�__getitem__s�zFileWrapper.__getitem__cCs|S�Nr)r
rrr�__iter__!szFileWrapper.__iter__cCs|j�|j�}|r|St�r)r
rr�
StopIteration)r
rrrr�__next__$szFileWrapper.__next__N)r)�__name__�
__module__�__qualname__rrrrrrrrrs

rcCs	|�d�dvr
dSdS)NZHTTPS)ZyesZon�1�https�http)�get)�environrrrr*srcCs�	|dd}ddlm}|�d�r||d7}n)||d7}|ddkr4|dd	kr3|d
|d7}n|ddkrB|d
|d7}|||�d�pJd
dd�7}|S)N�wsgi.url_schemez://r��quote�	HTTP_HOST�SERVER_NAMEr#�SERVER_PORT�443�:�80�SCRIPT_NAME�/�latin1)�encoding)�urllib.parser)r%)r&�urlr)rrrr2s
�rTcCsr	t|�}ddlm}||�dd�ddd�}|�d�s$||d	d�7}n||7}|r7|�d
�r7|d|d
7}|S)Nrr(�	PATH_INFO�z/;=,r2)Zsafer3r0�ZQUERY_STRING�?)rr4r)r%)r&Z
include_queryr5r)�	path_inforrrrFs
rcCs�	|�dd�}|sdS|�d�}dd�|dd�D�|dd�<|d}|d=|�dd�}t�|d|�}|�d�r@|dd�}|sK|�d�sK|d7}||d<d�|�|d<|d	kr\d}|S)
Nr6r7r1cSsg|]
}|r|dkr|�qS)�.r)�.0�prrr�
<listcomp>esz#shift_path_info.<locals>.<listcomp>r8���r0r;)r%�split�	posixpath�normpath�endswith�join)r&r:�
path_parts�nameZscript_namerrrrSs&

rcCs	|�dd�|�dd�|�d|d�|�dd�d|vr/d	|vr/|�dd
�|�d	d�|�dd
�|�dd�|�dd�|�dd�ddlm}m}|�d|��|�d|��|�dt|��|ddkrs|�dd�dS|ddkr�|�dd�dSdS)Nr+z	127.0.0.1ZSERVER_PROTOCOLzHTTP/1.0r*ZREQUEST_METHODZGETr0r6r7r1zwsgi.version)r8rz
wsgi.run_oncerzwsgi.multithreadzwsgi.multiprocess)�StringIO�BytesIOz
wsgi.inputzwsgi.errorsr'r$r,r/r#r-)�
setdefault�iorGrHr)r&rGrHrrrr|s*�r>zproxy-authenticateZupgradeztransfer-encodingz
keep-alive�teZtrailerszproxy-authorizationZ
connectioncCs	t|���Sr)�_hoppish�lower)Zheader_namerrr�
is_hop_by_hop�srN)T)rA�__all__rrrrrr�__contains__rLrNrrrr�<module>s

)(�__pycache__/handlers.cpython-310.opt-1.pyc000064400000037126151543516720014236 0ustar00o

���h�T�@s�dZddlmZmZmZddlmZddlZddlZddl	Z	gd�Z
gd�Zgd�Zd	d
�Z
hd�jZdd
�Zdd�ZGdd�d�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZdS)z/Base classes for server/gateway implementations�)�FileWrapper�guess_scheme�
is_hop_by_hop)�Headers�N)�BaseHandler�
SimpleHandler�BaseCGIHandler�
CGIHandler�
IISCGIHandler�read_environ)ZMonZTueZWedZThuZFriZSatZSun)
NZJanZFebZMarZAprZMayZJunZJulZAugZSepZOctZNovZDecc
	Cs:t�|�\	}}}}}}}}}	dt||t|||||fS)Nz#%s, %02d %3s %4d %02d:%02d:%02d GMT)�time�gmtime�_weekdayname�
_monthname)
Z	timestampZyearZmonthZdayZhhZmmZssZwd�y�z�r�7/opt/alt/python310/lib64/python3.10/wsgiref/handlers.py�format_date_times�r>
ZCONTENT_TYPE�	PATH_INFOZCONTENT_LENGTHZREMOTE_USERZREQUEST_METHODZHTTPS�SCRIPT_NAMEZ	AUTH_TYPEZQUERY_STRINGZREMOTE_IDENTcCs6t|�p|�d�p|�d�p|�d�ot|dd��S)NZHTTP_ZSSL_Z	REDIRECT_�	)�_is_request�
startswith�_needs_transcode)�krrrrs�rcCs�t��}d}zd�d|�Wntyd}Ynwi}tj��D]S\}}t|�rptjdkrgtj�	dd��
�}|�d�rE|�d��d�}n+|�d	�rKn%|�d
�r]d|vr]|�d��d�}n|�|d��d�}n	|�||��d�}|||<q!|S)z'Read environment, fixing HTTP variables�surrogateescape�zutf-8�replaceZwin32�SERVER_SOFTWAREzmicrosoft-iis/�
iso-8859-1zapache/zsimplehttp/zpython/3)
�sys�getfilesystemencoding�encode�LookupError�os�environ�itemsr�platform�get�lowerr�decode)�encZescr'r�vZsoftwarerrrr"s0�

	
�
rc@s"eZdZdZdZdZdZdZdZdZ	dZ
e�Ze
ZeZdZdZdgZd	ZdZZdZdZd
Zdd�Zd
d�Zdd�Zdd�Zdd�Zdd�Zd;dd�Z dd�Z!dd�Z"dd�Z#dd �Z$d!d"�Z%d#d$�Z&d%d&�Z'd'd(�Z(d)d*�Z)d+d,�Z*d-d.�Z+d/d0�Z,d1d2�Z-d3d4�Z.d5d6�Z/d7d8�Z0d9d:�Z1dS)<rz+Manage the invocation of a WSGI application)rrTFz1.0Nz500 Internal Server Error)zContent-Typez
text/plains;A server error occurred.  Please contact the administrator.rc
Cshz|��||j|j�|_|��WdStttfy YdSz|��WYdS|�	��)zInvoke the applicationN)
�
setup_environr'�start_response�result�finish_response�ConnectionAbortedError�BrokenPipeError�ConnectionResetError�handle_error�close)�selfZapplicationrrr�run�szBaseHandler.runcCs�|j��}|_|��|��|d<|��|d<|j|d<|j|d<|��|d<|j	|d<|j
|d<|jdur<|j|d	<|jrK|j
rM|�d
|j
�dSdSdS)z&Set up the environment for one requestz
wsgi.inputzwsgi.errorszwsgi.versionz
wsgi.run_oncezwsgi.url_schemezwsgi.multithreadzwsgi.multiprocessNzwsgi.file_wrapperr )�
os_environ�copyr'�add_cgi_vars�	get_stdin�
get_stderr�wsgi_version�
wsgi_run_once�
get_scheme�wsgi_multithread�wsgi_multiprocess�wsgi_file_wrapper�
origin_server�server_software�
setdefault)r8�envrrrr/�s





�zBaseHandler.setup_environcCs^z|��r	|��s|jD]}|�|�q|��Wnt|jd�r(|j���|��dS)a>Send any iterable data, then close self and the iterable

        Subclasses intended for use in asynchronous servers will
        want to redefine this method, such that it sets up callbacks
        in the event loop to iterate over the data, and to call
        'self.close()' once the response is finished.
        r7N)�result_is_file�sendfiler1�write�finish_content�hasattrr7�r8�datarrrr2�s
�
zBaseHandler.finish_responsecCs
t|j�S)z Return the URL scheme being used)rr'�r8rrrrA�s
zBaseHandler.get_schemec
CsJzt|j�}Wn
tttfyYdSw|dkr#t|j�|jd<dSdS)z@Compute Content-Length or switch to chunked encoding if possibler�Content-LengthN)�lenr1�	TypeError�AttributeError�NotImplementedError�str�
bytes_sent�headers)r8Zblocksrrr�set_content_length�s��zBaseHandler.set_content_lengthcCsd|jvr|��dSdS)zqMake any necessary header changes or defaults

        Subclasses can extend this to add other defaults.
        rQN)rXrYrPrrr�cleanup_headers�s
�zBaseHandler.cleanup_headerscCsl|rz|jr|d|d��|d��Wd}nd}w|jdur#td��||_|�|�|_|�|d�}	|jS)z4'start_response()' callable as specified by PEP 3333rr�NzHeaders already set!ZStatus)�headers_sent�with_tracebackrX�AssertionError�status�
headers_class�_convert_string_typerK)r8r_rX�exc_info�name�valrrrr0�s�
zBaseHandler.start_responsecCs$t|�tur|Std�|t|����)zConvert/check value type.z!{0} must be of type str (got {1}))�typerVr^�format�repr)r8�value�titlerrrra�s
�z BaseHandler._convert_string_typecCs�|jrC|��r=|�d|j|jf�d��d|jvr(|�dtt����d��|j	r?d|jvrA|�d|j	�d��dSdSdSdS|�d|j�d��dS)	z6Transmit version/status/date/server, via self._write()zHTTP/%s %s
r!ZDatez
Date: %s
ZServerzServer: %s
zStatus: %s
N)
rE�client_is_modern�_write�http_versionr_r$rXrr
rFrPrrr�
send_preambles
��zBaseHandler.send_preamblecCsP|jstd��|jst|�|_|��n	|jt|�7_|�|�|��dS)z+'write()' callable as specified by PEP 3333zwrite() before start_response()N)r_r^r\rRrW�send_headersrk�_flushrNrrrrKs


zBaseHandler.writecCsdS)aPlatform-specific file transmission

        Override this method in subclasses to support platform-specific
        file transmission.  It is only called if the application's
        return iterable ('self.result') is an instance of
        'self.wsgi_file_wrapper'.

        This method should return a true value if it was able to actually
        transmit the wrapped file-like object using a platform-specific
        approach.  It should return a false value if normal iteration
        should be used instead.  An exception can be raised to indicate
        that transmission was attempted, but failed.

        NOTE: this method should call 'self.send_headers()' if
        'self.headers_sent' is false and it is going to attempt direct
        transmission of the file.
        FrrPrrrrJ)szBaseHandler.sendfilecCs&|js|j�dd�|��dS	dS)z.Ensure headers and content have both been sentrQ�0N)r\rXrGrnrPrrrrL>szBaseHandler.finish_contentc	Cs�z5t|jd�r!|j��Wd|_|_|_|_d|_d|_dSWd|_|_|_|_d|_d|_dSd|_|_|_|_d|_d|_w)z�Close the iterable (if needed) and reset all instance vars

        Subclasses may want to also drop the client connection.
        r7NrF)rMr1r7rXr_r'rWr\rPrrrr7Hs��zBaseHandler.closecCs<|��d|_|jr|��r|��|�t|j��dSdS)z1Transmit headers to the client, via self._write()TN)rZr\rErjrmrk�bytesrXrPrrrrnUs�zBaseHandler.send_headerscCs|j}|duot|j|�S)z@True if 'self.result' is an instance of 'self.wsgi_file_wrapper'N)rD�
isinstancer1)r8�wrapperrrrrI^szBaseHandler.result_is_filecCs|jd��dkS)z,True if client can accept status and headersZSERVER_PROTOCOLzHTTP/0.9)r'�upperrPrrrrjdszBaseHandler.client_is_moderncCsLz"ddlm}|��}||d|d|d|j|�|��Wd}dSd}w)z�Log the 'exc_info' tuple in the server log

        Subclasses may override to retarget the output or change its format.
        r)�print_exceptionrr[N)�	tracebackrur>�traceback_limit�flush)r8rbru�stderrrrr�
log_exceptionis�
zBaseHandler.log_exceptioncCs6|�t���|js|�|j|j�|_|��dSdS)z>Log current error, and send error output to client if possibleN)	rzr"rbr\�error_outputr'r0r1r2rPrrrr6ys
�zBaseHandler.handle_errorcCs$||j|jdd�t���|jgS)aZWSGI mini-app to create error output

        By default, this just uses the 'error_status', 'error_headers',
        and 'error_body' attributes to generate an output page.  It can
        be overridden in a subclass to dynamically generate diagnostics,
        choose an appropriate message for the user's preferred language, etc.

        Note, however, that it's not recommended from a security perspective to
        spit out diagnostics to any old user; ideally, you should have to do
        something special to enable diagnostic output, which is why we don't
        include any here!
        N)�error_status�
error_headersr"rb�
error_body)r8r'r0rrrr{�s
zBaseHandler.error_outputcC�t�)aOverride in subclass to buffer data for send to client

        It's okay if this method actually transmits the data; BaseHandler
        just separates write and flush operations for greater efficiency
        when the underlying system actually has such a distinction.
        �rUrNrrrrk�szBaseHandler._writecCr)z�Override in subclass to force sending of recent '_write()' calls

        It's okay if this method is a no-op (i.e., if '_write()' actually
        sends the data.
        r�rPrrrro�szBaseHandler._flushcCr)z4Override in subclass to return suitable 'wsgi.input'r�rPrrrr=��zBaseHandler.get_stdincCr)z5Override in subclass to return suitable 'wsgi.errors'r�rPrrrr>�r�zBaseHandler.get_stderrcCr)z>Override in subclass to insert CGI variables in 'self.environ'r�rPrrrr<�r�zBaseHandler.add_cgi_vars�N)2�__name__�
__module__�__qualname__�__doc__r?rBrCr@rErlrFrr:rrDrr`rwr|r}r~r_r1r\rXrWr9r/r2rArYrZr0rarmrKrJrLr7rnrIrjrzr6r{rkror=r>r<rrrrr^sX


		rc@sDeZdZdZ	ddd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dS)raqHandler that's just initialized with streams, environment, etc.

    This handler subclass is intended for synchronous HTTP/1.0 origin servers,
    and handles sending the entire response output, given the correct inputs.

    Usage::

        handler = SimpleHandler(
            inp,out,err,env, multithread=False, multiprocess=True
        )
        handler.run(app)TFcCs(||_||_||_||_||_||_dSr�)�stdin�stdoutry�base_envrBrC)r8r�r�ryr'�multithread�multiprocessrrr�__init__�s
zSimpleHandler.__init__cC�|jSr�)r�rPrrrr=��zSimpleHandler.get_stdincCr�r�)ryrPrrrr>�r�zSimpleHandler.get_stderrcCs|j�|j�dSr�)r'�updater�rPrrrr<�szSimpleHandler.add_cgi_varscCs^|j�|�}|dus|t|�krdSddlm}|dt�	||d�}|s(dS|j�|�}q)Nr)�warnz9SimpleHandler.stdout.write() should not do partial writes)r�rKrR�warningsr��DeprecationWarning)r8rOr1r�rrrrk�s��zSimpleHandler._writecCs|j��|jj|_dSr�)r�rxrorPrrrro�s
zSimpleHandler._flushN)TF)
r�r�r�r�r�r=r>r<rkrorrrrr�s
�

rc@seZdZdZdZdS)r	a�CGI-like systems using input/output/error streams and environ mapping

    Usage::

        handler = BaseCGIHandler(inp,out,err,env)
        handler.run(app)

    This handler class is useful for gateway protocols like ReadyExec and
    FastCGI, that have usable input/output/error streams and an environment
    mapping.  It's also the base class for CGIHandler, which just uses
    sys.stdin, os.environ, and so on.

    The constructor also takes keyword arguments 'multithread' and
    'multiprocess' (defaulting to 'True' and 'False' respectively) to control
    the configuration sent to the application.  It sets 'origin_server' to
    False (to enable CGI-like output), and assumes that 'wsgi.run_once' is
    False.
    FN)r�r�r�r�rErrrrr	�sr	c@� eZdZdZdZiZdd�ZdS)r
a�CGI-based invocation via sys.stdin/stdout/stderr and os.environ

    Usage::

        CGIHandler().run(app)

    The difference between this class and BaseCGIHandler is that it always
    uses 'wsgi.run_once' of 'True', 'wsgi.multithread' of 'False', and
    'wsgi.multiprocess' of 'True'.  It does not take any initialization
    parameters, but always uses 'sys.stdin', 'os.environ', and friends.

    If you need to override any of these parameters, use BaseCGIHandler
    instead.
    Tc	Cs(tj|tjjtjjtjt�ddd�dS)NFT�r�r�)r	r�r"r��bufferr�ryrrPrrrr�s
�zCGIHandler.__init__N�r�r�r�r�r@r:r�rrrrr
�s
r
c@r�)raCGI-based invocation with workaround for IIS path bug

    This handler should be used in preference to CGIHandler when deploying on
    Microsoft IIS without having set the config allowPathInfo option (IIS>=7)
    or metabase allowPathInfoForScriptMappings (IIS<7).
    Tc	Csjt�}|�dd�}|�dd�}|d�|d�r"|t|�d�|d<tj|tjjtj	jtj
|ddd�dS)Nrrr�/FTr�)rr*rrRr	r�r"r�r�r�ry)r8r'�pathZscriptrrrr�2s
�zIISCGIHandler.__init__Nr�rrrrrs
r)r��utilrrrrXrr"r&r
�__all__rrr�__contains__rrrrrr	r
rrrrr�<module>s(�<V2__pycache__/validate.cpython-310.pyc000064400000034422151543516720013264 0ustar00o

���h�:�@s�dZdgZddlZddlZddlZe�d�Ze�d�ZGdd�de�Z	dd	�Z
d
d�Zdd�ZGd
d�d�Z
Gdd�d�ZGdd�d�ZGdd�d�ZGdd�d�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�ZdS)'a&
Middleware to check for obedience to the WSGI specification.

Some of the things this checks:

* Signature of the application and start_response (including that
  keyword arguments are not used).

* Environment checks:

  - Environment is a dictionary (and not a subclass).

  - That all the required keys are in the environment: REQUEST_METHOD,
    SERVER_NAME, SERVER_PORT, wsgi.version, wsgi.input, wsgi.errors,
    wsgi.multithread, wsgi.multiprocess, wsgi.run_once

  - That HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH are not in the
    environment (these headers should appear as CONTENT_LENGTH and
    CONTENT_TYPE).

  - Warns if QUERY_STRING is missing, as the cgi module acts
    unpredictably in that case.

  - That CGI-style variables (that don't contain a .) have
    (non-unicode) string values

  - That wsgi.version is a tuple

  - That wsgi.url_scheme is 'http' or 'https' (@@: is this too
    restrictive?)

  - Warns if the REQUEST_METHOD is not known (@@: probably too
    restrictive).

  - That SCRIPT_NAME and PATH_INFO are empty or start with /

  - That at least one of SCRIPT_NAME or PATH_INFO are set.

  - That CONTENT_LENGTH is a positive integer.

  - That SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should
    be '/').

  - That wsgi.input has the methods read, readline, readlines, and
    __iter__

  - That wsgi.errors has the methods flush, write, writelines

* The status is a string, contains a space, starts with an integer,
  and that integer is in range (> 100).

* That the headers is a list (not a subclass, not another kind of
  sequence).

* That the items of the headers are tuples of strings.

* That there is no 'status' header (that is used in CGI, but not in
  WSGI).

* That the headers don't contain newlines or colons, end in _ or -, or
  contain characters codes below 037.

* That Content-Type is given if there is content (CGI often has a
  default content type, but WSGI does not).

* That no Content-Type is given when there is no content (@@: is this
  too restrictive?)

* That the exc_info argument to start_response is a tuple or None.

* That all calls to the writer are with strings, and no other methods
  on the writer are accessed.

* That wsgi.input is used properly:

  - .read() is called with exactly one argument

  - That it returns a string

  - That readline, readlines, and __iter__ return strings

  - That .close() is not called

  - No other methods are provided

* That wsgi.errors is used properly:

  - .write() and .writelines() is called with a string

  - That .close() is not called, and no other methods are provided.

* The response iterator:

  - That it is not a string (it should be a list of a single string; a
    string will work, but perform horribly).

  - That .__next__() returns a string

  - That the iterator is not iterated over until start_response has
    been called (that can signal either a server or application
    error).

  - That .close() is called (doesn't raise exception, only prints to
    sys.stderr, because we only know it isn't called when the object
    is garbage collected).
�	validator�Nz^[a-zA-Z][a-zA-Z0-9\-_]*$z[\000-\037]c@seZdZdZdS)�WSGIWarningz:
    Raised in response to WSGI-spec-related warnings
    N)�__name__�
__module__�__qualname__�__doc__�rr�7/opt/alt/python310/lib64/python3.10/wsgiref/validate.pyrysrcGs|st|��dS�N)�AssertionError)Zcond�argsrrr	�assert_~s�r
cCs$t|�tur|Std�|t|����)Nz!{0} must be of type str (got {1}))�type�strr�format�repr)�value�titlerrr	�check_string_type�s
�rcs�fdd�}|S)a�
    When applied between a WSGI server and a WSGI application, this
    middleware will check for WSGI compliance on a number of levels.
    This middleware does not modify the request or response in any
    way, but will raise an AssertionError if anything seems off
    (except for a failure to close the application iterator, which
    will be printed to stderr -- there's no way to raise an exception
    at that point).
    cs�tt|�dkd�t|d�|\}�t|�g���fdd�}t|d�|d<t|d�|d<�||�}t|duo=|dkd	�t|�t|��S)
N�zTwo arguments required�No keyword arguments allowedcs�tt|�dkpt|�dkd|f�t|d�|d}|d}t|�dkr+|d}nd}t|�t|�t||�t|���d�t�|��S)Nr�zInvalid number of arguments: %srr�)r
�len�check_status�
check_headers�check_content_type�check_exc_info�append�WriteWrapper)r�kw�status�headers�exc_info�Zstart_responseZstart_response_startedrr	�start_response_wrapper�s�


z;validator.<locals>.lint_app.<locals>.start_response_wrapper�
wsgi.input�wsgi.errorsFz>The application must return an iterator, if only an empty list)r
r�
check_environ�InputWrapper�ErrorWrapper�check_iterator�IteratorWrapper)rr �environr%�iterator��applicationr$r	�lint_app�s
�
zvalidator.<locals>.lint_appr)r0r1rr/r	r�s)c@s<eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
S)r)cC�
||_dSr
)�input)�self�
wsgi_inputrrr	�__init__��
zInputWrapper.__init__cGs0tt|�dk�|jj|�}tt|�tu�|S�Nr)r
rr3�readr�bytes�r4r�vrrr	r9��zInputWrapper.readcGs0tt|�dk�|jj|�}tt|�tu�|Sr8)r
rr3�readlinerr:r;rrr	r>�r=zInputWrapper.readlinecGsJtt|�dk�|jj|�}tt|�tu�|D]
}tt|�tu�q|Sr8)r
rr3�	readlinesr�listr:)r4r�lines�linerrr	r?�szInputWrapper.readlinesccs�	|��}|s
dS|Vqr
)r>)r4rBrrr	�__iter__�s��zInputWrapper.__iter__cC�tdd�dS)Nrz input.close() must not be called�r
�r4rrr	�close��zInputWrapper.closeN)	rrrr6r9r>r?rCrGrrrr	r)�sr)c@�4eZdZdd�Zdd�Zdd�Zdd�Zd	d
�ZdS)r*cCr2r
)�errors)r4�wsgi_errorsrrr	r6�r7zErrorWrapper.__init__cCs tt|�tu�|j�|�dSr
)r
rrrJ�write�r4�srrr	rL�szErrorWrapper.writecCs|j��dSr
)rJ�flushrFrrr	rO�rHzErrorWrapper.flushcCs|D]}|�|�qdSr
)rL)r4�seqrBrrr	�
writelines�s�zErrorWrapper.writelinescCrD)Nrz!errors.close() must not be calledrErFrrr	rG�rHzErrorWrapper.closeN)rrrr6rLrOrQrGrrrr	r*�sr*c@�eZdZdd�Zdd�ZdS)rcCr2r
)�writer)r4Zwsgi_writerrrr	r6�r7zWriteWrapper.__init__cCstt|�tu�|�|�dSr
)r
rr:rSrMrrr	�__call__�szWriteWrapper.__call__N)rrrr6rTrrrr	r��rc@rR)�PartialIteratorWrappercCr2r
�r.)r4�
wsgi_iteratorrrr	r6r7zPartialIteratorWrapper.__init__cCst|jd�Sr
)r,r.rFrrr	rCszPartialIteratorWrapper.__iter__N)rrrr6rCrrrr	rV�rUrVc@rI)r,cCs ||_t|�|_d|_||_dS)NF)�original_iterator�iterr.�closed�check_start_response)r4rXr\rrr	r6	s

zIteratorWrapper.__init__cCs|Sr
rrFrrr	rCszIteratorWrapper.__iter__cCsTt|jd�t|j�}t|�turtdd|f�|jdur(t|jd�d|_|S)NzIterator read after closedFz$Iterator yielded non-bytestring (%r)zjThe application returns and we started iterating over its body, but start_response has not yet been called)r
r[�nextr.rr:r\)r4r<rrr	�__next__s�

�zIteratorWrapper.__next__cCs$d|_t|jd�r|j��dSdS)NTrG)r[�hasattrrYrGrFrrr	rGs�zIteratorWrapper.closecCs"|js	tj�d�t|jd�dS)Nz/Iterator garbage collected without being closed)r[�sys�stderrrLr
rFrrr	�__del__#s��zIteratorWrapper.__del__N)rrrr6rCr^rGrbrrrr	r,sr,cCs�tt|�tudt|�|f�dD]}t||vd|f�qdD]}t||vd||dd�f�q d|vr<t�dt�|��D]}d	|vrGq@tt||�tud
|t||�||f�q@tt|d�tud|df�t|d
dvd|d
�t	|d�t
|d�|ddvr�t�d|dt�t|�d�p�|d�d�d|d�t|�d�p�|d�d�d|d�|�d�r�tt
|d�dkd|d�|�d�s�td|vd�t|�d�dkd�dS)Nz:Environment is not of the right type: %r (environment: %r))	�REQUEST_METHODZSERVER_NAMEZSERVER_PORT�wsgi.versionr&r'zwsgi.multithreadzwsgi.multiprocessz
wsgi.run_oncez$Environment missing required key: %r)ZHTTP_CONTENT_TYPEZHTTP_CONTENT_LENGTHz8Environment should not have the key: %s (use %s instead)�ZQUERY_STRINGz�QUERY_STRING is not in the WSGI environment; the cgi module will use sys.argv when this variable is missing, so application errors are more likely�.z9Environmental variable %s is not a string: %r (value: %r)rdz#wsgi.version should be a tuple (%r)zwsgi.url_scheme)ZhttpZhttpszwsgi.url_scheme unknown: %rr&r'rc)ZGETZHEADZPOSTZOPTIONSZPATCHZPUTZDELETEZTRACEzUnknown REQUEST_METHOD: %rZSCRIPT_NAME�/z$SCRIPT_NAME doesn't start with /: %rZ	PATH_INFOz"PATH_INFO doesn't start with /: %rZCONTENT_LENGTHrzInvalid CONTENT_LENGTH: %rzgOne of SCRIPT_NAME or PATH_INFO are required (PATH_INFO should at least be '/' if SCRIPT_NAME is empty)zOSCRIPT_NAME cannot be '/'; it should instead be '', and PATH_INFO should be '/')r
r�dict�warnings�warnr�keysr�tuple�check_input�check_errors�get�
startswith�int)r-�keyrrr	r(*sx
���������
�
�
�
�

�
��r(cC�&dD]}tt||�d||f�qdS)N)r9r>r?rCz-wsgi.input (%r) doesn't have the attribute %s�r
r_)r5�attrrrr	rmk�
���rmcCrs)N)rOrLrQz.wsgi.errors (%r) doesn't have the attribute %srt)rKrurrr	rnqrvrncCszt|d�}|�dd�d}tt|�dkd|�t|�}t|dkd|�t|�dks1|dd	kr;t�d
|t�dSdS)N�Statusrrrz)Status codes must be three characters: %r�dzStatus code is invalid: %r�� zjThe status string (%r) should be a three-digit integer followed by a single space and a status explanation)r�splitr
rrqrirjr)r!Zstatus_codeZ
status_intrrr	rws
����rcCstt|�tud|t|�f�|D]n}tt|�tud|t|�f�tt|�dk�|\}}t|d�}t|d�}t|��dkd|�td|voKd	|vd
|�tt�|�d|�t|�	d�of|�	d
�d|�t
�|�rtdd|t
�|��d�f�qdS)Nz%Headers (%r) must be of type list: %rz1Individual headers (%r) must be of type tuple: %rr�Header namezHeader valuer!zyThe Status header cannot be used; it conflicts with CGI script, and HTTP status is not given through headers (value: %r).�
�:z,Header names may not contain ':' or '\n': %rzBad header name: %r�-�_z#Names may not end in '-' or '_': %rrz#Bad header value: %r (bad char: %r))r
rr@rlrr�lower�	header_re�search�endswith�bad_header_value_re�group)r"�item�namerrrr	r�sB
��
��

����
���rcCs�t|d�}t|�dd�d�}d}|D]\}}t|d�}|��dkr0||vr)dStdd|�q||vr>tdd|�dSdS)	Nrwrr)��i0r|zcontent-typezJContent-Type header found in a %s response, which must not return content.z,No Content-Type header found in headers (%s))rrqr{r�r
)r!r"�codeZNO_MESSAGE_BODYr�rrrr	r�s

���rcCs*t|dup
t|�tud|t|�f�dS)Nz exc_info (%r) is not a tuple: %r)r
rrl)r#rrr	r�s�rcCstt|ttf�d�dS)NzwYou should not return a string as your application iterator, instead return a single-item list containing a bytestring.)r
�
isinstancerr:rWrrr	r+�s�r+)r�__all__�rer`ri�compiler�r��Warningrr
rrr)r*rrVr,r(rmrnrrrrr+rrrr	�<module>s0j

7#		#A__pycache__/simple_server.cpython-310.pyc000064400000012312151543516720014344 0ustar00o

���h3�@s4dZddlmZmZddlZddlZddlmZddl	m
Z
dZgd�ZdeZ
e
�d	ej��dZe
d
eZGdd�de�ZGd
d�de�ZGdd�de�Zdd�Zeefdd�Zedkr�edde��'Zej��Zededdedd�ddlZe�d�e��Wd�dS1s�wYdSdS)a!BaseHTTPServer that implements the Python WSGI protocol (PEP 3333)

This is both an example of how WSGI can be implemented, and a basis for running
simple web applications on a local machine, such as might be done when testing
or debugging an application.  It has not been reviewed for security issues,
however, and we strongly recommend that you use a "real" web server for
production use.

For example usage, see the 'if __name__=="__main__"' block at the end of the
module.  See also the BaseHTTPServer module docs for other API information.
�)�BaseHTTPRequestHandler�
HTTPServerN)�
SimpleHandler)�python_implementationz0.2)�
WSGIServer�WSGIRequestHandler�demo_app�make_server�WSGIServer/�/� c@seZdZeZdd�ZdS)�
ServerHandlerc	Cs<z|j�|j�dd�d|j�Wt�|�dSt�|�w)Nr�r)�request_handlerZlog_requestZstatus�splitZ
bytes_sentr�close��self�r�</opt/alt/python310/lib64/python3.10/wsgiref/simple_server.pyr s
�zServerHandler.closeN)�__name__�
__module__�__qualname__�software_versionZserver_softwarerrrrrr
sr
c@s4eZdZdZdZdd�Zdd�Zdd�Zd	d
�ZdS)rz7BaseHTTPServer that implements the Python WSGI protocolNcCst�|�|��dS)z.Override server_bind to store the server name.N)r�server_bind�
setup_environrrrrr0s
zWSGIServer.server_bindcCsFi}|_|j|d<d|d<t|j�|d<d|d<d|d<d|d<dS)	NZSERVER_NAMEzCGI/1.1ZGATEWAY_INTERFACEZSERVER_PORT��REMOTE_HOST�CONTENT_LENGTHZSCRIPT_NAME)�base_environZserver_name�strZserver_port)r�envrrrr5s

zWSGIServer.setup_environcCs|jS�N��applicationrrrr�get_app?�zWSGIServer.get_appcCs
||_dSr"r#)rr$rrr�set_appBs
zWSGIServer.set_app)	rrr�__doc__r$rrr%r'rrrrr*s
rc@s,eZdZdeZdd�Zdd�Zdd�ZdS)	rr
cCsL|jj��}|j|d<|j|d<|j|d<d|jvr$|j�dd�\}}n|jd}}tj	�
|d�|d<||d	<|��}||jd
krF||d<|jd
|d<|j
�d
�dur]|j
��|d<n|j
d
|d<|j
�d�}|rp||d<|j
��D].\}}|�dd���}|��}||vr�qud||vr�|d|d|7<qu||d|<qu|S)NZSERVER_PROTOCOLZSERVER_SOFTWAREZREQUEST_METHOD�?rrz
iso-8859-1Z	PATH_INFOZQUERY_STRINGrrZREMOTE_ADDRzcontent-typeZCONTENT_TYPEzcontent-lengthr�-�_ZHTTP_�,)�serverr�copy�request_version�server_version�command�pathr�urllib�parseZunquoteZaddress_stringZclient_addressZheaders�getZget_content_type�items�replace�upper�strip)rr!r2Zquery�hostZlength�k�vrrr�get_environKs6



zWSGIRequestHandler.get_environcCstjSr")�sys�stderrrrrr�
get_stderrpr&zWSGIRequestHandler.get_stderrcCs�|j�d�|_t|j�dkrd|_d|_d|_|�d�dS|��s$dSt	|j|j
|��|��dd�}||_
|�|j���dS)zHandle a single HTTP requestiiri�NF)Zmultithread)Zrfile�readlineZraw_requestline�lenZrequestliner/r1Z
send_errorZ
parse_requestr
Zwfiler@r=r�runr-r%)rZhandlerrrr�handless
�zWSGIRequestHandler.handleN)rrr�__version__r0r=r@rDrrrrrGs
%rcCsrddlm}|�}td|d�t|d�t|���}|D]\}}t|dt|�|d�q|ddg�|���d�gS)	Nr)�StringIOzHello world!)�file�=z200 OK)zContent-Typeztext/plain; charset=utf-8zutf-8)�iorF�print�sortedr6�repr�getvalue�encode)�environZstart_responserF�stdout�hr;r<rrrr�s
rcCs|||f|�}|�|�|S)zACreate a new WSGI server listening on `host` and `port` for `app`)r')r:�portZappZserver_classZ
handler_classr-rrrr	�s
r	�__main__ri@zServing HTTP onrRrz...zhttp://localhost:8000/xyz?abc) r(Zhttp.serverrrr>Zurllib.parser3Zwsgiref.handlersr�platformrrE�__all__r0�versionr�sys_versionrr
rrrr	rZhttpdZsocketZgetsocknameZsarJZ
webbrowser�openZhandle_requestrrrr�<module>s4C
�	


"��__init__.py000064400000001113151543516720006662 0ustar00"""wsgiref -- a WSGI (PEP 3333) Reference Library

Current Contents:

* util -- Miscellaneous useful functions and wrappers

* headers -- Manage response headers

* handlers -- base classes for server/gateway implementations

* simple_server -- a simple BaseHTTPServer that supports WSGI

* validate -- validation wrapper that sits between an app and a server
  to detect errors in either

To-Do:

* cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard)

* cgi_wrapper -- Run CGI apps under WSGI

* router -- a simple middleware component that handles URL traversal
"""
util.py000064400000013333151543516720006107 0ustar00"""Miscellaneous WSGI-related Utilities"""

import posixpath

__all__ = [
    'FileWrapper', 'guess_scheme', 'application_uri', 'request_uri',
    'shift_path_info', 'setup_testing_defaults',
]


class FileWrapper:
    """Wrapper to convert file-like objects to iterables"""

    def __init__(self, filelike, blksize=8192):
        self.filelike = filelike
        self.blksize = blksize
        if hasattr(filelike,'close'):
            self.close = filelike.close

    def __getitem__(self,key):
        import warnings
        warnings.warn(
            "FileWrapper's __getitem__ method ignores 'key' parameter. "
            "Use iterator protocol instead.",
            DeprecationWarning,
            stacklevel=2
        )
        data = self.filelike.read(self.blksize)
        if data:
            return data
        raise IndexError

    def __iter__(self):
        return self

    def __next__(self):
        data = self.filelike.read(self.blksize)
        if data:
            return data
        raise StopIteration

def guess_scheme(environ):
    """Return a guess for whether 'wsgi.url_scheme' should be 'http' or 'https'
    """
    if environ.get("HTTPS") in ('yes','on','1'):
        return 'https'
    else:
        return 'http'

def application_uri(environ):
    """Return the application's base URI (no PATH_INFO or QUERY_STRING)"""
    url = environ['wsgi.url_scheme']+'://'
    from urllib.parse import quote

    if environ.get('HTTP_HOST'):
        url += environ['HTTP_HOST']
    else:
        url += environ['SERVER_NAME']

        if environ['wsgi.url_scheme'] == 'https':
            if environ['SERVER_PORT'] != '443':
                url += ':' + environ['SERVER_PORT']
        else:
            if environ['SERVER_PORT'] != '80':
                url += ':' + environ['SERVER_PORT']

    url += quote(environ.get('SCRIPT_NAME') or '/', encoding='latin1')
    return url

def request_uri(environ, include_query=True):
    """Return the full request URI, optionally including the query string"""
    url = application_uri(environ)
    from urllib.parse import quote
    path_info = quote(environ.get('PATH_INFO',''), safe='/;=,', encoding='latin1')
    if not environ.get('SCRIPT_NAME'):
        url += path_info[1:]
    else:
        url += path_info
    if include_query and environ.get('QUERY_STRING'):
        url += '?' + environ['QUERY_STRING']
    return url

def shift_path_info(environ):
    """Shift a name from PATH_INFO to SCRIPT_NAME, returning it

    If there are no remaining path segments in PATH_INFO, return None.
    Note: 'environ' is modified in-place; use a copy if you need to keep
    the original PATH_INFO or SCRIPT_NAME.

    Note: when PATH_INFO is just a '/', this returns '' and appends a trailing
    '/' to SCRIPT_NAME, even though empty path segments are normally ignored,
    and SCRIPT_NAME doesn't normally end in a '/'.  This is intentional
    behavior, to ensure that an application can tell the difference between
    '/x' and '/x/' when traversing to objects.
    """
    path_info = environ.get('PATH_INFO','')
    if not path_info:
        return None

    path_parts = path_info.split('/')
    path_parts[1:-1] = [p for p in path_parts[1:-1] if p and p != '.']
    name = path_parts[1]
    del path_parts[1]

    script_name = environ.get('SCRIPT_NAME','')
    script_name = posixpath.normpath(script_name+'/'+name)
    if script_name.endswith('/'):
        script_name = script_name[:-1]
    if not name and not script_name.endswith('/'):
        script_name += '/'

    environ['SCRIPT_NAME'] = script_name
    environ['PATH_INFO']   = '/'.join(path_parts)

    # Special case: '/.' on PATH_INFO doesn't get stripped,
    # because we don't strip the last element of PATH_INFO
    # if there's only one path part left.  Instead of fixing this
    # above, we fix it here so that PATH_INFO gets normalized to
    # an empty string in the environ.
    if name=='.':
        name = None
    return name

def setup_testing_defaults(environ):
    """Update 'environ' with trivial defaults for testing purposes

    This adds various parameters required for WSGI, including HTTP_HOST,
    SERVER_NAME, SERVER_PORT, REQUEST_METHOD, SCRIPT_NAME, PATH_INFO,
    and all of the wsgi.* variables.  It only supplies default values,
    and does not replace any existing settings for these variables.

    This routine is intended to make it easier for unit tests of WSGI
    servers and applications to set up dummy environments.  It should *not*
    be used by actual WSGI servers or applications, since the data is fake!
    """

    environ.setdefault('SERVER_NAME','127.0.0.1')
    environ.setdefault('SERVER_PROTOCOL','HTTP/1.0')

    environ.setdefault('HTTP_HOST',environ['SERVER_NAME'])
    environ.setdefault('REQUEST_METHOD','GET')

    if 'SCRIPT_NAME' not in environ and 'PATH_INFO' not in environ:
        environ.setdefault('SCRIPT_NAME','')
        environ.setdefault('PATH_INFO','/')

    environ.setdefault('wsgi.version', (1,0))
    environ.setdefault('wsgi.run_once', 0)
    environ.setdefault('wsgi.multithread', 0)
    environ.setdefault('wsgi.multiprocess', 0)

    from io import StringIO, BytesIO
    environ.setdefault('wsgi.input', BytesIO())
    environ.setdefault('wsgi.errors', StringIO())
    environ.setdefault('wsgi.url_scheme',guess_scheme(environ))

    if environ['wsgi.url_scheme']=='http':
        environ.setdefault('SERVER_PORT', '80')
    elif environ['wsgi.url_scheme']=='https':
        environ.setdefault('SERVER_PORT', '443')



_hoppish = {
    'connection', 'keep-alive', 'proxy-authenticate',
    'proxy-authorization', 'te', 'trailers', 'transfer-encoding',
    'upgrade'
}.__contains__

def is_hop_by_hop(header_name):
    """Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header"""
    return _hoppish(header_name.lower())
headers.py000064400000015156151543516720006552 0ustar00"""Manage HTTP Response Headers

Much of this module is red-handedly pilfered from email.message in the stdlib,
so portions are Copyright (C) 2001,2002 Python Software Foundation, and were
written by Barry Warsaw.
"""

# Regular expression that matches `special' characters in parameters, the
# existence of which force quoting of the parameter value.
import re
tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')

def _formatparam(param, value=None, quote=1):
    """Convenience function to format and return a key=value pair.

    This will quote the value if needed or if quote is true.
    """
    if value is not None and len(value) > 0:
        if quote or tspecials.search(value):
            value = value.replace('\\', '\\\\').replace('"', r'\"')
            return '%s="%s"' % (param, value)
        else:
            return '%s=%s' % (param, value)
    else:
        return param


class Headers:
    """Manage a collection of HTTP response headers"""

    def __init__(self, headers=None):
        headers = headers if headers is not None else []
        if type(headers) is not list:
            raise TypeError("Headers must be a list of name/value tuples")
        self._headers = headers
        if __debug__:
            for k, v in headers:
                self._convert_string_type(k)
                self._convert_string_type(v)

    def _convert_string_type(self, value):
        """Convert/check value type."""
        if type(value) is str:
            return value
        raise AssertionError("Header names/values must be"
            " of type str (got {0})".format(repr(value)))

    def __len__(self):
        """Return the total number of headers, including duplicates."""
        return len(self._headers)

    def __setitem__(self, name, val):
        """Set the value of a header."""
        del self[name]
        self._headers.append(
            (self._convert_string_type(name), self._convert_string_type(val)))

    def __delitem__(self,name):
        """Delete all occurrences of a header, if present.

        Does *not* raise an exception if the header is missing.
        """
        name = self._convert_string_type(name.lower())
        self._headers[:] = [kv for kv in self._headers if kv[0].lower() != name]

    def __getitem__(self,name):
        """Get the first header value for 'name'

        Return None if the header is missing instead of raising an exception.

        Note that if the header appeared multiple times, the first exactly which
        occurrence gets returned is undefined.  Use getall() to get all
        the values matching a header field name.
        """
        return self.get(name)

    def __contains__(self, name):
        """Return true if the message contains the header."""
        return self.get(name) is not None


    def get_all(self, name):
        """Return a list of all the values for the named field.

        These will be sorted in the order they appeared in the original header
        list or were added to this instance, and may contain duplicates.  Any
        fields deleted and re-inserted are always appended to the header list.
        If no fields exist with the given name, returns an empty list.
        """
        name = self._convert_string_type(name.lower())
        return [kv[1] for kv in self._headers if kv[0].lower()==name]


    def get(self,name,default=None):
        """Get the first header value for 'name', or return 'default'"""
        name = self._convert_string_type(name.lower())
        for k,v in self._headers:
            if k.lower()==name:
                return v
        return default


    def keys(self):
        """Return a list of all the header field names.

        These will be sorted in the order they appeared in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        """
        return [k for k, v in self._headers]

    def values(self):
        """Return a list of all header values.

        These will be sorted in the order they appeared in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        """
        return [v for k, v in self._headers]

    def items(self):
        """Get all the header fields and values.

        These will be sorted in the order they were in the original header
        list, or were added to this instance, and may contain duplicates.
        Any fields deleted and re-inserted are always appended to the header
        list.
        """
        return self._headers[:]

    def __repr__(self):
        return "%s(%r)" % (self.__class__.__name__, self._headers)

    def __str__(self):
        """str() returns the formatted headers, complete with end line,
        suitable for direct HTTP transmission."""
        return '\r\n'.join(["%s: %s" % kv for kv in self._headers]+['',''])

    def __bytes__(self):
        return str(self).encode('iso-8859-1')

    def setdefault(self,name,value):
        """Return first matching header value for 'name', or 'value'

        If there is no header named 'name', add a new header with name 'name'
        and value 'value'."""
        result = self.get(name)
        if result is None:
            self._headers.append((self._convert_string_type(name),
                self._convert_string_type(value)))
            return value
        else:
            return result

    def add_header(self, _name, _value, **_params):
        """Extended header setting.

        _name is the header field to add.  keyword arguments can be used to set
        additional parameters for the header field, with underscores converted
        to dashes.  Normally the parameter will be added as key="value" unless
        value is None, in which case only the key will be added.

        Example:

        h.add_header('content-disposition', 'attachment', filename='bud.gif')

        Note that unlike the corresponding 'email.message' method, this does
        *not* handle '(charset, language, value)' tuples: all values must be
        strings or None.
        """
        parts = []
        if _value is not None:
            _value = self._convert_string_type(_value)
            parts.append(_value)
        for k, v in _params.items():
            k = self._convert_string_type(k)
            if v is None:
                parts.append(k.replace('_', '-'))
            else:
                v = self._convert_string_type(v)
                parts.append(_formatparam(k.replace('_', '-'), v))
        self._headers.append((self._convert_string_type(_name), "; ".join(parts)))
validate.py000064400000035371151543516720006731 0ustar00# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
# Licensed under the MIT license: https://opensource.org/licenses/mit-license.php
# Also licenced under the Apache License, 2.0: https://opensource.org/licenses/apache2.0.php
# Licensed to PSF under a Contributor Agreement
"""
Middleware to check for obedience to the WSGI specification.

Some of the things this checks:

* Signature of the application and start_response (including that
  keyword arguments are not used).

* Environment checks:

  - Environment is a dictionary (and not a subclass).

  - That all the required keys are in the environment: REQUEST_METHOD,
    SERVER_NAME, SERVER_PORT, wsgi.version, wsgi.input, wsgi.errors,
    wsgi.multithread, wsgi.multiprocess, wsgi.run_once

  - That HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH are not in the
    environment (these headers should appear as CONTENT_LENGTH and
    CONTENT_TYPE).

  - Warns if QUERY_STRING is missing, as the cgi module acts
    unpredictably in that case.

  - That CGI-style variables (that don't contain a .) have
    (non-unicode) string values

  - That wsgi.version is a tuple

  - That wsgi.url_scheme is 'http' or 'https' (@@: is this too
    restrictive?)

  - Warns if the REQUEST_METHOD is not known (@@: probably too
    restrictive).

  - That SCRIPT_NAME and PATH_INFO are empty or start with /

  - That at least one of SCRIPT_NAME or PATH_INFO are set.

  - That CONTENT_LENGTH is a positive integer.

  - That SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should
    be '/').

  - That wsgi.input has the methods read, readline, readlines, and
    __iter__

  - That wsgi.errors has the methods flush, write, writelines

* The status is a string, contains a space, starts with an integer,
  and that integer is in range (> 100).

* That the headers is a list (not a subclass, not another kind of
  sequence).

* That the items of the headers are tuples of strings.

* That there is no 'status' header (that is used in CGI, but not in
  WSGI).

* That the headers don't contain newlines or colons, end in _ or -, or
  contain characters codes below 037.

* That Content-Type is given if there is content (CGI often has a
  default content type, but WSGI does not).

* That no Content-Type is given when there is no content (@@: is this
  too restrictive?)

* That the exc_info argument to start_response is a tuple or None.

* That all calls to the writer are with strings, and no other methods
  on the writer are accessed.

* That wsgi.input is used properly:

  - .read() is called with exactly one argument

  - That it returns a string

  - That readline, readlines, and __iter__ return strings

  - That .close() is not called

  - No other methods are provided

* That wsgi.errors is used properly:

  - .write() and .writelines() is called with a string

  - That .close() is not called, and no other methods are provided.

* The response iterator:

  - That it is not a string (it should be a list of a single string; a
    string will work, but perform horribly).

  - That .__next__() returns a string

  - That the iterator is not iterated over until start_response has
    been called (that can signal either a server or application
    error).

  - That .close() is called (doesn't raise exception, only prints to
    sys.stderr, because we only know it isn't called when the object
    is garbage collected).
"""
__all__ = ['validator']


import re
import sys
import warnings

header_re = re.compile(r'^[a-zA-Z][a-zA-Z0-9\-_]*$')
bad_header_value_re = re.compile(r'[\000-\037]')

class WSGIWarning(Warning):
    """
    Raised in response to WSGI-spec-related warnings
    """

def assert_(cond, *args):
    if not cond:
        raise AssertionError(*args)

def check_string_type(value, title):
    if type (value) is str:
        return value
    raise AssertionError(
        "{0} must be of type str (got {1})".format(title, repr(value)))

def validator(application):

    """
    When applied between a WSGI server and a WSGI application, this
    middleware will check for WSGI compliance on a number of levels.
    This middleware does not modify the request or response in any
    way, but will raise an AssertionError if anything seems off
    (except for a failure to close the application iterator, which
    will be printed to stderr -- there's no way to raise an exception
    at that point).
    """

    def lint_app(*args, **kw):
        assert_(len(args) == 2, "Two arguments required")
        assert_(not kw, "No keyword arguments allowed")
        environ, start_response = args

        check_environ(environ)

        # We use this to check if the application returns without
        # calling start_response:
        start_response_started = []

        def start_response_wrapper(*args, **kw):
            assert_(len(args) == 2 or len(args) == 3, (
                "Invalid number of arguments: %s" % (args,)))
            assert_(not kw, "No keyword arguments allowed")
            status = args[0]
            headers = args[1]
            if len(args) == 3:
                exc_info = args[2]
            else:
                exc_info = None

            check_status(status)
            check_headers(headers)
            check_content_type(status, headers)
            check_exc_info(exc_info)

            start_response_started.append(None)
            return WriteWrapper(start_response(*args))

        environ['wsgi.input'] = InputWrapper(environ['wsgi.input'])
        environ['wsgi.errors'] = ErrorWrapper(environ['wsgi.errors'])

        iterator = application(environ, start_response_wrapper)
        assert_(iterator is not None and iterator != False,
            "The application must return an iterator, if only an empty list")

        check_iterator(iterator)

        return IteratorWrapper(iterator, start_response_started)

    return lint_app

class InputWrapper:

    def __init__(self, wsgi_input):
        self.input = wsgi_input

    def read(self, *args):
        assert_(len(args) == 1)
        v = self.input.read(*args)
        assert_(type(v) is bytes)
        return v

    def readline(self, *args):
        assert_(len(args) <= 1)
        v = self.input.readline(*args)
        assert_(type(v) is bytes)
        return v

    def readlines(self, *args):
        assert_(len(args) <= 1)
        lines = self.input.readlines(*args)
        assert_(type(lines) is list)
        for line in lines:
            assert_(type(line) is bytes)
        return lines

    def __iter__(self):
        while 1:
            line = self.readline()
            if not line:
                return
            yield line

    def close(self):
        assert_(0, "input.close() must not be called")

class ErrorWrapper:

    def __init__(self, wsgi_errors):
        self.errors = wsgi_errors

    def write(self, s):
        assert_(type(s) is str)
        self.errors.write(s)

    def flush(self):
        self.errors.flush()

    def writelines(self, seq):
        for line in seq:
            self.write(line)

    def close(self):
        assert_(0, "errors.close() must not be called")

class WriteWrapper:

    def __init__(self, wsgi_writer):
        self.writer = wsgi_writer

    def __call__(self, s):
        assert_(type(s) is bytes)
        self.writer(s)

class PartialIteratorWrapper:

    def __init__(self, wsgi_iterator):
        self.iterator = wsgi_iterator

    def __iter__(self):
        # We want to make sure __iter__ is called
        return IteratorWrapper(self.iterator, None)

class IteratorWrapper:

    def __init__(self, wsgi_iterator, check_start_response):
        self.original_iterator = wsgi_iterator
        self.iterator = iter(wsgi_iterator)
        self.closed = False
        self.check_start_response = check_start_response

    def __iter__(self):
        return self

    def __next__(self):
        assert_(not self.closed,
            "Iterator read after closed")
        v = next(self.iterator)
        if type(v) is not bytes:
            assert_(False, "Iterator yielded non-bytestring (%r)" % (v,))
        if self.check_start_response is not None:
            assert_(self.check_start_response,
                "The application returns and we started iterating over its body, but start_response has not yet been called")
            self.check_start_response = None
        return v

    def close(self):
        self.closed = True
        if hasattr(self.original_iterator, 'close'):
            self.original_iterator.close()

    def __del__(self):
        if not self.closed:
            sys.stderr.write(
                "Iterator garbage collected without being closed")
        assert_(self.closed,
            "Iterator garbage collected without being closed")

def check_environ(environ):
    assert_(type(environ) is dict,
        "Environment is not of the right type: %r (environment: %r)"
        % (type(environ), environ))

    for key in ['REQUEST_METHOD', 'SERVER_NAME', 'SERVER_PORT',
                'wsgi.version', 'wsgi.input', 'wsgi.errors',
                'wsgi.multithread', 'wsgi.multiprocess',
                'wsgi.run_once']:
        assert_(key in environ,
            "Environment missing required key: %r" % (key,))

    for key in ['HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH']:
        assert_(key not in environ,
            "Environment should not have the key: %s "
            "(use %s instead)" % (key, key[5:]))

    if 'QUERY_STRING' not in environ:
        warnings.warn(
            'QUERY_STRING is not in the WSGI environment; the cgi '
            'module will use sys.argv when this variable is missing, '
            'so application errors are more likely',
            WSGIWarning)

    for key in environ.keys():
        if '.' in key:
            # Extension, we don't care about its type
            continue
        assert_(type(environ[key]) is str,
            "Environmental variable %s is not a string: %r (value: %r)"
            % (key, type(environ[key]), environ[key]))

    assert_(type(environ['wsgi.version']) is tuple,
        "wsgi.version should be a tuple (%r)" % (environ['wsgi.version'],))
    assert_(environ['wsgi.url_scheme'] in ('http', 'https'),
        "wsgi.url_scheme unknown: %r" % environ['wsgi.url_scheme'])

    check_input(environ['wsgi.input'])
    check_errors(environ['wsgi.errors'])

    # @@: these need filling out:
    if environ['REQUEST_METHOD'] not in (
        'GET', 'HEAD', 'POST', 'OPTIONS', 'PATCH', 'PUT', 'DELETE', 'TRACE'):
        warnings.warn(
            "Unknown REQUEST_METHOD: %r" % environ['REQUEST_METHOD'],
            WSGIWarning)

    assert_(not environ.get('SCRIPT_NAME')
            or environ['SCRIPT_NAME'].startswith('/'),
        "SCRIPT_NAME doesn't start with /: %r" % environ['SCRIPT_NAME'])
    assert_(not environ.get('PATH_INFO')
            or environ['PATH_INFO'].startswith('/'),
        "PATH_INFO doesn't start with /: %r" % environ['PATH_INFO'])
    if environ.get('CONTENT_LENGTH'):
        assert_(int(environ['CONTENT_LENGTH']) >= 0,
            "Invalid CONTENT_LENGTH: %r" % environ['CONTENT_LENGTH'])

    if not environ.get('SCRIPT_NAME'):
        assert_('PATH_INFO' in environ,
            "One of SCRIPT_NAME or PATH_INFO are required (PATH_INFO "
            "should at least be '/' if SCRIPT_NAME is empty)")
    assert_(environ.get('SCRIPT_NAME') != '/',
        "SCRIPT_NAME cannot be '/'; it should instead be '', and "
        "PATH_INFO should be '/'")

def check_input(wsgi_input):
    for attr in ['read', 'readline', 'readlines', '__iter__']:
        assert_(hasattr(wsgi_input, attr),
            "wsgi.input (%r) doesn't have the attribute %s"
            % (wsgi_input, attr))

def check_errors(wsgi_errors):
    for attr in ['flush', 'write', 'writelines']:
        assert_(hasattr(wsgi_errors, attr),
            "wsgi.errors (%r) doesn't have the attribute %s"
            % (wsgi_errors, attr))

def check_status(status):
    status = check_string_type(status, "Status")
    # Implicitly check that we can turn it into an integer:
    status_code = status.split(None, 1)[0]
    assert_(len(status_code) == 3,
        "Status codes must be three characters: %r" % status_code)
    status_int = int(status_code)
    assert_(status_int >= 100, "Status code is invalid: %r" % status_int)
    if len(status) < 4 or status[3] != ' ':
        warnings.warn(
            "The status string (%r) should be a three-digit integer "
            "followed by a single space and a status explanation"
            % status, WSGIWarning)

def check_headers(headers):
    assert_(type(headers) is list,
        "Headers (%r) must be of type list: %r"
        % (headers, type(headers)))
    for item in headers:
        assert_(type(item) is tuple,
            "Individual headers (%r) must be of type tuple: %r"
            % (item, type(item)))
        assert_(len(item) == 2)
        name, value = item
        name = check_string_type(name, "Header name")
        value = check_string_type(value, "Header value")
        assert_(name.lower() != 'status',
            "The Status header cannot be used; it conflicts with CGI "
            "script, and HTTP status is not given through headers "
            "(value: %r)." % value)
        assert_('\n' not in name and ':' not in name,
            "Header names may not contain ':' or '\\n': %r" % name)
        assert_(header_re.search(name), "Bad header name: %r" % name)
        assert_(not name.endswith('-') and not name.endswith('_'),
            "Names may not end in '-' or '_': %r" % name)
        if bad_header_value_re.search(value):
            assert_(0, "Bad header value: %r (bad char: %r)"
            % (value, bad_header_value_re.search(value).group(0)))

def check_content_type(status, headers):
    status = check_string_type(status, "Status")
    code = int(status.split(None, 1)[0])
    # @@: need one more person to verify this interpretation of RFC 2616
    #     http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
    NO_MESSAGE_BODY = (204, 304)
    for name, value in headers:
        name = check_string_type(name, "Header name")
        if name.lower() == 'content-type':
            if code not in NO_MESSAGE_BODY:
                return
            assert_(0, ("Content-Type header found in a %s response, "
                        "which must not return content.") % code)
    if code not in NO_MESSAGE_BODY:
        assert_(0, "No Content-Type header found in headers (%s)" % headers)

def check_exc_info(exc_info):
    assert_(exc_info is None or type(exc_info) is tuple,
        "exc_info (%r) is not a tuple: %r" % (exc_info, type(exc_info)))
    # More exc_info checks?

def check_iterator(iterator):
    # Technically a bytestring is legal, which is why it's a really bad
    # idea, because it may cause the response to be returned
    # character-by-character
    assert_(not isinstance(iterator, (str, bytes)),
        "You should not return a string as your application iterator, "
        "instead return a single-item list containing a bytestring.")