Skip to content

Instantly share code, notes, and snippets.

@darwin
Created January 8, 2009 10:41
Show Gist options
  • Save darwin/44680 to your computer and use it in GitHub Desktop.
Save darwin/44680 to your computer and use it in GitHub Desktop.
from openid import fetchers
from google.appengine.api import urlfetch
import logging
# other firepython enabled server should be created like this:
# firepython = None
#
# def main():
# app = Application()
# if FIREPYTHON_ENABLED:
# logging.getLogger().name = "other server"
# firepython = app = FirePythonWSGI(app, password=FIREPYTHON_PASSWORD, check_agent=False)
# run_wsgi_app(app)
# check_agent=False is needed because of GAE restrictions on headers
# http://code.google.com/appengine/docs/urlfetch/fetchfunction.html
class AppEngineFetcher(fetchers.HTTPFetcher):
def __init__(self, firepython=None, firepython_password=None):
fetchers.HTTPFetcher.__init__(self)
self.firepython = firepython # current firepython middleware instance
self.firepython_password = firepython_password # firepython password for other firepython-enabled server we are doing fetch against
"""An HTTPFetcher subclass that uses Google App Engine's urlfetch module.
"""
def fetch(self, url, body=None, headers=None):
if not fetchers._allowedURL(url):
raise ValueError('Bad URL scheme: %r' % (url,))
if not headers:
headers = {}
if body:
method = urlfetch.POST
headers['Content-type'] = 'application/x-www-form-urlencoded'
else:
method = urlfetch.GET
if self.firepython:
import firepython.utils
# note: this USER_AGENT doesn't work for GAE according to note here: http://code.google.com/appengine/docs/urlfetch/fetchfunction.html
fpua = firepython.utils.get_user_agent()
ua = headers.get('USER_AGENT')
if ua is None: ua = ''
headers['USER_AGENT'] = ua + " " + fpua
if self.firepython_password is not None:
ah = firepython.utils.get_auth_header(self.firepython_password)
headers[ah[0]] = ah[1]
count = 0
resp = urlfetch.fetch(url, body, method, headers=headers)
# follow redirects for a while
while resp.status_code in [301,302]:
count += 1
if count >= 3:
raise Exception('too many redirects')
if resp.headers.has_key('location'):
url = resp.headers['location']
elif resp.headers.has_key('Location'):
url = resp.headers['Location']
else:
raise Exception('Could not find location in headers: %r' % (resp.headers,))
resp = urlfetch.fetch(url, body, method, headers=headers)
if self.firepython:
self.firepython.republish(resp.headers)
# normalize headers
for key, val in resp.headers.items():
resp.headers[key.lower()] = val
return fetchers.HTTPResponse(url, resp.status_code, resp.headers, resp.content)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment