My favorites | Sign in
Project Logo
                
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
"""
cogen.web.wsgi server is asynchronous by default.
If you need to run a app that uses wsgi.input synchronously you need to wrapp
it in :class:`SynchronousInputMiddleware`.

"""
__all__ = [
'LazyStartResponseMiddleware', 'SynchronousInputMiddleware'
]


try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO

class COGENOperationWrapper(object):
def __init__(self, gate, module):
self.module = module
self.gate = gate

def __getattr__(self, key):
#~ if callable(self.module):
#~ return COGENOperationCall(self.gate, self.module)
what = getattr(self.module, key)
if callable(what):
return COGENOperationCall(self.gate, what)
else:
return self.__class__(self.gate, what)
class COGENCallWrapper(object):
def __init__(self, gate):
self.gate = gate

def __call__(self, obj):
return COGENOperationCall(self.gate, obj)

class COGENSimpleWrapper(object):
def __init__(self, gate):
self.gate = gate

def __call__(self, obj):
self.gate.operation = obj

class COGENOperationCall(object):
def __init__(self, gate, obj):
self.gate = gate
self.obj = obj

def __call__(self, *args, **kwargs):
self.gate.operation = self.obj(*args, **kwargs)
return ""
class COGENProxy(object):
__slots__ = (
'content_length', 'read_count', 'operation', 'result', 'exception'
)

def __init__(self, content_length=None, read_count=None, operation=None, result=None, exception=None):
self.content_length = content_length
self.read_count = read_count
self.operation = operation
self.result = result
self.exception = exception

def __str__(self):
return repr(self.__dict__)

class LazyStartResponseMiddleware:
"""This is a evil piece of middleware that proxyes the start_response
call and delays it till the appiter yields a non-empty string.
Also, this returns a fake write callable that buffers the strings passed
though it. Use at your own peril :)
"""
def __init__(self, app, global_conf={}):
self.app = app
self.sr_called = False

def start_response(self, status, headers, exc=None):
self.sr_called = True
self.status = status
self.headers = headers
self.exc = exc
self.out = StringIO()
return self.out.write

def __call__(self, environ, start_response):
started = False
app_iter = self.app(environ, self.start_response)
for chunk in app_iter:
if not started and self.sr_called and chunk:
started = True
write = start_response(self.status, self.headers, self.exc)
out = self.out.getvalue()
if out:
write(out)
yield chunk
if not started and self.sr_called:
start_response(self.status, self.headers, self.exc)
lazy_sr = LazyStartResponseMiddleware

class SynchronousInputMiddleware:
"""Middleware for providing a regular synchronous wsgi.input to the app.
Note that it reads the whole input in memory so you sould rather use the
async input (environ['cogen.input']) for large requests.
"""
def __init__(self, app, global_conf={}, buffer_length=1024):
self.app = app
self.buffer_length = int(buffer_length)

def __call__(self, environ, start_response):
buff = StringIO()
remaining = content_length = environ['cogen.wsgi'].content_length or 0
while remaining:
yield environ['cogen.input'].read(min(remaining, self.buffer_length))
result = environ['cogen.wsgi'].result
if isinstance(result, Exception):
import traceback
traceback.print_exception(*environ['cogen.wsgi'].exception)
break
else:
if not result:
break
buff.write(result)
remaining -= len(result)
buff.seek(0)
environ['wsgi.input'] = buff
environ['CONTENT_LENGTH'] = str(content_length)
iterator = self.app(environ, start_response)
for i in iterator:
yield i
if hasattr(iterator, 'close'):
iterator.close()

sync_input = SynchronousInputMiddleware

Show details Hide details

Change log

r588 by ionel.mc on Apr 26, 2009   Diff
Removed trailing spaces. Fixed
inconsistent end of line format.

Merged from amcnabb8's branch.
Go to: 
Project members, sign in to write a code review

Older revisions

r556 by ionel.mc on Jan 03, 2009   Diff
some cleanup like remove useless
imports and a couple of relics of old
past
r555 by ionel.mc on Jan 01, 2009   Diff
docs update
r530 by ionel.mc on Dec 24, 2008   Diff
removing the apydia docs generator and
replacing it with sphinx; tweaked the
docstrings in some modules.
All revisions of this file

File info

Size: 4552 bytes, 134 lines
Hosted by Google Code