httputils.py (20096B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\scriber\httputils.py 2 from __future__ import print_function 3 import datetime as pydt 4 import urllib 5 import urlparse 6 import pprint 7 import typeutils 8 import datetimeutils 9 from scriber import const 10 import logging 11 log = logging.getLogger('scriber') 12 13 class Url(object): 14 15 def __init__(self, full_url): 16 self.raw = full_url 17 self.scheme = '' 18 self.auth_user = '' 19 self.auth_pass = '' 20 self.host = '' 21 self.port = 0 22 self.path = '' 23 self.query_string = '' 24 self.fragment_id = '' 25 self.path_list = [] 26 self.file = '' 27 self.file_ext = '' 28 self.file_path = '' 29 self._parse() 30 31 def _parse(self): 32 if self.raw: 33 match = const.URL_MATCHER.match(self.raw) 34 if match: 35 d = match.groupdict() 36 self.scheme = d.get('scheme', '') 37 self.host = d.get('host', '') 38 self.path = d.get('path', '') 39 self.query_string = d.get('querystr', '') 40 self.fragment_id = d.get('fragment', '') 41 if self.host: 42 match = const.HOST_MATCHER.match(self.host) 43 if match: 44 d = match.groupdict() 45 self.auth_user = d.get('user', '') 46 self.auth_pass = d.get('pass', '') 47 self.host = d.get('host', '') 48 self.port = typeutils.int_eval(d.get('port', None), 80) 49 if self.path: 50 self.path_list = self.path.split('/') 51 self.file_path = self.path_list[:-1] 52 self.file = self.path_list[-1] 53 if self.file: 54 self.file_ext = self.file.split('.')[-1] 55 56 def __str__(self): 57 return self.raw 58 59 def __repr__(self): 60 buff = [] 61 if self.scheme: 62 buff.append('[schema=%s]' % self.scheme) 63 buff.append('//') 64 if self.auth_user: 65 buff.append('[user=%s]' % self.auth_user) 66 if self.auth_pass: 67 buff.append(':[pass=***]') 68 buff.append('@') 69 if self.host: 70 buff.append('[host=%s]' % self.host) 71 if self.port: 72 buff.append(':[port=%s]' % self.port) 73 buff.append('/') 74 if self.path: 75 buff.append('[path=%s]' % self.path) 76 if self.query_string: 77 buff.append('?[querystr=%s]' % self.query_string) 78 if self.fragment_id: 79 buff.append('#[fragment=%s]' % self.fragment_id) 80 return ''.join(buff) 81 82 def __dump__(self): 83 print('<Url __dump__>') 84 pprint.pprint(self.__dict__) 85 print('</Url>') 86 87 88 class MethodParams(object): 89 90 def __init__(self, data): 91 self.raw = data 92 self.data = {} 93 self._parse_data() 94 95 def _parse_data(self): 96 self.data = self.raw 97 98 def getitem(self, name): 99 return self.str(name) 100 101 def __getitem__(self, item): 102 return self.getitem(item) 103 104 def contains(self, name): 105 return name in self.data 106 107 def __contains__(self, item): 108 return self.contains(item) 109 110 def raw(self, name, default = ''): 111 if self.contains(name): 112 return self.data[name] 113 return default 114 115 def str(self, name, default = ''): 116 if self.contains(name): 117 raw = self.data[name] 118 if isinstance(raw, unicode): 119 return urllib.unquote(raw.encode('utf-8')) 120 else: 121 return urllib.unquote(raw) 122 return default 123 124 def int(self, name, default = 0): 125 if self.contains(name): 126 return typeutils.int_eval(self.data[name], default) 127 return default 128 129 def float(self, name, default = 0.0): 130 if self.contains(name): 131 return typeutils.float_eval(self.data[name]) 132 return default 133 134 def bool(self, name, default = False): 135 if self.contains(name): 136 return typeutils.bool_eval(self.data[name]) 137 return default 138 139 def datetime(self, name, default = pydt.datetime.now()): 140 if self.contains(name) and self.data[name]: 141 return datetimeutils.any_to_datetime(self.data[name], default) 142 return default 143 144 def date(self, name, default = pydt.datetime.now().date()): 145 if self.contains(name) and self.data[name]: 146 val = datetimeutils.any_to_datetime(self.data[name], default) 147 if isinstance(val, pydt.datetime): 148 return val.date() 149 return default 150 151 def time(self, name, default = pydt.datetime.now().time()): 152 if self.contains(name) and self.data[name]: 153 val = datetimeutils.any_to_datetime(self.data[name], default) 154 if isinstance(val, pydt.datetime): 155 return val.time() 156 return default 157 158 def is_list(self, name): 159 if self.contains(name): 160 if isinstance(self.data[name], (list, tuple)): 161 return True 162 return False 163 164 def list(self, name, default = ()): 165 if self.contains(name): 166 if isinstance(self.data[name], (list, tuple)): 167 return self.data[name] 168 else: 169 return [self.data[name]] 170 return default 171 172 def str_list(self, name, default = ()): 173 if self.contains(name): 174 if isinstance(self.data[name], (list, tuple)): 175 return [ urllib.unquote(i) for i in self.data[name] ] 176 else: 177 return [urllib.unquote(self.data[name])] 178 return default 179 180 def int_list(self, name, default = (), item_default = 0): 181 if self.contains(name): 182 if isinstance(self.data[name], (list, tuple)): 183 return [ typeutils.int_eval(i, item_default) for i in self.data[name] ] 184 else: 185 return [typeutils.int_eval(self.data[name], item_default)] 186 return default 187 188 def float_list(self, name, default = (), item_default = 0.0): 189 if self.contains(name): 190 if isinstance(self.data[name], (list, tuple)): 191 return [ typeutils.float_eval(i, item_default) for i in self.data[name] ] 192 else: 193 return [typeutils.float_eval(self.data[name], item_default)] 194 return default 195 196 def bool_list(self, name, default = ()): 197 if self.contains(name): 198 if isinstance(self.data[name], (list, tuple)): 199 return [ typeutils.bool_eval(i) for i in self.data[name] ] 200 else: 201 return [typeutils.bool_eval(self.data[name])] 202 return default 203 204 def __repr__(self): 205 return '%r' % self.data 206 207 def __len__(self): 208 return len(self.data) 209 210 def __nonzero__(self): 211 return bool(self.data) 212 213 def __dump__(self): 214 classname = self.__class__.__name__ 215 print('<%s __dump__>' % classname) 216 pprint.pprint(self.__dict__) 217 print('</%s>' % classname) 218 219 220 class UnifiedParams(object): 221 222 def __init__(self, get_data, post_data): 223 self.get_data = get_data 224 self.post_data = post_data 225 226 def getitem(self, name): 227 return self.str(name) 228 229 def contains(self, name): 230 if self.post_data.contains(name): 231 return True 232 if self.get_data.contains(name): 233 return True 234 return False 235 236 def raw(self, name, default = ''): 237 if self.post_data.contains(name): 238 return self.post_data.raw(name, default) 239 if self.get_data.contains(name): 240 return self.get_data.raw(name, default) 241 return default 242 243 def str(self, name, default = ''): 244 if self.post_data.contains(name): 245 return self.post_data.str(name, default) 246 if self.get_data.contains(name): 247 return self.get_data.str(name, default) 248 return default 249 250 def int(self, name, default = 0): 251 if self.post_data.contains(name): 252 return self.post_data.int(name, default) 253 if self.get_data.contains(name): 254 return self.get_data.int(name, default) 255 return default 256 257 def float(self, name, default = 0.0): 258 if self.post_data.contains(name): 259 return self.post_data.float(name, default) 260 if self.get_data.contains(name): 261 return self.get_data.float(name, default) 262 return default 263 264 def bool(self, name, default = False): 265 if self.post_data.contains(name): 266 return self.post_data.bool(name, default) 267 if self.get_data.contains(name): 268 return self.get_data.bool(name, default) 269 return default 270 271 def datetime(self, name, default = pydt.datetime.now()): 272 if self.post_data.contains(name): 273 return self.post_data.datetime(name, default) 274 if self.get_data.contains(name): 275 return self.get_data.datetime(name, default) 276 return default 277 278 def date(self, name, default = pydt.datetime.now().date()): 279 if self.post_data.contains(name): 280 return self.post_data.date(name, default) 281 if self.get_data.contains(name): 282 return self.get_data.date(name, default) 283 return default 284 285 def time(self, name, default = pydt.datetime.now().time()): 286 if self.post_data.contains(name): 287 return self.post_data.time(name, default) 288 if self.get_data.contains(name): 289 return self.get_data.time(name, default) 290 return default 291 292 def is_list(self, name): 293 if self.post_data.contains(name): 294 if isinstance(self.post_data[name], (list, tuple)): 295 return True 296 if self.get_data.contains(name): 297 if isinstance(self.get_data[name], (list, tuple)): 298 return True 299 return False 300 301 def list(self, name, default = ()): 302 if self.post_data.contains(name): 303 return self.post_data.list(name, default) 304 if self.get_data.contains(name): 305 return self.get_data.list(name, default) 306 return default 307 308 def str_list(self, name, default = ()): 309 if self.post_data.contains(name): 310 return self.post_data.str_list(name, default) 311 if self.get_data.contains(name): 312 return self.get_data.str_list(name, default) 313 return default 314 315 def int_list(self, name, default = (), item_default = 0): 316 if self.post_data.contains(name): 317 return self.post_data.int_list(name, default, item_default=item_default) 318 if self.get_data.contains(name): 319 return self.get_data.int_list(name, default, item_default=item_default) 320 return default 321 322 def float_list(self, name, default = (), item_default = 0.0): 323 if self.post_data.contains(name): 324 return self.post_data.float_list(name, default, item_default=item_default) 325 if self.get_data.contains(name): 326 return self.get_data.float_list(name, default, item_default=item_default) 327 return default 328 329 def bool_list(self, name, default = ()): 330 if self.post_data.contains(name): 331 return self.post_data.bool_list(name, default) 332 if self.get_data.contains(name): 333 return self.get_data.bool_list(name, default) 334 return default 335 336 337 class AbstractRequest(object): 338 339 def __init__(self, request): 340 self.original = request 341 self.raw = '' 342 self.post = MethodParams({}) 343 self.get = MethodParams({}) 344 self.cookies = MethodParams({}) 345 self.url = Url('') 346 self.headers = {} 347 self.body = '' 348 self.method = '' 349 self.client_ip = '' 350 self.is_secure = False 351 self._parse_data() 352 self.p = UnifiedParams(self.get, self.post) 353 354 def _parse_data(self): 355 raise NotImplementedError('AbstractRequest is Abstract!') 356 357 def __dump__(self): 358 classname = self.__class__.__name__ 359 print('<%s __dump__>' % classname) 360 pprint.pprint(self.__dict__) 361 print('</%s>' % classname) 362 363 def __str__(self): 364 return '%s(url=%s, ip=%s)' % (self.__class__.__name__, self.url, self.client_ip) 365 366 def __repr__(self): 367 return '<{class_name}, url={url}, ip={ip}, method={method}>\n GET={get!r}\n POST={post!r}\n COOKIES={cookies!r}\n HEADERS={headers!r}\n\n</{class_name}>'.format(class_name=self.__class__.__name__, url=self.url, ip=self.client_ip, method=self.method, get=self.get, post=self.post, cookies=self.cookies, headers=self.headers) 368 369 370 class MoonshineRequest(AbstractRequest): 371 372 def _parse_data(self): 373 self.raw = self.original.raw 374 self.post = MethodParams(self.original.form) 375 self.get = MethodParams(self.original.query) 376 self.cookies = MethodParams(self.original.cookie) 377 self.headers = dict(zip([ str(k).lower() for k in self.original.header.keys() ], self.original.header.values())) 378 self.client_ip = self.original.ep.address 379 self.method = self.original.method 380 self.is_secure = False 381 if ':' in self.client_ip: 382 parts = self.client_ip.split(':') 383 if parts and len(parts) > 0: 384 self.client_ip = parts[0] 385 if self.original.path.startswith('/'): 386 path = self.original.path[1:] 387 else: 388 path = self.original.path 389 self.url = Url('%s/%s' % (self.headers.get('host', ''), path)) 390 try: 391 body = self.raw.replace('\r', '') 392 self.body = body[body.index('\n\n') + 2:] 393 except (ValueError, IndexError): 394 self.body = '' 395 396 397 class DjangoRequest(AbstractRequest): 398 399 def _parse_data(self): 400 self.raw = str(self.original.body) 401 self.method = self.original.method 402 self.post = MethodParams(self.original.POST) 403 self.get = MethodParams(self.original.GET) 404 self.cookies = MethodParams(self.original.COOKIES) 405 self.url = Url(self.original.get_full_path()) 406 self.client_ip = self.original.META['REMOTE_ADDR'] 407 self.body = self.original.body 408 self.headers['content-length'] = self.original.META.get('CONTENT_LENGTH', -1) 409 self.headers['content-type'] = self.original.META.get('CONTENT_TYPE', '') 410 self.is_secure = self.original.is_secure() 411 for k, v in self.original.META.iteritems(): 412 if k.startswith('HTTP_'): 413 self.headers[k[5:].lower().replace('_', '-')] = v 414 415 416 class CherryPyRequest(AbstractRequest): 417 418 def _parse_data(self): 419 self.raw = str(self.original.body) 420 self.post = MethodParams(self.original.body.params) 421 self.client_ip = self.original.remote.ip 422 qs_params = urlparse.parse_qs(self.original.query_string, keep_blank_values=True) 423 for k in qs_params.keys(): 424 if isinstance(qs_params[k], list): 425 if len(qs_params[k]) < 1: 426 qs_params[k] = '' 427 elif len(qs_params[k]) == 1: 428 qs_params[k] = qs_params[k][0] 429 430 self.get = MethodParams(qs_params) 431 self.cookies = dict([ (k, v) for k, v in self.original.cookie.iteritems() ]) 432 self.method = self.original.method 433 self.headers = dict([ (k.lower(), v) for k, v in self.original.header_list ]) 434 self.url = Url('%s%s?%s' % (self.original.base, self.original.path_info, self.original.query_string)) 435 self.body = self.original.body 436 self.is_secure = self.original.scheme.lower() == 'https' 437 438 439 class Cookie(object): 440 441 def __init__(self, name, value, max_age = None, expires = None, path = '/', domain = None, secure = False, httponly = False): 442 self.name = name 443 self.value = value 444 self.max_age = max_age 445 self.expires = expires 446 self.path = path 447 self.domain = domain 448 self.secure = secure 449 self.httponly = httponly 450 451 def __str__(self): 452 return 'Cookie(%s=%s)' % (self.name, self.value) 453 454 def __repr__(self): 455 extras = [] 456 if self.max_age: 457 extras.append('max_age=%s' % self.max_age) 458 if self.expires: 459 extras.append('expires=%s' % self.expires) 460 if self.path: 461 extras.append('path=%s' % self.path) 462 if self.domain: 463 extras.append('domain=%s' % self.domain) 464 if self.secure: 465 extras.append('secure=%s' % self.secure) 466 if self.httponly: 467 extras.append('httponly=%s' % self.httponly) 468 if extras: 469 extras = ', %s' % ', '.join(extras) 470 else: 471 extras = '' 472 return 'Cookie(name=%s, value=%s%s)' % (self.name, self.value, extras) 473 474 475 class AbstractResponse(object): 476 RESPONSE_TYPE_META = 0 477 RESPONSE_TYPE_SCRIPT = 1 478 RESPONSE_TYPE_STATIC = 2 479 RESPONSE_TYPE_REDIRECT = 3 480 RESPONSE_TYPE_ERROR = 4 481 482 def __init__(self, response_type = None): 483 self.headers = {} 484 self.set_cookies = {} 485 self.delete_cookies = [] 486 self.response_type = response_type or AbstractResponse.RESPONSE_TYPE_META 487 self.body = None 488 self.request = None 489 self.session = None 490 self.data = {} 491 self.original_url = '' 492 493 def add_cookie(self, name, value, max_age = None, expires = None, path = '/', domain = None, secure = False, httponly = False): 494 self.set_cookies[name] = Cookie(name, value, max_age, expires, path, domain, secure, httponly) 495 496 def delete_cookie(self, name): 497 self.delete_cookies.append(name) 498 499 def add_header(self, name, value): 500 self.headers[name] = value 501 502 503 class MetaResponse(AbstractResponse): 504 505 def __init__(self): 506 super(MetaResponse, self).__init__(AbstractResponse.RESPONSE_TYPE_META) 507 508 509 class ScriptResponse(AbstractResponse): 510 511 def __init__(self, script = ''): 512 super(ScriptResponse, self).__init__(AbstractResponse.RESPONSE_TYPE_SCRIPT) 513 self.body = script 514 515 516 class StaticResponse(AbstractResponse): 517 518 def __init__(self, body = ''): 519 super(StaticResponse, self).__init__(AbstractResponse.RESPONSE_TYPE_STATIC) 520 self.body = body 521 522 523 class RedirectResponse(AbstractResponse): 524 525 def __init__(self, url = '', original_url = ''): 526 super(RedirectResponse, self).__init__(AbstractResponse.RESPONSE_TYPE_REDIRECT) 527 self.body = url 528 self.original_url = original_url 529 530 531 class ErrorResponse(AbstractResponse): 532 533 def __init__(self, message = ''): 534 super(ErrorResponse, self).__init__(AbstractResponse.RESPONSE_TYPE_ERROR) 535 self.body = message 536 537 538 def parse_request(request): 539 if isinstance(request, AbstractRequest): 540 return request 541 request_class = getattr(request, '__class__', None) 542 if request_class: 543 class_name = str(request_class) 544 if class_name.startswith("<class '"): 545 class_name = class_name[8:] 546 if class_name.endswith("'>"): 547 class_name = class_name[:-2] 548 if class_name.endswith('.net.httpService.Request'): 549 return MoonshineRequest(request) 550 if class_name.startswith('cherrypy.'): 551 return CherryPyRequest(request) 552 if class_name.startswith('django.'): 553 return DjangoRequest(request) 554 log.error('Unknown class_name: %s=' % class_name) 555 log.error('Unknown http request type: %s=%r' % (request_class, request)) 556 return request 557 558 559 def url_append_qs(url, **kwargs): 560 if not kwargs: 561 return url 562 req_url = [url] 563 if '?' in url: 564 if url[-1] not in ('?', '&'): 565 req_url.append('&') 566 else: 567 req_url.append('?') 568 req_url.append(urllib.urlencode(kwargs)) 569 return ''.join(req_url) 570 571 572 def get_mimetype(file_name): 573 if file_name: 574 parts = file_name.split('.') 575 if len(parts) > 1: 576 return const.MIME_TYPE_BY_EXTENSION.get(parts[-1], const.MIME_TYPE_DEFAULT) 577 return const.MIME_TYPE_DEFAULT 578 579 580 if __name__ == '__main__': 581 m = MethodParams({'q': str(u'%D0%B0%D1%82%D1%8C')}) 582 s = m.str('q') 583 print(u'%r' % s) 584 print('%s' % s)