ModPythonAdapter.py :  » Web-Frameworks » Webware » Webware-1.0.2 » WebKit » Adapters » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Frameworks » Webware 
Webware » Webware 1.0.2 » WebKit » Adapters » ModPythonAdapter.py
###########################################
# mod_python adapter for WebKit
#
#
# Contributed by: Dave Wallace
# Modified by Jay Love and Geoff Talvola
#
##########################################

"""
Here's how I set up my Apache conf:

<Location /WK >
   SetHandler python-program
   # add the directory that contains ModPythonAdapter.py
   PythonPath "sys.path+['/path/to/WebKit']"
   PythonOption AppWorkDir /path/to/dir/with/adapter.address
   PythonHandler WebKit.Adapters.ModPythonAdapter
   PythonDebug On
</Location>

If you used the MakeAppWorkDir.py script to make a seperate
application working directory, specify that path for the AppWorkDir
option, otherwise it should be in your WebKit directory in which case
you should use /path/to/WebKit/adapter.address

http://localhost/WK/Welcome


You may also send all requests with a .psp extension to WebKit by adding these lines, outside
of any location or directory.

AddHandler python-program .psp
PythonPath "sys.path+['/path/to/WebKit']"
PythonHandler modpHandler::pspHandler
PythonOption AppWorkDir /path/to/dir/with/adapter.address
"""

# Fix the current working directory -- this gets initialized incorrectly
# for some reason when run using mod_python.
import os
try:
  os.chdir(os.path.abspath(os.path.dirname(__file__)))
except Exception:
  pass

from mod_python import apache
import time

from socket import *
import sys

from Adapter import Adapter

debug = 0
__adapter = None
bufsize = 32*1024


class ModPythonAdapter(Adapter):
  def __init__(self, host, port, webkitdir):
    Adapter.__init__(self, webkitdir)
    self.host = host
    self.port = port

  def handler(self, req):
    self.reset(req)
    try:
      # Get input
      myInput = self.input(req)

      # get the apache module to do the grunt work of
      # building the environment
      env=apache.build_cgi_env(req)

      #make sure env is a dictionary (may not be for Apache2)
      env=dict(env)

      # Fix up the path
      if not env.has_key('PATH_INFO'): env['PATH_INFO']=req.path_info

      # Communicate with the app server
      respdict = self.transactWithAppServer(env, myInput, self.host, self.port)

      # Respond back to Apache
      # self.respond(req, respdict)

    except:
      self.handleException(req)
    return apache.OK


  def pspHandler(self, req):
    self.reset(req)
    try:
      # Get input
      myInput = self.input(req)

      # get the apache module to do the grunt work of
      #   building the environment
      env=apache.build_cgi_env(req)

      #make sure env is a dictionary (may not be for Apache2)
      env=dict(env)

      # Special environment setup needed for psp handler
      env['WK_ABSOLUTE']=1

      # Fix up the path
      if not env.has_key('PATH_INFO'): env['PATH_INFO']=req.path_info

      # Communicate with the app server
      respdict = self.transactWithAppServer(env, myInput, self.host, self.port)

      # Respond back to Apache
      self.respond(req, respdict)

    except:
      self.handleException(req)
    return apache.OK


  def typehandler(self, req):
    """ Not being used yet.
    Probably never be used, b/c the req.handler field is read only in mod_python.
    """
    self.reset(req)
    debug=1
    if debug:
      ot = open("/tmp/log2.txt","a")
      ot.write("In Type Handler\n")
      ot.flush()

    if req.filename is None:
      return apache.DECLINED
    fn = req.filename
    if debug:
      ot.write("TH: Filename: %s\n"%fn)
    ext = fn[fn.rfind("."):]
    if debug:
      ot.write("TH: Extension: %s\n"%ext)

    if debug:
      ot.write("Req_Handler = %s\n"%req.handler)
      ot.flush()
      ot.close()

    if ext == ".psp":
      req.handler = "python-program"
      return apache.OK
    else:
      return apache.DECLINED


  def input(self, req):
    myInput = ''
    inp = req.read(bufsize)
    # this looks like bad performance if we don't get it all
    #  in the first buffer
    while inp:
      myInput = myInput + inp
      inp = req.read(bufsize)
    return myInput


  def processResponse(self, data):
    req = self.request()
    if self.doneHeader():
      req.write(data)
      return
    headerData = self.headerData() + data
    self.setHeaderData(headerData)
    headerend = headerData.find("\r\n\r\n")
    if headerend < 0:
      return
    headers = headerData[:headerend]
    for header in headers.split("\r\n"):
      colon = header.find(':')
      name = header[:colon]
      value = header[colon+1:]
      req.headers_out.add(name, value)
      if name.lower() == 'content-type':
        req.content_type = value
      if name.lower() == 'status':
        req.status = int(value.lstrip().split(' ', 1)[0])
    req.send_http_header()
    req.write(headerData[headerend+4:])
    self.setDoneHeader(1)

  def handleException(self, req):
    import traceback

    apache.log_error('WebKit mod_python: Error while responding to request\n')
    apache.log_error('Python exception:\n')
    traceback.print_exc(file=sys.stderr)

    output = traceback.format_exception(*sys.exc_info())
    output = ''.join(output)
    output = output.replace('&', '&amp;'
      ).replace('<', '&lt;').replace('>', '&gt;')
    req.write('''
<html><body>
<p><pre>ERROR

%s</pre>
</body></html>\n''' % output)


  def reset(self, request):
    self.setDoneHeader(0)
    self.setHeaderData('')
    self.setRequest(request)

  # These methods are non-thread-safe.  On platforms like NT where Apache runs multi-threaded,
  # and the same ModPythonAdapter instance may be called simultaneously for different requests,
  # they need to replaced with threadsafe versions.  See WinModPythonAdapter below.
  def doneHeader(self):
    return self._doneHeader
  def setDoneHeader(self, doneHeader):
    self._doneHeader = doneHeader
  def headerData(self):
    return self._headerData
  def setHeaderData(self, headerData):
    self._headerData = headerData
  def request(self):
    return self._request
  def setRequest(self, request):
    self._request = request


