cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / servlet.py
blobc9ac5683ec095fa856059ae24c54c25c8f26a34d
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
6 class RequestHeaders(object):
7 '''A custom dictionary impementation for headers which ignores the case
8 of requests, since different HTTP libraries seem to mangle them.
9 '''
10 def __init__(self, dict_):
11 if isinstance(dict_, RequestHeaders):
12 self._dict = dict_
13 else:
14 self._dict = dict((k.lower(), v) for k, v in dict_.iteritems())
16 def get(self, key, default=None):
17 return self._dict.get(key.lower(), default)
19 def __repr__(self):
20 return repr(self._dict)
22 def __str__(self):
23 return repr(self._dict)
26 class Request(object):
27 '''Request data.
28 '''
29 def __init__(self, path, host, headers, arguments={}):
30 self.path = path.lstrip('/')
31 assert not '/' in host, 'Host "%s" should not contain a slash' % host
32 self.host = host
33 self.headers = RequestHeaders(headers)
34 self.arguments = arguments
36 @staticmethod
37 def ForTest(path, host=None, headers=None, arguments=None):
38 return Request(path,
39 host or 'developer.chrome.com',
40 headers or {},
41 arguments or {})
43 def __repr__(self):
44 return 'Request(path=%s, host=%s, headers=%s)' % (
45 self.path, self.host, self.headers)
47 def __str__(self):
48 return repr(self)
50 class _ContentBuilder(object):
51 '''Builds the response content.
52 '''
53 def __init__(self):
54 self._buf = []
56 def Append(self, content):
57 if isinstance(content, unicode):
58 content = content.encode('utf-8', 'replace')
59 self._buf.append(content)
61 def ToString(self):
62 self._Collapse()
63 return self._buf[0]
65 def __str__(self):
66 return self.ToString()
68 def __len__(self):
69 return len(self.ToString())
71 def _Collapse(self):
72 self._buf = [''.join(self._buf)]
74 class Response(object):
75 '''The response from Get().
76 '''
77 def __init__(self, content=None, headers=None, status=None):
78 self.content = _ContentBuilder()
79 if content is not None:
80 self.content.Append(content)
81 self.headers = {}
82 if headers is not None:
83 self.headers.update(headers)
84 self.status = status
86 @staticmethod
87 def Ok(content, headers=None):
88 '''Returns an OK (200) response.
89 '''
90 return Response(content=content, headers=headers, status=200)
92 @staticmethod
93 def Redirect(url, permanent=False):
94 '''Returns a redirect (301 or 302) response.
95 '''
96 status = 301 if permanent else 302
97 return Response(headers={'Location': url}, status=status)
99 @staticmethod
100 def BadRequest(content, headers=None):
101 '''Returns a bad request (400) response.
103 return Response(content=content, headers=headers, status=400)
105 @staticmethod
106 def Unauthorized(content, method, realm, headers={}):
107 '''Returns an unauthorized (401) response.
109 new_headers = headers.copy()
110 new_headers.update({
111 'WWW-Authentication': '%s realm="%s"' % (method, realm)})
112 return Response(content=content, headers=headers, status=401)
114 @staticmethod
115 def Forbidden(content, headers=None):
116 '''Returns an forbidden (403) response.
118 return Response(content=content, headers=headers, status=403)
120 @staticmethod
121 def NotFound(content, headers=None):
122 '''Returns a not found (404) response.
124 return Response(content=content, headers=headers, status=404)
126 @staticmethod
127 def NotModified(content, headers=None):
128 return Response(content=content, headers=headers, status=304)
130 @staticmethod
131 def InternalError(content, headers=None):
132 '''Returns an internal error (500) response.
134 return Response(content=content, headers=headers, status=500)
136 @staticmethod
137 def ThrottledError(content, headers=None):
138 '''Returns an HTTP throttle error (429) response.
140 return Response(content=content, headers=headers, status=429)
142 def Append(self, content):
143 '''Appends |content| to the response content.
145 self.content.append(content)
147 def AddHeader(self, key, value):
148 '''Adds a header to the response.
150 self.headers[key] = value
152 def AddHeaders(self, headers):
153 '''Adds several headers to the response.
155 self.headers.update(headers)
157 def SetStatus(self, status):
158 self.status = status
160 def GetRedirect(self):
161 if self.headers.get('Location') is None:
162 return (None, None)
163 return (self.headers.get('Location'), self.status == 301)
165 def IsNotFound(self):
166 return self.status == 404
168 def __eq__(self, other):
169 return (isinstance(other, self.__class__) and
170 str(other.content) == str(self.content) and
171 other.headers == self.headers and
172 other.status == self.status)
174 def __ne__(self, other):
175 return not (self == other)
177 def __repr__(self):
178 return 'Response(content=%s bytes, status=%s, headers=%s)' % (
179 len(self.content), self.status, self.headers)
181 def __str__(self):
182 return repr(self)
184 class Servlet(object):
185 def __init__(self, request):
186 self._request = request
188 def Get(self):
189 '''Returns a Response.
191 raise NotImplemented()