Beispiel #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():
            self.channel.push(ShutdownProducer(), 0)
            Wakeup(lambda: asyncore.close_all())
        else:
            self.channel.push(None,0)
            Wakeup()
        self.channel=None
    def close(self):
        DebugLogger.log('A', id(self._request),
                '%s %s' % (self._request.reply_code, self._bytes))
        if not self._channel.closed:
            self._channel.push(LoggingProducer(self._request, self._bytes), 0)
            self._channel.push(CallbackProducer(self._channel.done), 0)
            self._channel.push(CallbackProducer(
                lambda t=('E', id(self._request)): apply(DebugLogger.log, t)), 0)
            if self._shutdown:
                self._channel.push(ShutdownProducer(), 0)
                Wakeup()
            else:
                if self._close: self._channel.push(None, 0)
            Wakeup()
        else:
            # channel closed too soon

            self._request.log(self._bytes)
            DebugLogger.log('E', id(self._request))

            if self._shutdown:
                Wakeup(lambda: asyncore.close_all())
            else:
                Wakeup()

        self._channel=None #need to break cycles?
        self._request=None
Beispiel #3
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)): apply(
                    DebugLogger.log, t)), 0)

            if self._shutdown:
                try:
                    r = self._shutdown[0]
                except:
                    r = 0
                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
Beispiel #4
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():
            self.channel.push(ShutdownProducer(), 0)
            Wakeup(lambda: asyncore.close_all())
        else:
            self.channel.push(None,0)
            Wakeup()
        self.channel=None
Beispiel #5
0
    def close(self):
        DebugLogger.log('A', id(self._request),
                        '%s %s' % (self._request.reply_code, self._bytes))
        if not self._channel.closed:
            self._channel.push(LoggingProducer(self._request, self._bytes), 0)
            self._channel.push(CallbackProducer(self._channel.done), 0)
            self._channel.push(
                CallbackProducer(lambda t=('E', id(self._request)): apply(
                    DebugLogger.log, t)), 0)
            if self._shutdown:
                self._channel.push(ShutdownProducer(), 0)
                Wakeup()
            else:
                if self._close: self._channel.push(None, 0)
            Wakeup()
        else:
            # channel closed too soon

            self._request.log(self._bytes)
            DebugLogger.log('E', id(self._request))

            if self._shutdown:
                Wakeup(lambda: asyncore.close_all())
            else:
                Wakeup()

        self._channel = None  #need to break cycles?
        self._request = None
Beispiel #6
0
    def log_request(self, bytes):

        DebugLogger.log('E', id(self))

        if self.env.has_key('HTTP_USER_AGENT'):
            user_agent=self.env['HTTP_USER_AGENT']
        else:
            user_agent=''
        if self.env.has_key('HTTP_REFERER'):
            referer=self.env['HTTP_REFERER']
        else:
            referer=''

        if self.env.has_key('PATH_INFO'):
            path=self.env['PATH_INFO']
        else:
            path=''
        if self.env.has_key('REQUEST_METHOD'):
            method=self.env['REQUEST_METHOD']
        else:
            method="GET"
        user_name = '-'
        if self.env.has_key('HTTP_AUTHORIZATION'):
            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
                    )
                )
Beispiel #7
0
    def log_request(self, bytes):

        DebugLogger.log('E', id(self))

        if self.env.has_key('HTTP_USER_AGENT'):
            user_agent=self.env['HTTP_USER_AGENT']
        else:
            user_agent=''
        if self.env.has_key('HTTP_REFERER'):
            referer=self.env['HTTP_REFERER']
        else:
            referer=''

        if self.env.has_key('PATH_INFO'):
            path=self.env['PATH_INFO']
        else:
            path=''
        if self.env.has_key('REQUEST_METHOD'):
            method=self.env['REQUEST_METHOD']
        else:
            method="GET"
        user_name = '-'
        if self.env.has_key('HTTP_AUTHORIZATION'):
            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
                    )
                )
Beispiel #8
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)
Beispiel #9
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()
    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)): apply(DebugLogger.log,t)), 0)

            if self._shutdown:
                try: r=self._shutdown[0]
                except: r=0
                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
Beispiel #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()
Beispiel #12
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 self.env.has_key('SERVER_SOFTWARE') and \
                    string.find(self.env['SERVER_SOFTWARE'],
                    'Microsoft-IIS') != -1:
                script = filter(
                    None,
                    string.split(string.strip(self.env['SCRIPT_NAME']), '/'))
                path = filter(
                    None, string.split(string.strip(self.env['PATH_INFO']),
                                       '/'))
                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()
    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 self.env.has_key('SERVER_SOFTWARE') and \
                    string.find(self.env['SERVER_SOFTWARE'],
                    'Microsoft-IIS') != -1:
                script = filter(None,string.split(
                        string.strip(self.env['SCRIPT_NAME']),'/'))
                path = filter(None,string.split(
                        string.strip(self.env['PATH_INFO']),'/'))
                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()
Beispiel #14
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()
Beispiel #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 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()