import httplib import urllib import urlparse import config import cache import security debug = 1 from exceptions import Exception class ContentTypeError(Exception): pass class proxy: def __init__(self): self.c = config.getConfig() def apply_security(self, headers, config): """ Apply security to this object, we except this to overriden by the web server """ raise NotImplementedError def process(self, headers, url=None): """ This is the main request loop """ # then lookup that url in the config config = self.c.startswith_lookup(url) if not config: raise ValueError, "No configuration can be found for the url: %s" % url data = None proxy_response = None found_in_cache = False if config.get('security'): self.apply_security(headers, config) # add in url? # next check the cache if config.get('cache'): cached = self.get_cache(headers, config) # add in url? if cached is not None: data, proxy_response = cached found_in_cache = True new_headers = self.headers_pass(headers) if not found_in_cache: data, proxy_response = self.get_data(new_headers, config, url) if found_in_cache: proxy_response["X-Cache"] = "Hit in the AjaxProxy cache." if not found_in_cache and config.get('cache'): self.set_cache(headers, config, data) # nothing to do here so far #if config.get('transform'): # data = transforms.transform(headers, data, config) return data, proxy_response def headers_pass(self, headers): """ This is a list of all the headers that the Ajax app passed that you would like to pass on, again rarely used """ return headers def get_cache(self, headers, config): """ An opportunity to override this, eg, you want to do Zope caching """ return cache.getCached(headers, config) def set_cache(self, headers, config, data): """ An opportunity to override this, eg, you want to do Zope caching """ return cache.setCached(headers, config, data) def get_incoming_data(self): """ Get the incoming data and then pass it on to the proxied request """ return None def get_data(self, headers, config, url): """ Given the configuration and the request from the client, go get this from the proxy """ # to do... # get all the other request headers, query string and # data and ensure that is passed along to this request content_type = config.get("required-content-type", "application/xml") verb = self.get_request_method() # we will assume data is not going to be encoded # i'm not sure this is a good idea if verb == "POST": data = self.get_incoming_data() data = urllib.urlencode(data) urlparsed = urlparse.urlparse(url) conn = httplib.HTTPConnection(urlparsed[1]) headers["Accept"] = content_type conn.request(verb, urlparsed[3], "", headers) res = conn.getresponse() hdr = res.headers.getheader('Content-type') if hdr.find(content_type) < 0: raise ContentTypeError, "The response must be of content-type %s not: %s. "\ "The expected content-type can be changed in the config file." % (content_type, hdr) return res.read(), res.headers if __name__=="__main__": pass