headers.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import six
  2. from w3lib.http import headers_dict_to_raw
  3. from scrapy.utils.datatypes import CaselessDict
  4. from scrapy.utils.python import to_unicode
  5. class Headers(CaselessDict):
  6. """Case insensitive http headers dictionary"""
  7. def __init__(self, seq=None, encoding='utf-8'):
  8. self.encoding = encoding
  9. super(Headers, self).__init__(seq)
  10. def normkey(self, key):
  11. """Normalize key to bytes"""
  12. return self._tobytes(key.title())
  13. def normvalue(self, value):
  14. """Normalize values to bytes"""
  15. if value is None:
  16. value = []
  17. elif isinstance(value, (six.text_type, bytes)):
  18. value = [value]
  19. elif not hasattr(value, '__iter__'):
  20. value = [value]
  21. return [self._tobytes(x) for x in value]
  22. def _tobytes(self, x):
  23. if isinstance(x, bytes):
  24. return x
  25. elif isinstance(x, six.text_type):
  26. return x.encode(self.encoding)
  27. elif isinstance(x, int):
  28. return six.text_type(x).encode(self.encoding)
  29. else:
  30. raise TypeError('Unsupported value type: {}'.format(type(x)))
  31. def __getitem__(self, key):
  32. try:
  33. return super(Headers, self).__getitem__(key)[-1]
  34. except IndexError:
  35. return None
  36. def get(self, key, def_val=None):
  37. try:
  38. return super(Headers, self).get(key, def_val)[-1]
  39. except IndexError:
  40. return None
  41. def getlist(self, key, def_val=None):
  42. try:
  43. return super(Headers, self).__getitem__(key)
  44. except KeyError:
  45. if def_val is not None:
  46. return self.normvalue(def_val)
  47. return []
  48. def setlist(self, key, list_):
  49. self[key] = list_
  50. def setlistdefault(self, key, default_list=()):
  51. return self.setdefault(key, default_list)
  52. def appendlist(self, key, value):
  53. lst = self.getlist(key)
  54. lst.extend(self.normvalue(value))
  55. self[key] = lst
  56. def items(self):
  57. return list(self.iteritems())
  58. def iteritems(self):
  59. return ((k, self.getlist(k)) for k in self.keys())
  60. def values(self):
  61. return [self[k] for k in self.keys()]
  62. def to_string(self):
  63. return headers_dict_to_raw(self)
  64. def to_unicode_dict(self):
  65. """ Return headers as a CaselessDict with unicode keys
  66. and unicode values. Multiple values are joined with ','.
  67. """
  68. return CaselessDict(
  69. (to_unicode(key, encoding=self.encoding),
  70. to_unicode(b','.join(value), encoding=self.encoding))
  71. for key, value in self.items())
  72. def __copy__(self):
  73. return self.__class__(self)
  74. copy = __copy__