Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from webob.compat import ( 

2 MutableMapping, 

3 iteritems_, 

4 string_types, 

5 ) 

6from webob.multidict import MultiDict 

7 

8__all__ = ['ResponseHeaders', 'EnvironHeaders'] 

9 

10class ResponseHeaders(MultiDict): 

11 """ 

12 Dictionary view on the response headerlist. 

13 Keys are normalized for case and whitespace. 

14 """ 

15 def __getitem__(self, key): 

16 key = key.lower() 

17 for k, v in reversed(self._items): 

18 if k.lower() == key: 

19 return v 

20 raise KeyError(key) 

21 

22 def getall(self, key): 

23 key = key.lower() 

24 return [v for (k, v) in self._items if k.lower() == key] 

25 

26 def mixed(self): 

27 r = self.dict_of_lists() 

28 for key, val in iteritems_(r): 

29 if len(val) == 1: 

30 r[key] = val[0] 

31 return r 

32 

33 def dict_of_lists(self): 

34 r = {} 

35 for key, val in iteritems_(self): 

36 r.setdefault(key.lower(), []).append(val) 

37 return r 

38 

39 def __setitem__(self, key, value): 

40 norm_key = key.lower() 

41 self._items[:] = [(k, v) for (k, v) in self._items if k.lower() != norm_key] 

42 self._items.append((key, value)) 

43 

44 def __delitem__(self, key): 

45 key = key.lower() 

46 items = self._items 

47 found = False 

48 for i in range(len(items)-1, -1, -1): 

49 if items[i][0].lower() == key: 

50 del items[i] 

51 found = True 

52 if not found: 

53 raise KeyError(key) 

54 

55 def __contains__(self, key): 

56 key = key.lower() 

57 for k, v in self._items: 

58 if k.lower() == key: 

59 return True 

60 return False 

61 

62 has_key = __contains__ 

63 

64 def setdefault(self, key, default=None): 

65 c_key = key.lower() 

66 for k, v in self._items: 

67 if k.lower() == c_key: 

68 return v 

69 self._items.append((key, default)) 

70 return default 

71 

72 def pop(self, key, *args): 

73 if len(args) > 1: 

74 raise TypeError("pop expected at most 2 arguments, got %s" 

75 % repr(1 + len(args))) 

76 key = key.lower() 

77 for i in range(len(self._items)): 

78 if self._items[i][0].lower() == key: 

79 v = self._items[i][1] 

80 del self._items[i] 

81 return v 

82 if args: 

83 return args[0] 

84 else: 

85 raise KeyError(key) 

86 

87 

88 

89 

90 

91 

92key2header = { 

93 'CONTENT_TYPE': 'Content-Type', 

94 'CONTENT_LENGTH': 'Content-Length', 

95 'HTTP_CONTENT_TYPE': 'Content_Type', 

96 'HTTP_CONTENT_LENGTH': 'Content_Length', 

97} 

98 

99header2key = dict([(v.upper(),k) for (k,v) in key2header.items()]) 

100 

101def _trans_key(key): 

102 if not isinstance(key, string_types): 

103 return None 

104 elif key in key2header: 

105 return key2header[key] 

106 elif key.startswith('HTTP_'): 

107 return key[5:].replace('_', '-').title() 

108 else: 

109 return None 

110 

111def _trans_name(name): 

112 name = name.upper() 

113 if name in header2key: 

114 return header2key[name] 

115 return 'HTTP_'+name.replace('-', '_') 

116 

117class EnvironHeaders(MutableMapping): 

118 """An object that represents the headers as present in a 

119 WSGI environment. 

120 

121 This object is a wrapper (with no internal state) for a WSGI 

122 request object, representing the CGI-style HTTP_* keys as a 

123 dictionary. Because a CGI environment can only hold one value for 

124 each key, this dictionary is single-valued (unlike outgoing 

125 headers). 

126 """ 

127 

128 def __init__(self, environ): 

129 self.environ = environ 

130 

131 def __getitem__(self, hname): 

132 return self.environ[_trans_name(hname)] 

133 

134 def __setitem__(self, hname, value): 

135 self.environ[_trans_name(hname)] = value 

136 

137 def __delitem__(self, hname): 

138 del self.environ[_trans_name(hname)] 

139 

140 def keys(self): 

141 return filter(None, map(_trans_key, self.environ)) 

142 

143 def __contains__(self, hname): 

144 return _trans_name(hname) in self.environ 

145 

146 def __len__(self): 

147 return len(list(self.keys())) 

148 

149 def __iter__(self): 

150 for k in self.keys(): 

151 yield k