Ejemplo n.º 1
0
    def _finish(self):
        self.channel.reply_code = self.status

        DebugLogger.log('A', id(self.channel), '%d %d' % (
            self.status, self.stdout.length))

        t = self._tempfile
        if t is not None:
            self.stdout.write((file_close_producer(t), 0))
        self._tempfile = None

        self.channel.sendStreamTerminator(FCGI_STDOUT)
        self.channel.sendEndRecord()
        self.stdout.close()
        self.stderr.close()

        if not self.channel.closed:
            self.channel.push_with_producer(LoggingProducer(self.channel,
                                                            self.stdout.length,
                                                            'log_request'), 0)
        if self._shutdownRequested():
            config.ZSERVER_EXIT_CODE = self._shutdown_flag
            self.channel.push(ShutdownProducer(), 0)
            Wakeup(lambda: asyncore.close_all())
        else:
            self.channel.push(None, 0)
            Wakeup()
        self.channel = None
Ejemplo n.º 2
0
    def close(self):
        if not self._channel.closed:
            data = self._data.getvalue()
            l = len(data)
            DebugLogger.log('A', id(self._channel),
                            '%s %s' % (self._channel.reply_code, l))
            self._channel.push('%010d%s%010d' % (l, data, 0), 0)
            self._channel.push(
                LoggingProducer(self._channel, l, 'log_request'), 0)
            self._channel.push(
                CallbackProducer(lambda t=
                                 ('E', id(self._channel)): DebugLogger(*t)), 0)

            if self._shutdown:
                try:
                    r = self._shutdown[0]
                except:
                    r = 0
                config.ZSERVER_EXIT_CODE = r
                self._channel.push(ShutdownProducer(), 0)
                Wakeup(lambda: asyncore.close_all())
            else:
                self._channel.push(None, 0)
                Wakeup()
        self._data = None
        self._channel = None
Ejemplo n.º 3
0
    def _finish(self):
        self.channel.reply_code = self.status

        DebugLogger.log('A', id(self.channel), '%d %d' % (
            self.status, self.stdout.length))

        t = self._tempfile
        if t is not None:
            self.stdout.write((file_close_producer(t), 0))
        self._tempfile = None

        self.channel.sendStreamTerminator(FCGI_STDOUT)
        self.channel.sendEndRecord()
        self.stdout.close()
        self.stderr.close()

        if not self.channel.closed:
            self.channel.push_with_producer(LoggingProducer(self.channel,
                                                            self.stdout.length,
                                                            'log_request'), 0)
        if self._shutdownRequested():
            config.ZSERVER_EXIT_CODE = self._shutdown_flag
            self.channel.push(ShutdownProducer(), 0)
            Wakeup(lambda: asyncore.close_all())
        else:
            self.channel.push(None, 0)
            Wakeup()
        self.channel = None
Ejemplo n.º 4
0
    def handle_request(self, request):
        self.hits.increment()

        DebugLogger.log('B', id(request),
                        '%s %s' % (request.command.upper(), request.uri))

        size = get_header(CONTENT_LENGTH, request.header)
        if size and size != '0':
            size = int(size)
            zhttp_collector(self, request, size)
        else:
            sin = StringIO()
            self.continue_request(sin, request)
Ejemplo n.º 5
0
    def handle_request(self, request):
        self.hits.increment()

        DebugLogger.log('B', id(request),
                        '%s %s' % (request.command.upper(), request.uri))

        size = get_header(CONTENT_LENGTH, request.header)
        if size and size != '0':
            size = int(size)
            zhttp_collector(self, request, size)
        else:
            sin = StringIO()
            self.continue_request(sin, request)
