This commit is contained in:
Aaron Terrell (Enus)
2010-01-07 10:47:40 -08:00
committed by Salad Dais
parent 007cb8aefd
commit b0781d3fb0

View File

@@ -29,38 +29,62 @@ util.wrap_socket_with_coroutine_socket()
# pyogp
from pyogp.lib.base.datatypes import UUID
from pyogp.lib.base.exc import DataParsingError
from pyogp.lib.base.network.stdlib_client import StdLibClient
from pyogp.lib.base.event_queue import EventQueueClient
from pyogp.lib.base.exc import DataParsingError, HTTPError
# initialize logging
logger = getLogger('pyogp.lib.base.caps_proxy')
class CapabilitiesProxy(object):
""" a manager class for proxyied http requests and responses"""
""" an application class for wsgiref.simple_server which handles
proxyied http requests and responses for capabilities """
def __init__(self,
seed_cap_url,
proxy_host_ip,
proxy_host_port,
proxy_host_port,
message_handler = None,
restclient = None):
# populated initially via the login response
self.seed_cap_url = seed_cap_url
# the local proxy info, needed for building urls to send to the viewer
self.proxy_host_ip = proxy_host_ip
self.proxy_host_port = proxy_host_port
if restclient == None:
# allow the message handler to be passed in
# otherwise, just set one up
if message_handler != None:
self.message_handler = message_handler
else:
from pyogp.lib.base.message.message_handler import MessageHandler
self.message_handler = MessageHandler()
# we may in the future use something other than urllib2 (StdLibClient)
if restclient == None:
from pyogp.lib.base.network.stdlib_client import StdLibClient
self.restclient = StdLibClient()
else:
self.restclient = restclient
# stores the capability url <-> proxy uuid combo
self.proxy_map = {}
self.add_proxy(self.seed_cap_url)
# stored the url:cap name map
self.capability_map = {}
# stores the event_queue info for parsing special data
self.event_queue_client = EventQueueClient()
self.event_queue_url = None
# init the seed cap proxy
self.add_proxy(self.seed_cap_url, 'seed_capability')
logger.info("Initialized the CapabilitiesProxy for %s" %
(seed_cap_url))
(self.seed_cap_url))
def add_proxy(self, url):
def add_proxy(self, url, capname):
""" adds the url and it's proxy, and the proxy and it's url"""
# make available UUID <-> url dicts
@@ -73,6 +97,9 @@ class CapabilitiesProxy(object):
self.proxy_map[url] = uuid
self.proxy_map[uuid] = url
# store the url:capname
self.capability_map[url] = capname
return uuid
def remove_proxy(self, proxied):
@@ -87,14 +114,10 @@ class CapabilitiesProxy(object):
try:
del self.proxy_map[val]
del self.capability_map[val]
except KeyError:
pass
'''
class HTTPProxyApp(object):
""" a app for handling proxied http requests to capabilities"""
'''
def swap_cap_urls(self, cap_map):
""" takes the response to a seed_cap request for cap urls
and maps proxy urls in place of the ones for the sim
@@ -102,66 +125,89 @@ class CapabilitiesProxy(object):
# we expect a dict of {'capname':'url'}
for cap in cap_map:
cap_proxy_uuid = self.add_proxy(cap_map[cap])
# store the EventQueueGet url separately
if cap == 'EventQueueGet':
self.event_queue_url = cap_map[cap]
cap_proxy_uuid = self.add_proxy(cap_map[cap], cap)
cap_map[cap] = "http://%s:%s/%s" % (self.proxy_host_ip,
self.proxy_host_port,
cap_proxy_uuid)
# store the url:capname
self.capability_map[cap_map[cap]] = cap
return cap_map
def __call__(self, environ, start_response):
""" handle a specific cap request and response using webob objects"""
self.environ = environ
self.start = start_response
self.request = Request(environ)
self.response = Response()
logger.debug("Calling cap %s via %s with body of: %s" %
(self.proxy_map[self.request.path[1:]],
logger.info("Calling cap %s (%s) via %s with body of: %s" %
(self.capability_map[self.proxy_map[self.request.path[1:]]],
self.proxy_map[self.request.path[1:]],
self.request.method,
self.request.body))
# todo: catch 404 and 500s
# urllib2 will return normally if the reponse status = 200
# returns HTTPError if not
# trap and send back to the viewer in either case
try:
if self.request.method=="GET":
proxy_response = self.restclient.GET(self.proxy_map[self.request.path[1:]])
elif self.request.method == "POST":
proxy_response = self.restclient.POST(self.proxy_map[self.request.path[1:]], self.request.body)
if self.request.method=="GET":
logger.debug("Cap %s responded with status %s and body of: %s" %
(self.proxy_map[self.request.path[1:]],
proxy_response.status,
proxy_response.body))
proxy_response = self.restclient.GET(self.proxy_map[self.request.path[1:]])
# build the response to the viewer
status = proxy_response.status
elif self.request.method == "POST":
proxy_response = self.restclient.POST(self.proxy_map[self.request.path[1:]],
self.request.body)
logger.info("Cap %s (%s) responded with status %s and body of: %s" %
(self.capability_map[self.proxy_map[self.request.path[1:]]],
self.proxy_map[self.request.path[1:]],
proxy_response.status,
proxy_response.body))
# build the webob.Response to send to the viewer
status = proxy_response.status
# if we are parsing the seed cap response, swap the cap urls
# with our proxied ones
if self.proxy_map[self.request.path[1:]] == self.seed_cap_url:
cap_map = self.swap_cap_urls(llsd.parse(proxy_response.body))
data = llsd.format_xml(cap_map)
# if we are parsing the event queue, decode the data
# then curry it on out
elif self.proxy_map[self.request.path[1:]] == self.event_queue_url:
self.event_queue_client._parse_result(llsd.parse(proxy_response.body))
data = proxy_response.body
# otherwise, just proxy the data
else:
data = proxy_response.body
# trap the HTTPError and build the appropriate response for the caller
except HTTPError, error:
status = error.code
data = error.msg
# if we are responding to the seed cap, swap the cap urls
if self.proxy_map[self.request.path[1:]] == self.seed_cap_url:
cap_map = self.swap_cap_urls(llsd.parse(proxy_response.body))
data = llsd.format_xml(cap_map)
else:
data = proxy_response.body
return self.send_response(status, data)
'''
data = self.request.body
if self.request.path=="/network/get" and self.request.method=="GET":
self.response.status=200
self.response.body="Hello, World"
return self.response(self.environ, self.start)
elif self.request.path=="/network/post" and self.request.method=="POST":
data = self.request.body
self.response.status=200
self.response.body="returned: %s" %data
return self.response(self.environ, self.start)
else:
return self.send_response(404, 'resource not found.')
'''
def send_response(self, status, body=''):
logger.debug(body)
""" send the response back to the caller """
logger.debug("Sending cap response to viewer: Status:%s Body:%s" % (status, body))
self.response.status = status
self.response.body = body
return self.response(self.environ, self.start)