-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathModSnakeAdapter.py
More file actions
150 lines (112 loc) · 4.46 KB
/
Copy pathModSnakeAdapter.py
File metadata and controls
150 lines (112 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python
"""WebWare for Python adapter for mod_snake.
Gifted to the WebWare project by Jon Travis (jtravis@covalent.net).
mod_snake is a plugin for Apache which allows modules to be written
in Python, and have the same power as C modules. In addition it
accelerates Python written CGI, similar to Py_Apache and mod_python
and includes support for HTML with embedded Python.
You can download mod_snake at: http://sourceforge.net/projects/modsnake
Usage:
Add the following lines to your httpd.conf file:
-- Snip here --
SnakeModuleDir /path/to/Webware
SnakeModuleDir /path/to/Webware/WebKit
SnakeModule ModSnakeAdapter.ModSnakeAdapter
WebwareAddress /path/to/Webware/WebKit/adapter.address
AddHandler webware .psp
<Location /wpy>
SetHandler webware
</Location>
-- Snip here --
Using the above configuration will tag all .psp files for processing
by the Webware handler. All files in the /wpy location will also be
given the same handler.
To change the chunk size that the mod_snake adaptor uses for reading
and writing data, simply add the directive:
WebwareChunkSize 69
(or whatever your new chunksize is)
"""
import mod_snake
import os
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
# Keys into the server-config dictionary
PER_SVR_SERVER = 0 # server_rec
PER_SVR_PORT = 1 # Port from webware address file
PER_SVR_ADDRESS = 2 # Address from webware address file
PER_SVR_CHUNKSIZE = 3 # Size of chunks to read and write
DEFAULT_CHUNKSIZE = 32 * 1024
from WebKit.Adapters.Adapter import Adapter
class ModSnakeAdapter(Adapter):
def __init__(self, module):
hooks = dict(
create_svr_config = self.create_svr_config,
content_handler = self.content_handler,
)
for hook in hooks:
module.add_hook(hook, hooks[hook])
directives = dict(
WebwareAddress = (mod_snake.RSRC_CONF,mod_snake.TAKE1,
self.cmd_WebwareAddress),
WebwareChunkSize = (mod_snake.RSRC_CONF,mod_snake.TAKE1,
self.cmd_WebwareChunkSize),
)
module.add_directives(directives)
Adapter.__init__(self, '')
def create_svr_config(self, server):
return {
PER_SVR_SERVER: server,
PER_SVR_PORT: '8086',
PER_SVR_ADDRESS: 'localhost',
PER_SVR_CHUNKSIZE: DEFAULT_CHUNKSIZE,
}
def cmd_WebwareChunkSize(self, per_dir, per_svr, chunksize):
chunksize = int(chunksize)
if chunksize <= 0:
return "chunksize must be > 0"
per_svr[PER_SVR_CHUNKSIZE] = int(chunksize)
def cmd_WebwareAddress(self, per_dir, per_svr, file):
host, port = open(file).read().split(':')
per_svr[PER_SVR_PORT] = int(port)
per_svr[PER_SVR_ADDRESS] = host
self._webKitDir = os.path.dirname(file)
def content_handler(self, per_dir, per_svr, request):
if request.handler != 'webware':
return mod_snake.DECLINED
res = request.setup_client_block(mod_snake.REQUEST_CHUNKED_ERROR)
if res:
raise IOError("Failed to setup client blocking method")
request.should_client_block()
strdata = StringIO()
while 1:
data, err = request.get_client_block(per_svr[PER_SVR_CHUNKSIZE])
if err <= 0:
break
strdata.write(data)
# Setup the subprocess environment, because os.environ suxx0r3z
request.add_common_vars()
request.add_cgi_vars()
env = {}
for key, val in request.subprocess_env.items():
env[key] = val
env["GATEWAY_INTERFACE"] = mod_snake.get_version()
response = self.transactWithAppServer(env, strdata.getvalue(),
per_svr[PER_SVR_ADDRESS], per_svr[PER_SVR_PORT])
self.respond( request, response)
return mod_snake.OK
def respond(self, req, respdict):
headerend = respdict.find("\n\n")
headers = respdict[:headerend]
for header in headers.split("\n"):
header = header.split(":")
field = header[0]
req.headers_out[field] = ":".join(header[1:])
field = field.lower()
if field == 'content-type':
req.content_type = header[1]
elif field == 'status':
req.status = int(header[1].lstrip().split(None, 1)[0])
req.send_http_header()
req.rwrite(respdict[headerend+2:])