Exemple #1
0
    def _do_read(self, length=None, use_readline=False):
        if use_readline:
            reader = self.rfile.readline
        else:
            reader = self.rfile.read
        content_length = self.content_length
        if content_length is None:
            # Either Content-Length or "Transfer-Encoding: chunked" must be present in a request with a body
            # if it was chunked, then this function would have not been called
            return ''
        self._send_100_continue()
        left = content_length - self.position
        if length is None:
            length = left
        elif length > left:
            length = left
        if not length:
            return b('')
        read = reader(length)
        self.position += len(read)
        if len(read) < length:
            if (use_readline
                    and not read.endswith(b("\n"))) or not use_readline:
                raise IOError(
                    "unexpected end of file while reading request at position %s"
                    % (self.position, ))

        return read
Exemple #2
0
    def _do_read(self, length=None, use_readline=False):
        if use_readline:
            reader = self.rfile.readline
        else:
            reader = self.rfile.read
        content_length = self.content_length
        if content_length is None:
            # Either Content-Length or "Transfer-Encoding: chunked" must be present in a request with a body
            # if it was chunked, then this function would have not been called
            return ''
        self._send_100_continue()
        left = content_length - self.position
        if length is None:
            length = left
        elif length > left:
            length = left
        if not length:
            return b('')
        read = reader(length)
        self.position += len(read)
        if len(read) < length:
            if (use_readline and not read.endswith(b("\n"))) or not use_readline:
                raise IOError("unexpected end of file while reading request at position %s" % (self.position,))

        return read
Exemple #3
0
 def _write(self, data):
     if not data:
         return
     if self.response_use_chunked:
         ## Write the chunked encoding
         data = b('\r\n').join((b('%x' % len(data)), data, b('')))
     self._sendall(data)
Exemple #4
0
 def _write(self, data):
     if not data:
         return
     if self.response_use_chunked:
         ## Write the chunked encoding
         data = b('\r\n').join((b('%x' % len(data)), data, b('')))
     self._sendall(data)
Exemple #5
0
    def _chunked_read(self, length=None, use_readline=False):
        rfile = self.rfile
        self._send_100_continue()

        if length == 0:
            return b("")

        if length is not None and length < 0:
            length = None

        if use_readline:
            reader = self.rfile.readline
        else:
            reader = self.rfile.read

        response = []
        while self.chunk_length != 0:
            maxreadlen = self.chunk_length - self.position
            if length is not None and length < maxreadlen:
                maxreadlen = length

            if maxreadlen > 0:
                data = reader(maxreadlen)
                if not data:
                    self.chunk_length = 0
                    raise IOError(
                        "unexpected end of file while parsing chunked data")

                datalen = len(data)
                response.append(data)

                self.position += datalen
                if self.chunk_length == self.position:
                    rfile.readline()

                if length is not None:
                    length -= datalen
                    if length == 0:
                        break
                if use_readline and data[-1:] == b("\n"):
                    break
            else:
                line = rfile.readline()
                if not line.endswith(b("\n")):
                    self.chunk_length = 0
                    raise IOError(
                        "unexpected end of file while reading chunked data header"
                    )
                self.chunk_length = int(line.split(b(";"), 1)[0], 16)
                self.position = 0
                if self.chunk_length == 0:
                    rfile.readline()
        return b('').join(response)
Exemple #6
0
    def _chunked_read(self, length=None, use_readline=False):
        rfile = self.rfile
        self._send_100_continue()

        if length == 0:
            return b("")

        if length is not None and length < 0:
            length = None

        if use_readline:
            reader = self.rfile.readline
        else:
            reader = self.rfile.read

        response = []
        while self.chunk_length != 0:
            maxreadlen = self.chunk_length - self.position
            if length is not None and length < maxreadlen:
                maxreadlen = length

            if maxreadlen > 0:
                data = reader(maxreadlen)
                if not data:
                    self.chunk_length = 0
                    raise IOError("unexpected end of file while parsing chunked data")

                datalen = len(data)
                response.append(data)

                self.position += datalen
                if self.chunk_length == self.position:
                    rfile.readline()

                if length is not None:
                    length -= datalen
                    if length == 0:
                        break
                if use_readline and data[-1:] == b("\n"):
                    break
            else:
                line = rfile.readline()
                if not line.endswith(b("\n")):
                    self.chunk_length = 0
                    raise IOError("unexpected end of file while reading chunked data header")
                self.chunk_length = int(line.split(b(";"), 1)[0], 16)
                self.position = 0
                if self.chunk_length == 0:
                    rfile.readline()
        return b('').join(response)
