remove use of 1.6.4-compatible 'wrapper'
[gae-samples.git] / openid-consumer / fetcher.py
blob95c944445eb10512e740cd819d018fb3d65e76d1
1 #!/usr/bin/python
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.
17 """
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.
24 """
26 import logging
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.
34 """
35 def fetch(self, url, body=None, headers=None):
36 """
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
47 cause exceptions.
49 @rtype: L{HTTPResponse}
51 @raise Exception: Different implementations will raise
52 different errors based on the underlying HTTP library.
53 """
54 if not fetchers._allowedURL(url):
55 raise ValueError('Bad URL scheme: %r' % (url,))
57 if not headers:
58 headers = {}
60 if body:
61 method = urlfetch.POST
62 if 'Content-Type' not in headers:
63 headers['Content-Type'] = 'application/x-www-form-urlencoded'
64 else:
65 method = urlfetch.GET
67 if not headers:
68 headers = {}
70 # follow up to 10 redirects
71 for i in range(10):
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']
77 else:
78 break
80 return fetchers.HTTPResponse(url, resp.status_code, resp.headers,
81 resp.content)