NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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)