Exemple #7
0
 def read(self, len=1024):
     """Read up to LEN bytes and return them.
     Return zero-length string on EOF."""
     while True:
         try:
             return self._sslobj.read(len)
         except SSLError:
             ex = sys.exc_info()[1]
             if ex.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
                 return b('')
             elif ex.args[0] == SSL_ERROR_WANT_READ:
                 if self.timeout == 0.0:
                     raise
                 if PY3:
                     ex = None
                     del ex
                 else:
                     sys.exc_clear()
                 self._wait(self._read_event, timeout_exc=_SSLErrorReadTimeout)
             elif ex.args[0] == SSL_ERROR_WANT_WRITE:
                 if self.timeout == 0.0:
                     raise
                 if PY3:
                     ex = None
                     del ex
                 else:
                     sys.exc_clear()
                 # note: using _SSLErrorReadTimeout rather than _SSLErrorWriteTimeout below is intentional
                 self._wait(self._write_event, timeout_exc=_SSLErrorReadTimeout)
             else:
                 raise
Exemple #8
0
        def _write_with_headers(self, data):
            towrite = bytearray()
            self.headers_sent = True
            self.finalize_headers()

            towrite.extend(b('%s %s\r\n' % (self.request_version, self.status)))
            for header in self.response_headers:
                towrite.extend(b('%s: %s\r\n' % header))

            towrite.extend(b('\r\n'))
            if data:
                if self.response_use_chunked:
                    ## Write the chunked encoding
                    towrite.extend(b("%x\r\n" % (len(data),)))
                    towrite.extend(data)
                    towrite.extend(b("\r\n"))
                else:
                    towrite.extend(data)
            self._sendall(towrite)
Exemple #9
0
        def _write_with_headers(self, data):
            towrite = bytearray()
            self.headers_sent = True
            self.finalize_headers()

            towrite.extend(b('%s %s\r\n' %
                             (self.request_version, self.status)))
            for header in self.response_headers:
                towrite.extend(b('%s: %s\r\n' % header))

            towrite.extend(b('\r\n'))
            if data:
                if self.response_use_chunked:
                    ## Write the chunked encoding
                    towrite.extend(b("%x\r\n" % (len(data), )))
                    towrite.extend(data)
                    towrite.extend(b("\r\n"))
                else:
                    towrite.extend(data)
            self._sendall(towrite)
Exemple #10
0
 def recv(self, size):
     while True:
         try:
             data = _read(self.fileno(), size)
         except (IOError, OSError):
             code = sys.exc_info()[1].args[0]
             if code not in ignored_errors:
                 raise
             if not PY3:
                 sys.exc_clear()
         else:
             if not self._translate or not data:
                 return data
             if self._eat_newline:
                 self._eat_newline = False
                 if data.startswith(b('\n')):
                     data = data[1:]
                     if not data:
                         return self.recv(size)
             if data.endswith(b('\r')):
                 self._eat_newline = True
             return self._translate_newlines(data)
         self.hub.wait(self._read_event)
Exemple #11
0
 def recv(self, size):
     while True:
         try:
             data = _read(self.fileno(), size)
         except (IOError, OSError):
             code = sys.exc_info()[1].args[0]
             if code not in ignored_errors:
                 raise
             if not PY3:
                 sys.exc_clear()
         else:
             if not self._translate or not data:
                 return data
             if self._eat_newline:
                 self._eat_newline = False
                 if data.startswith(b("\n")):
                     data = data[1:]
                     if not data:
                         return self.recv(size)
             if data.endswith(b("\r")):
                 self._eat_newline = True
             return self._translate_newlines(data)
         self.hub.wait(self._read_event)
Exemple #12
0
import gevent
from gevent.server import StreamServer
from gevent.hub import GreenletExit, reraise, PY3, b, string_types


__all__ = ['WSGIHandler', 'WSGIServer']


MAX_REQUEST_LINE = 8192
# 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"]
_INTERNAL_ERROR_STATUS = '500 Internal Server Error'
_INTERNAL_ERROR_BODY = b('Internal Server Error')
_INTERNAL_ERROR_HEADERS = [('Content-Type', 'text/plain'),
                           ('Connection', 'close'),
                           ('Content-Length', str(len(_INTERNAL_ERROR_BODY)))]
_REQUEST_TOO_LONG_RESPONSE = b("HTTP/1.0 414 Request URI Too Long\r\nConnection: close\r\nContent-length: 0\r\n\r\n")
_BAD_REQUEST_RESPONSE = b("HTTP/1.0 400 Bad Request\r\nConnection: close\r\nContent-length: 0\r\n\r\n")
_CONTINUE_RESPONSE = b("HTTP/1.1 100 Continue\r\n\r\n")


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)


