26
26
#
27
27
28
28
import cgi
29
+ import codecs
29
30
import importlib
30
31
import os
31
32
import sys
35
36
from mig .shared .bailout import bailout_helper , crash_helper , compact_string
36
37
from mig .shared .base import requested_backend , allow_script , \
37
38
is_default_str_coding , force_default_str_coding_rec
39
+ from mig .shared .compat import PY2
38
40
from mig .shared .defaults import download_block_size , default_fs_coding
39
41
from mig .shared .conf import get_configuration_object
40
42
from mig .shared .objecttypes import get_object_type_info
41
43
from mig .shared .output import validate , format_output , dummy_main , reject_main
42
44
from mig .shared .safeinput import valid_backend_name , html_escape , InputException
43
45
from mig .shared .scriptinput import fieldstorage_to_dict
44
46
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
+
45
59
46
60
def object_type_info (object_type ):
47
61
"""Lookup object type"""
48
62
49
63
return get_object_type_info (object_type )
50
64
51
65
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 ):
54
67
"""Run backend on behalf of client_id with supplied user_arguments_dict.
55
68
I.e. import main from import_path and execute it with supplied arguments.
56
69
"""
@@ -61,6 +74,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
61
74
before_time = time .time ()
62
75
63
76
output_objects = []
77
+ backend = 'UNKNOWN'
64
78
main = dummy_main
65
79
66
80
# _logger.debug("stub for backend %r" % backend)
@@ -69,6 +83,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
69
83
# NEVER print/output it verbatim before it is validated below.
70
84
71
85
try :
86
+ backend = requested_backend (environ , fallback = default_page )
72
87
valid_backend_name (backend )
73
88
except InputException as iex :
74
89
_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,
81
96
{'object_type' : 'link' , 'text' : 'Go to default interface' ,
82
97
'destination' : configuration .site_landing_page }
83
98
])
84
- return (output_objects , returnvalues .CLIENT_ERROR )
99
+ return backend , (output_objects , returnvalues .CLIENT_ERROR )
85
100
86
101
try :
87
102
# Import main from backend module
88
103
89
104
# _logger.debug("import main from %r" % import_path)
90
105
# 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 )
93
107
except Exception as err :
94
108
_logger .error ("%s could not import %r (%s): %s" %
95
109
(_addr , backend , import_path , err ))
@@ -100,7 +114,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
100
114
{'object_type' : 'link' , 'text' : 'Go to default interface' ,
101
115
'destination' : configuration .site_landing_page }
102
116
])
103
- return (output_objects , returnvalues .SYSTEM_ERROR )
117
+ return backend , (output_objects , returnvalues .SYSTEM_ERROR )
104
118
105
119
# _logger.debug("imported main %s" % main)
106
120
@@ -115,7 +129,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
115
129
output_objects .append (
116
130
{'object_type' : 'error_text' , 'text' :
117
131
'User input is not on expected format!' })
118
- return (output_objects , returnvalues .INVALID_ARGUMENT )
132
+ return backend , (output_objects , returnvalues .INVALID_ARGUMENT )
119
133
120
134
try :
121
135
(output_objects , (ret_code , ret_msg )) = main (client_id ,
@@ -125,7 +139,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
125
139
_logger .error ("%s script crashed:\n %s" % (_addr ,
126
140
traceback .format_exc ()))
127
141
crash_helper (configuration , backend , output_objects )
128
- return (output_objects , returnvalues .ERROR )
142
+ return backend , (output_objects , returnvalues .ERROR )
129
143
130
144
(val_ret , val_msg ) = validate (output_objects )
131
145
if not val_ret :
@@ -138,7 +152,7 @@ def stub(configuration, client_id, import_path, backend, user_arguments_dict,
138
152
after_time = time .time ()
139
153
output_objects .append ({'object_type' : 'timing_info' , 'text' :
140
154
"done in %.3fs" % (after_time - before_time )})
141
- return (output_objects , (ret_code , ret_msg ))
155
+ return backend , (output_objects , (ret_code , ret_msg ))
142
156
143
157
144
158
def wrap_wsgi_errors (environ , configuration , max_line_len = 100 ):
@@ -198,7 +212,7 @@ def _set_os_environ(value):
198
212
199
213
return _application (environ , start_response , _format_output = format_output , _set_environ = _set_os_environ , _wrap_wsgi_errors = wrap_wsgi_errors )
200
214
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 ):
202
216
203
217
# NOTE: pass app environ including apache and query args on to sub handlers
204
218
# through the usual 'os.environ' channel expected in functionality
@@ -305,7 +319,6 @@ def _application(environ, start_response, _format_output, _set_environ, _wrap_ws
305
319
default_page = configuration .site_landing_page
306
320
script_name = requested_backend (environ , fallback = default_page ,
307
321
strip_ext = False )
308
- backend = requested_backend (environ , fallback = default_page )
309
322
# _logger.debug('DEBUG: wsgi found backend %s and script %s' %
310
323
# (backend, script_name))
311
324
fieldstorage = cgi .FieldStorage (fp = environ ['wsgi.input' ],
@@ -314,13 +327,12 @@ def _application(environ, start_response, _format_output, _set_environ, _wrap_ws
314
327
if 'output_format' in user_arguments_dict :
315
328
output_format = user_arguments_dict ['output_format' ][0 ]
316
329
317
- module_path = 'mig.shared.functionality.%s' % backend
318
330
(allow , msg ) = allow_script (configuration , script_name , client_id )
319
331
if allow :
320
332
# _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 )
324
336
else :
325
337
_logger .warning ("wsgi handling refused script:%s" % script_name )
326
338
(output_objs , ret_val ) = reject_main (client_id ,
@@ -370,7 +382,7 @@ def _application(environ, start_response, _format_output, _set_environ, _wrap_ws
370
382
output_objs .append (wsgi_entry )
371
383
372
384
_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 ,
374
386
output_objs , output_format )
375
387
# _logger.debug("formatted %s output to %s" % (backend, output_format))
376
388
# _logger.debug("output:\n%s" % [output])
@@ -429,7 +441,7 @@ def _application(environ, start_response, _format_output, _set_environ, _wrap_ws
429
441
# (backend, i+1, chunk_parts))
430
442
# end index may be after end of content - but no problem
431
443
part = output [i * download_block_size :(i + 1 )* download_block_size ]
432
- yield part
444
+ yield _ensure_wsgi_chunk ( part )
433
445
if chunk_parts > 1 :
434
446
_logger .info ("WSGI %s finished yielding all %d output parts" %
435
447
(backend , chunk_parts ))
0 commit comments