Skip to content

Commit 5b37c7e

Browse files
committed
wip
1 parent 0ced25d commit 5b37c7e

File tree

2 files changed

+38
-20
lines changed

2 files changed

+38
-20
lines changed

mig/wsgi-bin/migwsgi.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#
2727

2828
import cgi
29+
import codecs
2930
import importlib
3031
import os
3132
import sys
@@ -35,22 +36,34 @@
3536
from mig.shared.bailout import bailout_helper, crash_helper, compact_string
3637
from mig.shared.base import requested_backend, allow_script, \
3738
is_default_str_coding, force_default_str_coding_rec
39+
from mig.shared.compat import PY2
3840
from mig.shared.defaults import download_block_size, default_fs_coding
3941
from mig.shared.conf import get_configuration_object
4042
from mig.shared.objecttypes import get_object_type_info
4143
from mig.shared.output import validate, format_output, dummy_main, reject_main
4244
from mig.shared.safeinput import valid_backend_name, html_escape, InputException
4345
from mig.shared.scriptinput import fieldstorage_to_dict
4446

47+
if PY2:
48+
pass
49+
else:
50+
def _ensure_wsgi_chunk(chunk):
51+
return codecs.encode(chunk, 'utf8')
52+
53+
54+
def _import_backend(backend):
55+
import_path = 'mig.shared.functionality.%s' % backend
56+
module_handle = importlib.import_module(import_path)
57+
return module_handle.main
58+
4559

4660
def object_type_info(object_type):
4761
"""Lookup object type"""
4862

4963
return get_object_type_info(object_type)
5064

5165

52-
def stub(configuration, client_id, import_path, backend, user_arguments_dict,
53-
environ):
66+
def stub(configuration, client_id, user_arguments_dict, environ, _retrieve_handler):
5467
"""Run backend on behalf of client_id with supplied user_arguments_dict.
5568
I.e. import main from import_path and execute it with supplied arguments.
5669
"""
@@ -61,6 +74,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
6174
before_time = time.time()
6275

6376
output_objects = []
77+
backend = 'UNKNOWN'
6478
main = dummy_main
6579

6680
# _logger.debug("stub for backend %r" % backend)
@@ -69,6 +83,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
6983
# NEVER print/output it verbatim before it is validated below.
7084

7185
try:
86+
backend = requested_backend(environ, fallback=default_page)
7287
valid_backend_name(backend)
7388
except InputException as iex:
7489
_logger.error("%s refused to import invalid backend %r (%s): %s" %
@@ -81,15 +96,14 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
8196
{'object_type': 'link', 'text': 'Go to default interface',
8297
'destination': configuration.site_landing_page}
8398
])
84-
return (output_objects, returnvalues.CLIENT_ERROR)
99+
return backend, (output_objects, returnvalues.CLIENT_ERROR)
85100

86101
try:
87102
# Import main from backend module
88103

89104
# _logger.debug("import main from %r" % import_path)
90105
# NOTE: dynamic module loading to find corresponding main function
91-
module_handle = importlib.import_module(import_path)
92-
main = module_handle.main
106+
main = _retrieve_handler(backend)
93107
except Exception as err:
94108
_logger.error("%s could not import %r (%s): %s" %
95109
(_addr, backend, import_path, err))
@@ -100,7 +114,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
100114
{'object_type': 'link', 'text': 'Go to default interface',
101115
'destination': configuration.site_landing_page}
102116
])
103-
return (output_objects, returnvalues.SYSTEM_ERROR)
117+
return backend, (output_objects, returnvalues.SYSTEM_ERROR)
104118

105119
# _logger.debug("imported main %s" % main)
106120

@@ -115,7 +129,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
115129
output_objects.append(
116130
{'object_type': 'error_text', 'text':
117131
'User input is not on expected format!'})
118-
return (output_objects, returnvalues.INVALID_ARGUMENT)
132+
return backend, (output_objects, returnvalues.INVALID_ARGUMENT)
119133