class Input(object):
Exemple #13
0
        def _execute_child(self, args, executable, preexec_fn, close_fds, cwd,
                           env, universal_newlines, startupinfo, creationflags,
                           shell, p2cread, p2cwrite, c2pread, c2pwrite,
                           errread, errwrite):
            """Execute program (POSIX version)"""

            if isinstance(args, string_types):
                args = [args]
            else:
                args = list(args)

            if shell:
                args = ["/bin/sh", "-c"] + args
                if executable:
                    args[0] = executable

            if executable is None:
                executable = args[0]

            self._loop.install_sigchld()

            # For transferring possible exec failure from child to parent
            # The first char specifies the exception type: 0 means
            # OSError, 1 means some other error.
            errpipe_read, errpipe_write = self.pipe_cloexec()
            try:
                try:
                    gc_was_enabled = gc.isenabled()
                    # Disable gc to avoid bug where gc -> file_dealloc ->
                    # write to stderr -> hang.  http://bugs.python.org/issue1336
                    gc.disable()
                    try:
                        self.pid = fork()
                    except:
                        if gc_was_enabled:
                            gc.enable()
                        raise
                    if self.pid == 0:
                        # Child
                        try:
                            # Close parent's pipe ends
                            if p2cwrite is not None:
                                os.close(p2cwrite)
                            if c2pread is not None:
                                os.close(c2pread)
                            if errread is not None:
                                os.close(errread)
                            os.close(errpipe_read)

                            # When duping fds, if there arises a situation
                            # where one of the fds is either 0, 1 or 2, it
                            # is possible that it is overwritten (#12607).
                            if c2pwrite == 0:
                                c2pwrite = os.dup(c2pwrite)
                            if errwrite == 0 or errwrite == 1:
                                errwrite = os.dup(errwrite)

                            # Dup fds for child
                            def _dup2(a, b):
                                # dup2() removes the CLOEXEC flag but
                                # we must do it ourselves if dup2()
                                # would be a no-op (issue #10806).
                                if a == b:
                                    self._set_cloexec_flag(a, False)
                                elif a is not None:
                                    os.dup2(a, b)
                                self._remove_nonblock_flag(b)

                            _dup2(p2cread, 0)
                            _dup2(c2pwrite, 1)
                            _dup2(errwrite, 2)

                            # Close pipe fds.  Make sure we don't close the
                            # same fd more than once, or standard fds.
                            closed = set([None])
                            for fd in [p2cread, c2pwrite, errwrite]:
                                if fd not in closed and fd > 2:
                                    os.close(fd)
                                    closed.add(fd)

                            # Close all other fds, if asked for
                            if close_fds:
                                self._close_fds(but=errpipe_write)

                            if cwd is not None:
                                os.chdir(cwd)

                            if preexec_fn:
                                preexec_fn()

                            if env is None:
                                os.execvp(executable, args)
                            else:
                                os.execvpe(executable, args, env)

                        except:
                            exc_type, exc_value, tb = sys.exc_info()
                            # Save the traceback and attach it to the exception object
                            exc_lines = traceback.format_exception(
                                exc_type, exc_value, tb)
                            exc_value.child_traceback = ''.join(exc_lines)
                            os.write(errpipe_write, pickle.dumps(exc_value))

                        finally:
                            # Make sure that the process exits no matter what.
                            # The return code does not matter much as it won't be
                            # reported to the application
                            os._exit(1)

                    # Parent
                    self._watcher = self._loop.child(self.pid)
                    self._watcher.start(self._on_child, self._watcher)

                    if gc_was_enabled:
                        gc.enable()
                finally:
                    # be sure the FD is closed no matter what
                    os.close(errpipe_write)

                if p2cread is not None and p2cwrite is not None:
                    os.close(p2cread)
                if c2pwrite is not None and c2pread is not None:
                    os.close(c2pwrite)
                if errwrite is not None and errread is not None:
                    os.close(errwrite)

                # Wait for exec to fail or succeed; possibly raising exception
                errpipe_read = FileObject(errpipe_read, 'rb')
                data = errpipe_read.read()
            finally:
                if hasattr(errpipe_read, 'close'):
                    errpipe_read.close()
                else:
                    os.close(errpipe_read)

            if data != b(""):
                self.wait()
                child_exception = pickle.loads(data)
                for fd in (p2cwrite, c2pread, errread):
                    if fd is not None:
                        os.close(fd)
                raise child_exception
