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.
10 def __init__(self
, dict_
):
11 if isinstance(dict_
, RequestHeaders
):
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
)
20 return repr(self
._dict
)
23 return repr(self
._dict
)
26 class Request(object):
29 def __init__(self
, path
, host
, headers
):
30 self
.path
= path
.lstrip('/')
31 self
.host
= host
.rstrip('/')
32 self
.headers
= RequestHeaders(headers
)
35 def ForTest(path
, host
='http://developer.chrome.com', headers
=None):
36 return Request(path
, host
, headers
or {})
39 return 'Request(path=%s, host=%s, headers=%s)' % (
40 self
.path
, self
.host
, self
.headers
)
45 class _ContentBuilder(object):
46 '''Builds the response content.
51 def Append(self
, content
):
52 if isinstance(content
, unicode):
53 content
= content
.encode('utf-8', 'replace')
54 self
._buf
.append(content
)
61 return self
.ToString()
64 return len(self
.ToString())
67 self
._buf
= [''.join(self
._buf
)]
69 class Response(object):
70 '''The response from Get().
72 def __init__(self
, content
=None, headers
=None, status
=None):
73 self
.content
= _ContentBuilder()
74 if content
is not None:
75 self
.content
.Append(content
)
77 if headers
is not None:
78 self
.headers
.update(headers
)
82 def Ok(content
, headers
=None):
83 '''Returns an OK (200) response.
85 return Response(content
=content
, headers
=headers
, status
=200)
88 def Redirect(url
, permanent
=False):
89 '''Returns a redirect (301 or 302) response.
91 status
= 301 if permanent
else 302
92 return Response(headers
={'Location': url
}, status
=status
)
95 def NotFound(content
, headers
=None):
96 '''Returns a not found (404) response.
98 return Response(content
=content
, headers
=headers
, status
=404)
101 def NotModified(content
, headers
=None):
102 return Response(content
=content
, headers
=headers
, status
=304)
105 def InternalError(content
, headers
=None):
106 '''Returns an internal error (500) response.
108 return Response(content
=content
, headers
=headers
, status
=500)
110 def Append(self
, content
):
111 '''Appends |content| to the response content.
113 self
.content
.append(content
)
115 def AddHeader(self
, key
, value
):
116 '''Adds a header to the response.
118 self
.headers
[key
] = value
120 def AddHeaders(self
, headers
):
121 '''Adds several headers to the response.
123 self
.headers
.update(headers
)
125 def SetStatus(self
, status
):
128 def GetRedirect(self
):
129 if self
.headers
.get('Location') is None:
131 return (self
.headers
.get('Location'), self
.status
== 301)
133 def IsNotFound(self
):
134 return self
.status
== 404
136 def __eq__(self
, other
):
137 return (isinstance(other
, self
.__class
__) and
138 str(other
.content
) == str(self
.content
) and
139 other
.headers
== self
.headers
and
140 other
.status
== self
.status
)
142 def __ne__(self
, other
):
143 return not (self
== other
)
146 return 'Response(content=%s bytes, status=%s, headers=%s)' % (
147 len(self
.content
), self
.status
, self
.headers
)
152 class Servlet(object):
153 def __init__(self
, request
):
154 self
._request
= request
157 '''Returns a Response.
159 raise NotImplemented()