Changeset 2504

Show
Ignore:
Timestamp:
01/22/10 22:58:03 (8 weeks ago)
Author:
JensDiemer
Message:
 
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/0.9/scripts/fcgi_scripts/index.fcgi

    r2471 r2504  
    55    PyLucid fastCGI dispatcher 
    66    ~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    7    
     7 
    88    You should check if the shebang is ok for your environment! 
    99        some examples: 
     
    2525    $Author: $ 
    2626 
    27     :copyleft: 2007-2009 by the PyLucid team, see AUTHORS for more details. 
     27    :copyleft: 2007-2010 by the PyLucid team, see AUTHORS for more details. 
    2828    :license: GNU GPL v3 or above, see LICENSE for more details. 
    2929""" 
    3030 
    31 #print "Content-type: text/html; charset=utf-8\r\n\r\nHARDCORE DEBUG:\n" 
    32 #print "Content-type: text/plain; charset=utf-8\r\n\r\nHARDCORE DEBUG:\n" 
    33 #import cgitb;cgitb.enable() 
    3431 
    3532import os 
     33import sys 
     34import time 
     35import traceback 
     36import StringIO 
    3637 
    3738 
    3839##################################################################################################### 
    39 # CHANGE THIS PATH: 
     40# PLEASE CHANGE THIS PATH: 
    4041# 
    41 # The absolute filesystem path to ...PyLucid_env/bin/activate_this.py 
     42os.environ["VIRTUALENV_FILE"] = "please/insert/path/to/PyLucid_env/bin/activate_this.py" 
    4243# 
    43 os.environ["VIRTUALENV_FILE"] = "/path/to/PyLucid_env/bin/activate_this.py" 
     44# It's the absolute filesystem path to ...PyLucid_env/bin/activate_this.py 
    4445# 
    4546##################################################################################################### 
     
    5051 
    5152 
    52 def traceback_end(): 
    53     """ Print out a traceback and terminate with sys.exit() """ 
    54     print 
    55     print "-" * 80 
    56     import sys 
    57     print "Python v%s" % sys.version 
    58     print "-" * 80 
    59     try: 
    60         import traceback 
    61         print traceback.format_exc() 
    62     except Exception, e: 
    63         print "Error: %s" % e 
    64     sys.exit() 
     53# Low level log file. Only created if the fastCGI app can't start. 
     54LOGFILE = "low_level_fcgi.log" 
     55 
     56 
     57def low_level_log(msg): 
     58    """ append >msg< into LOGFILE """ 
     59    try: 
     60        msg = "%s - %s\n" % (time.ctime()[4:-4], msg) 
     61        f = open(LOGFILE, 'a') 
     62        f.write(msg) 
     63        f.close() 
     64        sys.stderr.write(msg) 
     65    except Exception, err: 
     66        sys.stderr.write("Error, creating %r: %s" % (LOGFILE, err)) 
     67 
     68 
     69def tail_log(max=7): 
     70    """ returns the last >max< lines, from LOGFILE """ 
     71    try: 
     72        f = file(LOGFILE, "r") 
     73        seekpos = -80 * max 
     74        try: 
     75            f.seek(seekpos, 2) 
     76        except IOError: # File is to small 
     77            pass 
     78        last_lines = "".join(f.readlines()[-max:]) 
     79        f.close() 
     80        return last_lines 
     81    except: 
     82        return "Error, getting %r content:\n%s" % ( 
     83            LOGFILE, traceback.format_exc() 
     84        ) 
     85 
     86 
     87 
     88 
     89def activate_virtualenv(): 
     90    """ 
     91    Activate the virtualenv by execute the .../bin/activate_this.py 
     92    """ 
     93    try: 
     94        virtualenv_file = os.environ["VIRTUALENV_FILE"]# = "not exist!" 
     95    except KeyError, err: 
     96        etype, evalue, etb = sys.exc_info() 
     97        evalue = etype("environment variable VIRTUALENV_FILE not set!") 
     98        raise etype, evalue, etb 
     99 
     100    try: 
     101        execfile(virtualenv_file, dict(__file__=virtualenv_file)) 
     102    except Exception, err: 
     103        etype, evalue, etb = sys.exc_info() 
     104        evalue = etype( 
     105            ( 
     106                "VIRTUALENV_FILE value is wrong: %r" 
     107                " - Please edit the file %r and change the path!" 
     108            ) % (virtualenv_file, __file__) 
     109        ) 
     110        raise etype, evalue, etb 
     111 
     112 
     113def run_django_cgi(): 
     114    """ 
     115    Try to run the django app via CGI, using wsgiref (exist since Python v2.5) 
     116    returns the raw response content. 
     117    """ 
     118    activate_virtualenv() 
     119 
     120    from wsgiref.handlers import CGIHandler 
     121    from django.core.handlers.wsgi import WSGIHandler 
     122 
     123    os.environ['REQUEST_METHOD'] = "GET" 
     124    os.environ['REMOTE_ADDR'] = "localhost" 
     125    os.environ['SERVER_NAME'] = "low level fastCGI test %r" % __file__ 
     126    os.environ['SERVER_PORT'] = "80" 
     127 
     128    old_stdout = sys.stdout 
     129    old_stderr = sys.stderr 
     130 
     131    buffer = StringIO.StringIO() 
     132    sys.stdout = buffer 
     133    sys.stderr = buffer 
     134    try: 
     135        CGIHandler().run(WSGIHandler()) 
     136        return buffer.getvalue() 
     137    finally: 
     138        sys.stdout = old_stdout 
     139        sys.stderr = old_stderr 
     140        buffer.close() 
     141 
     142 
     143def lowlevel_error_app(environ, start_response): 
     144    """ 
     145    Fallback fastcgi application, used to display the user some information, why the 
     146    main app doesn't start. 
     147    """ 
     148    start_response('200 OK', [('Content-Type', 'text/html')]) 
     149    yield "<h1>PyLucid - Low level error ;( </h1>" 
     150    yield "<p>Python v%s</p>" % sys.version 
     151    from cgi import escape 
     152 
     153    yield "<h3>FastCGI Environment</h3>" 
     154    yield "<table>" 
     155    for k, v in sorted(os.environ.items()): 
     156        yield '<tr><th>%s</th><td>%s</td></tr>' % (escape(k), escape(v)) 
     157    yield "</table>" 
     158 
     159    yield "<h2>Last lines in %s</h2>" % LOGFILE 
     160    yield "<pre>%s</pre>" % tail_log() 
     161 
     162    yield "<h2>Try to run django app with CGI:</h2>" 
     163    yield "<p>(You will see the raw, escaped response content or a traceback!)</p>" 
     164    yield "<pre>" 
     165    try: 
     166        yield escape(run_django_cgi()) 
     167    except: 
     168        yield "Error: %s" % traceback.format_exc() 
     169    yield "</pre>" 
     170 
     171    yield "<p><small>Low level traceback - END</small></p>" 
     172 
     173 
     174def run_django_fcgi(): 
     175    """ 
     176    run the django app with django.core.servers.fastcgi.runfastcgi 
     177    turn flup debug on, if settings.DEBUG is on. 
     178    """ 
     179    activate_virtualenv() 
     180 
     181    try: 
     182        from django.conf import settings 
     183    except: 
     184        etype, evalue, etb = sys.exc_info() 
     185        evalue = etype("Can't import 'settings'!") 
     186        raise etype, evalue, etb 
     187 
     188    try: 
     189        from django.core.handlers.wsgi import WSGIHandler 
     190        from django.core.servers.fastcgi import runfastcgi 
     191    except Exception, err: 
     192        etype, evalue, etb = sys.exc_info() 
     193        evalue = etype("Can't import django stuff: %s" % err) 
     194        raise etype, evalue, etb 
     195 
     196    runfastcgi( 
     197        method="threaded", daemonize="false", 
     198        debug=settings.DEBUG # Enable flup debug 
     199    ) 
    65200 
    66201 
    67202try: 
    68     virtualenv_file = os.environ["VIRTUALENV_FILE"] 
    69 except KeyError, err: 
    70     print "Content-type: text/plain; charset=utf-8\r\n\r\n" 
    71     print "PyLucid - Low-Level-Error!" 
    72     print 
    73     print "environment variable VIRTUALENV_FILE not set!" 
    74     print "(VIRTUALENV_FILE is the path to '.../PyLucid_env/bin/activate_this.py')" 
    75     print 
    76     traceback_end() 
    77  
    78  
    79 try: 
    80     execfile(virtualenv_file, dict(__file__=virtualenv_file)) 
    81 except Exception, err: 
    82     print "Content-type: text/plain; charset=utf-8\r\n\r\n" 
    83     print "PyLucid - Low-Level-Error!" 
    84     print 
    85     print "VIRTUALENV_FILE value is wrong: %r" % virtualenv_file 
    86     print 
    87     print "Please edit the file %r and change the path!" % __file__ 
    88     print 
    89     traceback_end() 
    90  
    91  
    92 try: 
    93     from django.conf import settings 
     203    run_django_fcgi() 
    94204except: 
    95     print "Content-type: text/plain; charset=utf-8\r\n\r\n" 
    96     print "PyLucid - Low-Level-Error!" 
    97     print 
    98     print "Can't import 'settings'!" 
    99     print 
    100     traceback_end() 
    101  
    102  
    103 try: 
    104     from django.core.handlers.wsgi import WSGIHandler 
    105     from django.core.servers.fastcgi import runfastcgi 
    106 except Exception, e: 
    107     print "Content-type: text/plain; charset=utf-8\r\n\r\n" 
    108     print "<h1>Error:</h1><h2>Can't import django stuff:</h2>" 
    109     print "<h3>%s</h3>" % e 
    110     traceback_end() 
    111  
    112  
    113 try: 
    114     #~ runfastcgi() 
    115     runfastcgi(method="threaded", daemonize="false") 
    116     #runfastcgi(socket="fcgi.sock", daemonize="false") 
    117 except Exception, e: 
    118     print "Content-type: text/plain; charset=utf-8\r\n\r\n" 
    119     print "Low-Level-Error:", e 
    120     print 
    121     print "-" * 80 
    122     print 
    123     traceback_end() 
     205    # Catch the traceback and run a minimal fcgi debug application 
     206 
     207    low_level_log(traceback.format_exc()) # Write full traceback into LOGFILE 
     208 
     209    try: 
     210        # http://trac.saddi.com/flup/browser/flup/server/fcgi.py 
     211        from flup.server.fcgi import WSGIServer 
     212        WSGIServer(lowlevel_error_app, debug=True).run() 
     213    except: 
     214        low_level_log( 
     215            "Can't start lowlevel_error_app: %s" % traceback.format_exc() 
     216        ) 
     217 
     218