Exemple #14
0
        def _execute_child(self, args, executable, preexec_fn, close_fds,
                           cwd, env, universal_newlines,
                           startupinfo, creationflags, shell,
                           p2cread, p2cwrite,
                           c2pread, c2pwrite,
                           errread, errwrite):
            """Execute program (POSIX version)"""

            if isinstance(args, string_types):
                args = [args]
            else:
                args = list(args)

            if shell:
                args = ["/bin/sh", "-c"] + args
                if executable:
                    args[0] = executable

            if executable is None:
                executable = args[0]

            self._loop.install_sigchld()

            # For transferring possible exec failure from child to parent
            # The first char specifies the exception type: 0 means
            # OSError, 1 means some other error.
            errpipe_read, errpipe_write = self.pipe_cloexec()
            try:
                try:
                    gc_was_enabled = gc.isenabled()
                    # Disable gc to avoid bug where gc -> file_dealloc ->
                    # write to stderr -> hang.  http://bugs.python.org/issue1336
                    gc.disable()
                    try:
                        self.pid = fork()
                    except:
                        if gc_was_enabled:
                            gc.enable()
                        raise
                    if self.pid == 0:
                        # Child
                        try:
                            # Close parent's pipe ends
                            if p2cwrite is not None:
                                os.close(p2cwrite)
                            if c2pread is not None:
                                os.close(c2pread)
                            if errread is not None:
                                os.close(errread)
                            os.close(errpipe_read)

                            # When duping fds, if there arises a situation
                            # where one of the fds is either 0, 1 or 2, it
                            # is possible that it is overwritten (#12607).
                            if c2pwrite == 0:
                                c2pwrite = os.dup(c2pwrite)
                            if errwrite == 0 or errwrite == 1:
                                errwrite = os.dup(errwrite)

                            # Dup fds for child
                            def _dup2(a, b):
                                # dup2() removes the CLOEXEC flag but
                                # we must do it ourselves if dup2()
                                # would be a no-op (issue #10806).
                                if a == b:
                                    self._set_cloexec_flag(a, False)
                                elif a is not None:
                                    os.dup2(a, b)
                                self._remove_nonblock_flag(b)
                            _dup2(p2cread, 0)
                            _dup2(c2pwrite, 1)
                            _dup2(errwrite, 2)

                            # Close pipe fds.  Make sure we don't close the
                            # same fd more than once, or standard fds.
                            closed = set([None])
                            for fd in [p2cread, c2pwrite, errwrite]:
                                if fd not in closed and fd > 2:
                                    os.close(fd)
                                    closed.add(fd)

                            # Close all other fds, if asked for
                            if close_fds:
                                self._close_fds(but=errpipe_write)

                            if cwd is not None:
                                os.chdir(cwd)

                            if preexec_fn:
                                preexec_fn()

                            if env is None:
                                os.execvp(executable, args)
                            else:
                                os.execvpe(executable, args, env)

                        except:
                            exc_type, exc_value, tb = sys.exc_info()
                            # Save the traceback and attach it to the exception object
                            exc_lines = traceback.format_exception(exc_type,
                                                                   exc_value,
                                                                   tb)
                            exc_value.child_traceback = ''.join(exc_lines)
                            os.write(errpipe_write, pickle.dumps(exc_value))

                        finally:
                            # Make sure that the process exits no matter what.
                            # The return code does not matter much as it won't be
                            # reported to the application
                            os._exit(1)

                    # Parent
                    self._watcher = self._loop.child(self.pid)
                    self._watcher.start(self._on_child, self._watcher)

                    if gc_was_enabled:
                        gc.enable()
                finally:
                    # be sure the FD is closed no matter what
                    os.close(errpipe_write)

                if p2cread is not None and p2cwrite is not None:
                    os.close(p2cread)
                if c2pwrite is not None and c2pread is not None:
                    os.close(c2pwrite)
                if errwrite is not None and errread is not None:
                    os.close(errwrite)

                # Wait for exec to fail or succeed; possibly raising exception
                errpipe_read = FileObject(errpipe_read, 'rb')
                data = errpipe_read.read()
            finally:
                if hasattr(errpipe_read, 'close'):
                    errpipe_read.close()
                else:
                    os.close(errpipe_read)

            if data != b(""):
                self.wait()
                child_exception = pickle.loads(data)
                for fd in (p2cwrite, c2pread, errread):
                    if fd is not None:
                        os.close(fd)
                raise child_exception
Exemple #15
0
    None,  # Dummy so we can use 1-based month numbers
    "Jan",
    "Feb",
    "Mar",
    "Apr",
    "May",
    "Jun",
    "Jul",
    "Aug",
    "Sep",
    "Oct",
    "Nov",
    "Dec"
]
_INTERNAL_ERROR_STATUS = '500 Internal Server Error'
_INTERNAL_ERROR_BODY = b('Internal Server Error')
_INTERNAL_ERROR_HEADERS = [('Content-Type', 'text/plain'),
                           ('Connection', 'close'),
                           ('Content-Length', str(len(_INTERNAL_ERROR_BODY)))]
_REQUEST_TOO_LONG_RESPONSE = b(
    "HTTP/1.0 414 Request URI Too Long\r\nConnection: close\r\nContent-length: 0\r\n\r\n"
)
_BAD_REQUEST_RESPONSE = b(
    "HTTP/1.0 400 Bad Request\r\nConnection: close\r\nContent-length: 0\r\n\r\n"
)
_CONTINUE_RESPONSE = b("HTTP/1.1 100 Continue\r\n\r\n")


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" % (