Ejemplo n.º 6
0
    def log_request(self, bytes):
        DebugLogger.log('E', id(self))

        if 'HTTP_USER_AGENT' in self.env:
            user_agent = self.env['HTTP_USER_AGENT']
        else:
            user_agent = ''

        if 'HTTP_REFERER' in self.env:
            referer = self.env['HTTP_REFERER']
        else:
            referer = ''

        if 'PATH_INFO' in self.env:
            path = self.env['PATH_INFO']
        else:
            path = ''

        if 'REQUEST_METHOD' in self.env:
            method = self.env['REQUEST_METHOD']
        else:
            method = "GET"

        user_name = '-'
        if 'HTTP_AUTHORIZATION' in self.env:
            http_authorization = self.env['HTTP_AUTHORIZATION']
            if string.lower(http_authorization[:6]) == 'basic ':
                try:
                    decoded = base64.decodestring(http_authorization[6:])
                except base64.binascii.Error:
                    decoded = ''
                t = string.split(decoded, ':', 1)
                if len(t) >= 2:
                    user_name = t[0]
        if self.addr:
            self.server.logger.log(
                self.addr[0], '%s - %s [%s] "%s %s" %d %d "%s" "%s"' %
                (self.addr[1], user_name,
                 time.strftime('%d/%b/%Y:%H:%M:%S ', time.localtime(
                     time.time())) + tz_for_log, method, path, self.reply_code,
                 bytes, referer, user_agent))
        else:
            self.server.logger.log(
                '127.0.0.1 ', '- %s [%s] "%s %s" %d %d "%s" "%s"' %
                (user_name,
                 time.strftime('%d/%b/%Y:%H:%M:%S ', time.localtime(
                     time.time())) + tz_for_log, method, path, self.reply_code,
                 bytes, referer, user_agent))
Ejemplo n.º 7
0
    def continue_request(self, sin, request):
        "continue handling request now that we have the stdin"

        s = get_header(CONTENT_LENGTH, request.header)
        if s:
            s = int(s)
        else:
            s = 0
        DebugLogger.log('I', id(request), s)

        env = self.get_environment(request)
        zresponse = make_response(request, env)
        if self._force_connection_close:
            zresponse._http_connection = 'close'
        zrequest = HTTPRequest(sin, env, zresponse)
        request.channel.current_request = None
        request.channel.queue.append((self.module_name, zrequest, zresponse))
        request.channel.work()
Ejemplo n.º 8
0
    def continue_request(self, sin, request):
        "continue handling request now that we have the stdin"

        s = get_header(CONTENT_LENGTH, request.header)
        if s:
            s = int(s)
        else:
            s = 0
        DebugLogger.log('I', id(request), s)

        env = self.get_environment(request)
        zresponse = make_response(request, env)
        if self._force_connection_close:
            zresponse._http_connection = 'close'
        zrequest = HTTPRequest(sin, env, zresponse)
        request.channel.current_request = None
        request.channel.queue.append((self.module_name, zrequest, zresponse))
        request.channel.work()
Ejemplo n.º 9
0
    def found_terminator(self):
        if self.size is None:
            # read the next size header
            # and prepare to read env or stdin
            self.data.seek(0)
            self.size = string.atoi(self.data.read())
            self.set_terminator(self.size)
            if self.size == 0:

                DebugLogger.log('I', id(self), 0)

                self.set_terminator('\r\n')
                self.data = StringIO()
                self.send_response()
            elif self.size > 1048576:
                self.data = TemporaryFile('w+b')
            else:
                self.data = StringIO()
        elif not self.env:
            # read env
            self.size = None
            self.data.seek(0)
            buff = self.data.read()
            for line in string.split(buff, '\000'):
                try:
                    k, v = string.split(line, '=', 1)
                    self.env[k] = v
                except:
                    pass
            # Hack around broken IIS PATH_INFO
            # maybe, this should go in ZPublisher...
            if 'SERVER_SOFTWARE' in self.env and \
                    string.find(self.env['SERVER_SOFTWARE'],
                                'Microsoft-IIS') != -1:
                script = [
                    _f for _f in string.split(
                        string.strip(self.env['SCRIPT_NAME']), '/') if _f
                ]
                path = [
                    _f for _f in string.split(
                        string.strip(self.env['PATH_INFO']), '/') if _f
                ]
                self.env['PATH_INFO'] = '/' + string.join(
                    path[len(script):], '/')
            self.data = StringIO()

            DebugLogger.log(
                'B', id(self), '%s %s' %
                (self.env['REQUEST_METHOD'], self.env.get('PATH_INFO', '/')))

            # now read the next size header
            self.set_terminator(10)
        else:

            DebugLogger.log('I', id(self), self.terminator)

            # we're done, we've got both env and stdin
            self.set_terminator('\r\n')
            self.data.seek(0)
            self.send_response()
