3 # Copyright 2007, Google Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
18 An HTTPFetcher implementation that uses Google App Engine's urlfetch module.
20 HTTPFetcher is an interface defined in the top-level fetchers module in
21 JanRain's OpenID python library: http://openidenabled.com/python-openid/
23 For more, see openid/fetchers.py in that library.
28 from openid
import fetchers
29 from google
.appengine
.api
import urlfetch
32 class UrlfetchFetcher(fetchers
.HTTPFetcher
):
33 """An HTTPFetcher subclass that uses Google App Engine's urlfetch module.
35 def fetch(self
, url
, body
=None, headers
=None):
37 This performs an HTTP POST or GET, following redirects along
38 the way. If a body is specified, then the request will be a
39 POST. Otherwise, it will be a GET.
41 @param headers: HTTP headers to include with the request
42 @type headers: {str:str}
44 @return: An object representing the server's HTTP response. If
45 there are network or protocol errors, an exception will be
46 raised. HTTP error responses, like 404 or 500, do not
49 @rtype: L{HTTPResponse}
51 @raise Exception: Different implementations will raise
52 different errors based on the underlying HTTP library.
54 if not fetchers
._allowedURL
(url
):
55 raise ValueError('Bad URL scheme: %r' % (url
,))
61 method
= urlfetch
.POST
62 if 'Content-Type' not in headers
:
63 headers
['Content-Type'] = 'application/x-www-form-urlencoded'
70 # follow up to 10 redirects
72 resp
= urlfetch
.fetch(url
, body
, method
, headers
)
73 if resp
.status_code
in (301, 302):
74 logging
.debug('Following %d redirect to %s' %
75 (resp
.status_code
, resp
.headers
['location']))
76 url
= resp
.headers
['location']
80 return fetchers
.HTTPResponse(url
, resp
.status_code
, resp
.headers
,