handlers.py (7535B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\wsgiref\handlers.py 2 from types import StringType 3 from util import FileWrapper, guess_scheme, is_hop_by_hop 4 from headers import Headers 5 import sys, os, time 6 __all__ = ['BaseHandler', 7 'SimpleHandler', 8 'BaseCGIHandler', 9 'CGIHandler'] 10 try: 11 dict 12 except NameError: 13 14 def dict(items): 15 d = {} 16 for k, v in items: 17 d[k] = v 18 19 return d 20 21 22 _weekdayname = ['Mon', 23 'Tue', 24 'Wed', 25 'Thu', 26 'Fri', 27 'Sat', 28 'Sun'] 29 _monthname = [None, 30 'Jan', 31 'Feb', 32 'Mar', 33 'Apr', 34 'May', 35 'Jun', 36 'Jul', 37 'Aug', 38 'Sep', 39 'Oct', 40 'Nov', 41 'Dec'] 42 43 def format_date_time(timestamp): 44 year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp) 45 return '%s, %02d %3s %4d %02d:%02d:%02d GMT' % (_weekdayname[wd], 46 day, 47 _monthname[month], 48 year, 49 hh, 50 mm, 51 ss) 52 53 54 class BaseHandler(): 55 wsgi_version = (1, 0) 56 wsgi_multithread = True 57 wsgi_multiprocess = True 58 wsgi_run_once = False 59 origin_server = True 60 http_version = '1.0' 61 server_software = None 62 os_environ = dict(os.environ.items()) 63 wsgi_file_wrapper = FileWrapper 64 headers_class = Headers 65 traceback_limit = None 66 error_status = '500 Internal Server Error' 67 error_headers = [('Content-Type', 'text/plain')] 68 error_body = 'A server error occurred. Please contact the administrator.' 69 status = result = None 70 headers_sent = False 71 headers = None 72 bytes_sent = 0 73 74 def run(self, application): 75 try: 76 self.setup_environ() 77 self.result = application(self.environ, self.start_response) 78 self.finish_response() 79 except: 80 try: 81 self.handle_error() 82 except: 83 self.close() 84 raise 85 86 def setup_environ(self): 87 env = self.environ = self.os_environ.copy() 88 self.add_cgi_vars() 89 env['wsgi.input'] = self.get_stdin() 90 env['wsgi.errors'] = self.get_stderr() 91 env['wsgi.version'] = self.wsgi_version 92 env['wsgi.run_once'] = self.wsgi_run_once 93 env['wsgi.url_scheme'] = self.get_scheme() 94 env['wsgi.multithread'] = self.wsgi_multithread 95 env['wsgi.multiprocess'] = self.wsgi_multiprocess 96 if self.wsgi_file_wrapper is not None: 97 env['wsgi.file_wrapper'] = self.wsgi_file_wrapper 98 if self.origin_server and self.server_software: 99 env.setdefault('SERVER_SOFTWARE', self.server_software) 100 101 def finish_response(self): 102 if not self.result_is_file() or not self.sendfile(): 103 for data in self.result: 104 self.write(data) 105 106 self.finish_content() 107 self.close() 108 109 def get_scheme(self): 110 return guess_scheme(self.environ) 111 112 def set_content_length(self): 113 try: 114 blocks = len(self.result) 115 except (TypeError, AttributeError, NotImplementedError): 116 pass 117 else: 118 if blocks == 1: 119 self.headers['Content-Length'] = str(self.bytes_sent) 120 return 121 122 def cleanup_headers(self): 123 if 'Content-Length' not in self.headers: 124 self.set_content_length() 125 126 def start_response(self, status, headers, exc_info = None): 127 if exc_info: 128 try: 129 if self.headers_sent: 130 raise exc_info[0], exc_info[1], exc_info[2] 131 finally: 132 exc_info = None 133 134 elif self.headers is not None: 135 raise AssertionError('Headers already set!') 136 self.status = status 137 self.headers = self.headers_class(headers) 138 return self.write 139 140 def send_preamble(self): 141 if self.origin_server: 142 if self.client_is_modern(): 143 self._write('HTTP/%s %s\r\n' % (self.http_version, self.status)) 144 if 'Date' not in self.headers: 145 self._write('Date: %s\r\n' % format_date_time(time.time())) 146 if self.server_software and 'Server' not in self.headers: 147 self._write('Server: %s\r\n' % self.server_software) 148 else: 149 self._write('Status: %s\r\n' % self.status) 150 151 def write(self, data): 152 if not self.status: 153 raise AssertionError('write() before start_response()') 154 elif not self.headers_sent: 155 self.bytes_sent = len(data) 156 self.send_headers() 157 else: 158 self.bytes_sent += len(data) 159 self._write(data) 160 self._flush() 161 162 def sendfile(self): 163 return False 164 165 def finish_content(self): 166 if not self.headers_sent: 167 self.headers['Content-Length'] = '0' 168 self.send_headers() 169 170 def close(self): 171 try: 172 if hasattr(self.result, 'close'): 173 self.result.close() 174 finally: 175 self.result = self.headers = self.status = self.environ = None 176 self.bytes_sent = 0 177 self.headers_sent = False 178 179 def send_headers(self): 180 self.cleanup_headers() 181 self.headers_sent = True 182 if not self.origin_server or self.client_is_modern(): 183 self.send_preamble() 184 self._write(str(self.headers)) 185 186 def result_is_file(self): 187 wrapper = self.wsgi_file_wrapper 188 return wrapper is not None and isinstance(self.result, wrapper) 189 190 def client_is_modern(self): 191 return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9' 192 193 def log_exception(self, exc_info): 194 try: 195 from traceback import print_exception 196 stderr = self.get_stderr() 197 print_exception(exc_info[0], exc_info[1], exc_info[2], self.traceback_limit, stderr) 198 stderr.flush() 199 finally: 200 exc_info = None 201 202 def handle_error(self): 203 self.log_exception(sys.exc_info()) 204 if not self.headers_sent: 205 self.result = self.error_output(self.environ, self.start_response) 206 self.finish_response() 207 208 def error_output(self, environ, start_response): 209 start_response(self.error_status, self.error_headers[:], sys.exc_info()) 210 return [self.error_body] 211 212 def _write(self, data): 213 raise NotImplementedError 214 215 def _flush(self): 216 raise NotImplementedError 217 218 def get_stdin(self): 219 raise NotImplementedError 220 221 def get_stderr(self): 222 raise NotImplementedError 223 224 def add_cgi_vars(self): 225 raise NotImplementedError 226 227 228 class SimpleHandler(BaseHandler): 229 230 def __init__(self, stdin, stdout, stderr, environ, multithread = True, multiprocess = False): 231 self.stdin = stdin 232 self.stdout = stdout 233 self.stderr = stderr 234 self.base_env = environ 235 self.wsgi_multithread = multithread 236 self.wsgi_multiprocess = multiprocess 237 238 def get_stdin(self): 239 return self.stdin 240 241 def get_stderr(self): 242 return self.stderr 243 244 def add_cgi_vars(self): 245 self.environ.update(self.base_env) 246 247 def _write(self, data): 248 self.stdout.write(data) 249 self._write = self.stdout.write 250 251 def _flush(self): 252 self.stdout.flush() 253 self._flush = self.stdout.flush 254 255 256 class BaseCGIHandler(SimpleHandler): 257 origin_server = False 258 259 260 class CGIHandler(BaseCGIHandler): 261 wsgi_run_once = True 262 os_environ = {} 263 264 def __init__(self): 265 BaseCGIHandler.__init__(self, sys.stdin, sys.stdout, sys.stderr, dict(os.environ.items()), multithread=False, multiprocess=True)