120134
try:
121135
(output_objects, (ret_code, ret_msg)) = main(client_id,
@@ -125,7 +139,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
125139
_logger.error("%s script crashed:\n%s" % (_addr,
126140
traceback.format_exc()))
127141
crash_helper(configuration, backend, output_objects)
128-
return (output_objects, returnvalues.ERROR)
142+
return backend, (output_objects, returnvalues.ERROR)
129143

130144
(val_ret, val_msg) = validate(output_objects)
131145
if not val_ret:
@@ -138,7 +152,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
138152
after_time = time.time()
139153
output_objects.append({'object_type': 'timing_info', 'text':
140154
"done in %.3fs" % (after_time - before_time)})
141-
return (output_objects, (ret_code, ret_msg))
155+
return backend, (output_objects, (ret_code, ret_msg))
142156

143157

144158
def wrap_wsgi_errors(environ, configuration, max_line_len=100):
@@ -198,7 +212,7 @@ def _set_os_environ(value):
198212

199213
return _application(environ, start_response, _format_output=format_output, _set_environ=_set_os_environ, _wrap_wsgi_errors=wrap_wsgi_errors)
200214

201-
def _application(environ, start_response, _format_output, _set_environ, _wrap_wsgi_errors=True, _config_file=None, _skip_log=False):
215+
def _application(environ, start_response, _format_output, _set_environ, _retrieve_handler=_import_backend, _wrap_wsgi_errors=True, _config_file=None, _skip_log=False):
202216

203217
# NOTE: pass app environ including apache and query args on to sub handlers
204218
# through the usual 'os.environ' channel expected in functionality
@@ -305,7 +319,6 @@ def _application(environ, start_response, _format_output, _set_environ, _wrap_ws
305319
default_page = configuration.site_landing_page
306320
script_name = requested_backend(environ, fallback=default_page,
307321
strip_ext=False)
308-
backend = requested_backend(environ, fallback=default_page)
309322
# _logger.debug('DEBUG: wsgi found backend %s and script %s' %
310323
# (backend, script_name))
311324
fieldstorage = cgi.FieldStorage(fp=environ['wsgi.input'],
@@ -314,13 +327,12 @@ def _application(environ, start_response, _format_output, _set_environ, _wrap_ws
314327
if 'output_format' in user_arguments_dict:
315328
output_format = user_arguments_dict['output_format'][0]
316329

317-
module_path = 'mig.shared.functionality.%s' % backend
318330
(allow, msg) = allow_script(configuration, script_name, client_id)
319331
if allow:
320332
# _logger.debug("wsgi handling script: %s" % script_name)
321-
(output_objs, ret_val) = stub(configuration, client_id,
322-
module_path, backend,
323-
user_arguments_dict, environ)
333+
backend, (output_objs, ret_val) = stub(configuration, client_id,
334+
user_arguments_dict, environ,
335+
_retrieve_handler)
324336
else:
325337
_logger.warning("wsgi handling refused script:%s" % script_name)
326338
(output_objs, ret_val) = reject_main(client_id,
@@ -370,7 +382,7 @@ def _application(environ, start_response, _format_output, _set_environ, _wrap_ws
370382
output_objs.append(wsgi_entry)
371383

372384
_logger.debug("call format %r output to %s" % (backend, output_format))
373-
output = _format_output(configuration, backend, ret_code, ret_msg,
385+
output = format_output(configuration, backend, ret_code, ret_msg,
374386
output_objs, output_format)
375387
# _logger.debug("formatted %s output to %s" % (backend, output_format))
376388
# _logger.debug("output:\n%s" % [output])
@@ -429,7 +441,7 @@ def _application(environ, start_response, _format_output, _set_environ, _wrap_ws
429441
# (backend, i+1, chunk_parts))
430442
# end index may be after end of content - but no problem
431443
part = output[i*download_block_size:(i+1)*download_block_size]
432-
yield part
444+
yield _ensure_wsgi_chunk(part)
433445
if chunk_parts > 1:
434446
_logger.info("WSGI %s finished yielding all %d output parts" %
435447
(backend, chunk_parts))

tests/test_mig_wsgi-bin_migwsgi.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ def test_format_output(*args):
4040
return arranged
4141
return test_format_output
4242

43-
def create_wsgi_environ(config_file, env_http_host=None, env_path_info=None):
43+
def create_wsgi_environ(config_file, wsgi_input=None, env_http_host=None, env_path_info=None):
4444
environ = {}
45+
environ['wsgi.input'] = ()
4546
environ['MIG_CONF'] = config_file
4647
environ['HTTP_HOST'] = env_http_host
4748
environ['PATH_INFO'] = env_path_info
@@ -106,6 +107,9 @@ def test_xxx(self):
106107
config = _assert_local_config()
107108
config_global_values = _assert_local_config_global_values(config)
108109

110+
def fake_handler(*args):
111+
pass
112+
109113
def fake_start_response(status, headers, exc=None):
110114
fake_start_response.calls.append((status, headers, exc))
111115
fake_start_response.calls = []
@@ -120,19 +124,21 @@ def fake_set_environ(value):
120124
env_path_info='/'
121125
)
122126

123-
test_output_returner = create_output_returner(b'')
127+
test_output_returner = create_output_returner('HELLO WORLD')
124128

125129
yielder = migwsgi._application(wsgi_environ, fake_start_response,
126130
_format_output=test_output_returner,
127131
_set_environ=fake_set_environ,
132+
_retrieve_handler=lambda _: fake_handler,
128133
_wrap_wsgi_errors=noop,
129134
_config_file=_TEST_CONF_FILE,
130135
_skip_log=True,
131136
)
132137
chunks = list(yielder)
133138

134139
self.assertGreater(len(chunks), 0)
135-
140+
import codecs
141+
print(codecs.decode(chunks[0], 'utf8'))
136142

137143

138144
if __name__ == '__main__':

0 commit comments

Comments
 (0)