Ejemplo n.º 10
0
    def continue_request(self, sin, request):
        "continue handling request now that we have the stdin"

        s=get_header(CONTENT_LENGTH, request.header)
        if s:
            s=int(s)
        else:
            s=0
        DebugLogger.log('I', id(request), s)
        env=self.get_environment(request)
        path = request.uri.split('?', 1)[0]
        env['PATH_INFO'] += path
        # why not do the above in self.get_environment(request)?
        env['stdin'] = sin
        env['ZServer.medusa.http_server.http_request'] = request
        try:
            channel_pipe = ChannelPipe(request)
            view = self.get_view(env)
            # mini WSGI server:
            result = view(env, channel_pipe.start_response)
            for part in result:
                # XXX: This needs improvement. Basically, we block ZServer
                # iterating through the answer. If it's long, The ZServer will
                # block while the channel gobbles up all the result in memory.
                # Only after all the result has been absorbed will we return
                # control to the medusa thread to actually serve the view.
                # Instead, we should channel.push() a producer for the answer
                # that iterates the result whenever the medusa thread is ready
                # to push more content.
                #
                # For short content, like debug views, this is ok, but if a
                # view tried, for example, to stream a huge file, this would
                # be bad.
                channel_pipe.write(part)
            channel_pipe.close()
            request.channel.current_request=None
        except:
            log.exception("Failure calling view for %r with env:\n%s\n" %
                          (path, env))
            raise
Ejemplo n.º 11
0
    def continue_request(self, sin, request):
        "continue handling request now that we have the stdin"

        s = get_header(CONTENT_LENGTH, request.header)
        if s:
            s = int(s)
        else:
            s = 0
        DebugLogger.log('I', id(request), s)

        env = self.get_environment(request)
        version = request.version
        if version == '1.0' and is_proxying_match(request.request):
            # a request that was made as if this zope was an http 1.0 proxy.
            # that means we have to use some slightly different http
            # headers to manage persistent connections.
            connection_re = proxying_connection_re
        else:
            # a normal http request
            connection_re = CONNECTION

        env['http_connection'] = get_header(connection_re,
                                            request.header).lower()
        env['server_version'] = request.channel.server.SERVER_IDENT

        env['wsgi.output'] = ChannelPipe(request)
        env['wsgi.input'] = sin
        env['wsgi.errors'] = sys.stderr
        env['wsgi.version'] = (1, 0)
        env['wsgi.multithread'] = True
        env['wsgi.multiprocess'] = True
        env['wsgi.run_once'] = True
        env['wsgi.url_scheme'] = env['SERVER_PROTOCOL'].split('/')[0]

        request.channel.current_request = None
        request.channel.queue.append(
            ('Zope2WSGI', env, env['wsgi.output'].start_response))
        request.channel.work()
Ejemplo n.º 12
0
    def continue_request(self, sin, request):
        "continue handling request now that we have the stdin"

        s = get_header(CONTENT_LENGTH, request.header)
        if s:
            s = int(s)
        else:
            s = 0
        DebugLogger.log('I', id(request), s)

        env = self.get_environment(request)
        version = request.version
        if version == '1.0' and is_proxying_match(request.request):
            # a request that was made as if this zope was an http 1.0 proxy.
            # that means we have to use some slightly different http
            # headers to manage persistent connections.
            connection_re = proxying_connection_re
        else:
            # a normal http request
            connection_re = CONNECTION

        env['http_connection'] = get_header(connection_re,
                                            request.header).lower()
        env['server_version'] = request.channel.server.SERVER_IDENT

        env['wsgi.output'] = ChannelPipe(request)
        env['wsgi.input'] = sin
        env['wsgi.errors'] = sys.stderr
        env['wsgi.version'] = (1, 0)
        env['wsgi.multithread'] = True
        env['wsgi.multiprocess'] = True
        env['wsgi.run_once'] = True
        env['wsgi.url_scheme'] = env['SERVER_PROTOCOL'].split('/')[0]

        request.channel.current_request = None
        request.channel.queue.append(('Zope2WSGI', env,
                                      env['wsgi.output'].start_response))
        request.channel.work()