# NT-specific, thread-safe version of ModPythonAdapter.  Requires Win32 extensions.
if os.name == 'nt':
  import win32api

  # This is a Windows-specific thread-safe version of ModPythonAdapter.  It replaces the
  # non-thread-safe [set]doneHeader, [set]headerData, and [set]request with versions
  # that store the information keyed by thread ID.
  #
  # This seems a bit hokey, but it was easy to write and it works.
  OriginalModPythonAdapter = ModPythonAdapter
  class WinModPythonAdapter(OriginalModPythonAdapter):
    def __init__(self, host, port, webkitdir):
      OriginalModPythonAdapter.__init__(self, host, port, webkitdir)
      self._threadSafeStorage = {}

    def threadSafeValue(self, name):
      threadID = win32api.GetCurrentThreadId()
      return self._threadSafeStorage[threadID, name]
    def setThreadSafeValue(self, name, value):
      threadID = win32api.GetCurrentThreadId()
      self._threadSafeStorage[threadID, name] = value

    def doneHeader(self):
      return self.threadSafeValue('doneHeader')
    def setDoneHeader(self, doneHeader):
      self.setThreadSafeValue('doneHeader', doneHeader)
    def headerData(self):
      return self.threadSafeValue('headerData')
    def setHeaderData(self, headerData):
      self.setThreadSafeValue('headerData', headerData)
    def request(self):
      return self.threadSafeValue('request')
    def setRequest(self, request):
      self.setThreadSafeValue('request', request)

  # Replace ModPythonAdapter with the Windows-safe version.
  ModPythonAdapter = WinModPythonAdapter


def _adapter(req):
  global __adapter
  if __adapter is None:
    appWorkDir = req.get_options()['AppWorkDir']
    WEBWARE_ADDRESS_FILE = os.path.join(appWorkDir, 'adapter.address')
    host, port = open(WEBWARE_ADDRESS_FILE).read().split(':')
    port = int(port)
    __adapter = ModPythonAdapter(host, port, appWorkDir)
  return __adapter


def handler(req):
  return _adapter(req).handler(req)

def pspHandler(req):
  return _adapter(req).pspHandler(req)

def typehandler(req):
  return _adapter(req).typehandler(req)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.