Ejemplo n.º 13
0
    def found_terminator(self):
        # Are we starting a new record?  If so, data is the header.
        if not self.curRec:
            self.curRec = FCGIRecord(self.data.getvalue())
            if self.curRec.needMore():
                self.set_terminator(self.curRec.needMore())
                self.data = StringIO()
                return

        rec = self.curRec

        # If waiting for record content, give it to the record.
        if rec.needContent():
            rec.parseContent(self.data.getvalue())
            if rec.needMore():
                self.set_terminator(rec.needMore())
                self.data = StringIO()
                return

        if rec.needPadding():
            rec.gotPadding()

        # If we get this far without returning, we've got the whole
        # record.  Figure out what to do with it.

        if rec.recType in FCGI_ManagementTypes:
            # Apache mod_fastcgi doesn't send these, but others may
            self.handleManagementTypes(rec)

        elif rec.reqId == 0:
            # It's a management record of unknown type.
            # Complain about it...
            r2 = FCGIRecord()
            r2.recType = FCGI_UNKNOWN_TYPE
            r2.unknownType = rec.recType
            self.push(r2.getRecordAsString(), 0)

        # Since we don't actually have to do anything to ignore the
        # following conditions, they have been commented out and have
        # been left in the code for documentation purposes.

        # Ignore requests that aren't active
        # elif rec.reqId != self.requestId and rec.recType != FCGI_BEGIN_REQUEST:
        #     pass
        #
        # If we're already doing a request, ignore further BEGIN_REQUESTs
        # elif rec.recType == FCGI_BEGIN_REQUEST and self.requestId != 0:
        #     pass

        # Begin a new request
        elif rec.recType == FCGI_BEGIN_REQUEST and self.requestId == 0:
            self.requestId = rec.reqId
            if rec.role == FCGI_AUTHORIZER: self.remainingRecs = 1
            elif rec.role == FCGI_RESPONDER: self.remainingRecs = 2
            elif rec.role == FCGI_FILTER: self.remainingRecs = 3

        # Read some name-value pairs (the CGI environment)
        elif rec.recType == FCGI_PARAMS:
            if rec.contentLength == 0:  # end of the stream

                if self.env.has_key('REQUEST_METHOD'):
                    method = self.env['REQUEST_METHOD']
                else:
                    method = 'GET'
                if self.env.has_key('PATH_INFO'):
                    path = self.env['PATH_INFO']
                else:
                    path = ''
                DebugLogger.log('B', id(self), '%s %s' % (method, path))

                self.remainingRecs = self.remainingRecs - 1
                self.content_length = string.atoi(
                    self.env.get('CONTENT_LENGTH', '0'))
            else:
                self.env.update(rec.values)

        # read some stdin data
        elif rec.recType == FCGI_STDIN:
            if rec.contentLength == 0:  # end of the stream
                self.remainingRecs = self.remainingRecs - 1
            else:
                # see if stdin is getting too big, and
                # replace it with a tempfile if necessary
                if len(rec.content) + self.stdin.tell() > 1048576 and \
                        not self.using_temp_stdin:
                    t = TemporaryFile()
                    t.write(self.stdin.getvalue())
                    self.stdin = t
                    self.using_temp_stdin = 1
                self.stdin.write(rec.content)

        # read some filter data
        elif rec.recType == FCGI_DATA:
            if rec.contentLength == 0:  # end of the stream
                self.remainingRecs = self.remainingRecs - 1
            else:
                self.filterData.write(rec.content)

        # We've processed the record.  Now what do we do?
        if self.remainingRecs > 0:
            # prepare to get the next record
            self.setInitialState()

        else:
            # We've got them all.  Let ZPublisher do its thang.

            DebugLogger.log('I', id(self), self.stdin.tell())

            # But first, fixup the auth header if using newest mod_fastcgi.
            if self.env.has_key('Authorization'):
                self.env['HTTP_AUTHORIZATION'] = self.env['Authorization']
                del self.env['Authorization']

            self.stdin.seek(0)
            self.send_response()
Ejemplo n.º 14
0
    def log_request(self, bytes):
        DebugLogger.log('E', id(self))

        if 'HTTP_USER_AGENT' in self.env:
            user_agent = self.env['HTTP_USER_AGENT']
        else:
            user_agent = ''

        if 'HTTP_REFERER' in self.env:
            referer = self.env['HTTP_REFERER']
        else:
            referer = ''

        if 'PATH_INFO' in self.env:
            path = self.env['PATH_INFO']
        else:
            path = ''

        if 'REQUEST_METHOD' in self.env:
            method = self.env['REQUEST_METHOD']
        else:
            method = "GET"

        user_name = '-'
        if 'HTTP_AUTHORIZATION' in self.env:
            http_authorization = self.env['HTTP_AUTHORIZATION']
            if string.lower(http_authorization[:6]) == 'basic ':
                try:
                    decoded = base64.decodestring(http_authorization[6:])
                except base64.binascii.Error:
                    decoded = ''
                t = string.split(decoded, ':', 1)
                if len(t) >= 2:
                    user_name = t[0]
        if self.addr:
            self.server.logger.log(
                self.addr[0],
                '%s - %s [%s] "%s %s" %d %d "%s" "%s"' % (
                    self.addr[1],
                    user_name,
                    time.strftime(
                        '%d/%b/%Y:%H:%M:%S ',
                        time.localtime(time.time())
                    ) + tz_for_log,
                    method, path, self.reply_code, bytes,
                    referer, user_agent
                )
            )
        else:
            self.server.logger.log(
                '127.0.0.1 ',
                '- %s [%s] "%s %s" %d %d "%s" "%s"' % (
                    user_name,
                    time.strftime(
                        '%d/%b/%Y:%H:%M:%S ',
                        time.localtime(time.time())
                    ) + tz_for_log,
                    method, path, self.reply_code, bytes,
                    referer, user_agent
                )
            )
Ejemplo n.º 15
0
    def found_terminator(self):
        # Are we starting a new record?  If so, data is the header.
        if not self.curRec:
            self.curRec = FCGIRecord(self.data.getvalue())
            if self.curRec.needMore():
                self.set_terminator(self.curRec.needMore())
                self.data = StringIO()
                return

        rec = self.curRec

        # If waiting for record content, give it to the record.
        if rec.needContent():
            rec.parseContent(self.data.getvalue())
            if rec.needMore():
                self.set_terminator(rec.needMore())
                self.data = StringIO()
                return

        if rec.needPadding():
            rec.gotPadding()

        # If we get this far without returning, we've got the whole
        # record.  Figure out what to do with it.

        if rec.recType in FCGI_ManagementTypes:
            # Apache mod_fastcgi doesn't send these, but others may
            self.handleManagementTypes(rec)

        elif rec.reqId == 0:
            # It's a management record of unknown type.
            # Complain about it...
            r2 = FCGIRecord()
            r2.recType = FCGI_UNKNOWN_TYPE
            r2.unknownType = rec.recType
            self.push(r2.getRecordAsString(), 0)

        # Since we don't actually have to do anything to ignore the
        # following conditions, they have been commented out and have
        # been left in the code for documentation purposes.

        # Ignore requests that aren't active
        # elif (rec.reqId != self.requestId and
        #       rec.recType != FCGI_BEGIN_REQUEST):
        #     pass
        #
        # If we're already doing a request, ignore further BEGIN_REQUESTs
        # elif rec.recType == FCGI_BEGIN_REQUEST and self.requestId != 0:
        #     pass

        # Begin a new request
        elif rec.recType == FCGI_BEGIN_REQUEST and self.requestId == 0:
            self.requestId = rec.reqId
            if rec.role == FCGI_AUTHORIZER:
                self.remainingRecs = 1
            elif rec.role == FCGI_RESPONDER:
                self.remainingRecs = 2
            elif rec.role == FCGI_FILTER:
                self.remainingRecs = 3

        # Read some name-value pairs (the CGI environment)
        elif rec.recType == FCGI_PARAMS:
            if rec.contentLength == 0:  # end of the stream

                if 'REQUEST_METHOD' in self.env:
                    method = self.env['REQUEST_METHOD']
                else:
                    method = 'GET'
                if 'PATH_INFO' in self.env:
                    path = self.env['PATH_INFO']
                else:
                    path = ''
                DebugLogger.log('B', id(self), '%s %s' % (method, path))

                self.remainingRecs = self.remainingRecs - 1
                self.content_length = string.atoi(self.env.get(
                    'CONTENT_LENGTH', '0'))
            else:
                self.env.update(rec.values)

        # read some stdin data
        elif rec.recType == FCGI_STDIN:
            if rec.contentLength == 0:  # end of the stream
                self.remainingRecs = self.remainingRecs - 1
            else:
                # see if stdin is getting too big, and
                # replace it with a tempfile if necessary
                if len(rec.content) + self.stdin.tell() > 1048576 and \
                        not self.using_temp_stdin:
                    t = TemporaryFile()
                    t.write(self.stdin.getvalue())
                    self.stdin = t
                    self.using_temp_stdin = 1
                self.stdin.write(rec.content)

        # read some filter data
        elif rec.recType == FCGI_DATA:
            if rec.contentLength == 0:  # end of the stream
                self.remainingRecs = self.remainingRecs - 1
            else:
                self.filterData.write(rec.content)

        # We've processed the record.  Now what do we do?
        if self.remainingRecs > 0:
            # prepare to get the next record
            self.setInitialState()

        else:
            # We've got them all.  Let ZPublisher do its thang.
            DebugLogger.log('I', id(self), self.stdin.tell())

            # But first, fixup the auth header if using newest mod_fastcgi.
            if 'Authorization' in self.env:
                self.env['HTTP_AUTHORIZATION'] = self.env['Authorization']
                del self.env['Authorization']

            self.stdin.seek(0)
            self.send_response()