def make_request(self, resource, method="GET", body=None, params={}, headers={}): """ Make a request to a given resource @param resource: The resource URI to fetch from (ex. /users) @type resource: str @param method: The HTTP/1.1 Method to use, (GET/PUT/DELETE/POST/HEAD) @type method: str @param body: Optional body text to send @type body: str @param params: Optional additional GET/POST parameters to send (GET if GET, POST if POST) @type params: dict @param headers: Optional extra headers to send @type headers: dict """ from botoweb.request import Request from botoweb.response import Response import urllib query_params = [] for k in params: query_params.append("%s=%s" % (k, urllib.quote_plus(params[k]))) if method == "POST": req = Request.blank(resource) if query_params: body = "&".join(query_params) req.environ[ 'CONTENT_TYPE'] = 'application/x-www-form-urlencoded' else: if query_params: resource = "%s?%s" % (resource, "&".join(query_params)) req = Request.blank(resource) if body: req.body = body req.environ['CONTENT_LENGTH'] = str(len(req.body)) for k in headers: req.headers[k] = headers[k] req.method = method if self.user: req._user = self.user from pprint import pprint pprint(req.GET) return self.mapper.handle(req, Response())
def make_request(self, resource, method="GET", body=None, params={}, headers={}): """ Make a request to a given resource @param resource: The resource URI to fetch from (ex. /users) @type resource: str @param method: The HTTP/1.1 Method to use, (GET/PUT/DELETE/POST/HEAD) @type method: str @param body: Optional body text to send @type body: str @param params: Optional additional GET/POST parameters to send (GET if GET, POST if POST) @type params: dict @param headers: Optional extra headers to send @type headers: dict """ from botoweb.request import Request from botoweb.response import Response import urllib query_params = [] for k in params: query_params.append("%s=%s" % (k, urllib.quote_plus(params[k]))) if method == "POST": req = Request.blank(resource) if query_params: body = "&".join(query_params) req.environ["CONTENT_TYPE"] = "application/x-www-form-urlencoded" else: if query_params: resource = "%s?%s" % (resource, "&".join(query_params)) req = Request.blank(resource) if body: req.body = body req.environ["CONTENT_LENGTH"] = str(len(req.body)) for k in headers: req.headers[k] = headers[k] req.method = method if self.user: req._user = self.user from pprint import pprint pprint(req.GET) return self.mapper.handle(req, Response())
def test_handle_get_with_args_and_id(self): """ Test handing a GET request """ r = Request.blank("/foo/my_object_id?bar=biz&diz=dazzle") r.method = "GET" content = self.url_mapper.handle(r, Response()) assert (content.body == "<string>GET: my_object_id</string>")
def test_handle_get_with_args(self): """ Test handing a GET request """ r = Request.blank("/foo?bar=biz&diz=dazzle") r.method = "GET" content = self.url_mapper.handle(r, Response()) assert(content.body == "<string>GET</string>")
def test_handle_get_noargs(self): """ Test handing a GET request """ r = Request.blank("/foo") r.method = "GET" content = self.url_mapper.handle(r, Response()) assert (content.body == "<string>GET</string>")
def __call__(self, environ, start_response): """ Handles basic one-time-only WSGI setup, and handles error catching. """ resp = Response() req = Request(environ) try: # If there's too many threads already, just toss a # ServiceUnavailable to let the user know they should re-connect # later if self.maxthreads and self.threadpool: if len(self.threadpool.working) > self.maxthreads: raise ServiceUnavailable("Service Temporarily Overloaded") resp = self.handle(req, resp) except AssertionError, e: resp.set_status(400) resp.content_type = "text/plain" resp.body = str(e)
def test_path_with_trailing_slash(self): (handler, obj_id) = self.url_mapper.parse_path(Request.blank("/foo/")) assert (handler.__class__.__name__ == "SimpleHandler") assert (obj_id == None)
def test_path_with_object_id(self): my_obj_id = "2934823-423423432-asdf34AA-5498574298.avi" (handler, obj_id) = self.url_mapper.parse_path( Request.blank("/foo/%s" % my_obj_id)) assert (handler.__class__.__name__ == "SimpleHandler") assert (obj_id == my_obj_id)
def test_path_no_object(self): (handler, obj_id) = self.url_mapper.parse_path(Request.blank("/foo")) assert (handler.__class__.__name__ == "SimpleHandler") assert (obj_id == None)
def test_handle_post_with_args_and_id(self): r = Request.blank("/foo/my_object_id?bar=biz&diz=dazzle") r.method = "POST" content = self.url_mapper.handle(r, Response()) assert (content.body == "<string>POST: my_object_id</string>")
def test_path_no_object(self): (handler, obj_id) = self.url_mapper.parse_path(Request.blank("/foo")) assert(handler.__class__.__name__ == "SimpleHandler") assert(obj_id == None)
def _request(self, method, args, path='/'): """Generic Request All request args must contain at least: :msg_id: The message ID to correspond back when returning a response :model: The name of the model corresponding to this request (this corresponds to the "name" attribtute in handlers.yaml) Requests may also contain: :id: ID of the object to request :params: Any GET/POST parameters to pass in. The proper parameters are always used determined by what request type this is :post: POST parameters to send (ignores request method) :get: GET parameters to send (ignores request method) """ try: # Sanity Checking if args: msg_id = args.get('msg_id') if not args.has_key('msg_id'): self.emit('err', {'code': 400, 'msg': 'No msg_id provided'}) return if not args.has_key('model'): self.emit('err', {'code': 400, 'msg': 'No model provided'}) return path = self.request['routes'].get(args['model'], args['model']) log.info('%s: %s => %s' % (method, args['model'], path)) else: log.info('%s %s' % (method, path)) msg_id = 0 # Add in any GET/POST parameters post_params = None get_params = None if args: if method == 'POST': post_params = args.get('params') else: get_params = args.get('params') if args.has_key('get'): get_params = args.get('get') if args.has_key('post'): post_params = args.get('post') # Set up the Request and Response # objects resp = Response() environ = self.environ.copy() environ['REQUEST_METHOD'] = method.upper() if args: # If an ID is specified, add that to the path if args.has_key('id'): path += '/' + args['id'] # Also allow a parameter if args.has_key('param'): path += '/' + args['param'] # Set the path environ['PATH_INFO'] = path # Add in any GET paramters if get_params: environ['QUERY_STRING'] = urllib.urlencode(get_params) # Set up authorization if self.request.has_key('AUTH'): username = self.request['AUTH'].get('username') password = self.request['AUTH'].get('password') auth_header = ':'.join([username, password]) auth_header = 'BASIC %s' % auth_header.encode('base64') environ['HTTP_AUTHORIZATION'] = auth_header req = Request(environ) req.accept = self.headers.get('accept', req.headers.get('X-Application-Accept', 'application/json')) # Add in any POST params if post_params: req.content_type = 'application/x-www-form-urlencoded' req.body = urllib.urlencode(post_params) for header in self.headers: # We already handled the accept header above if header == 'accept': continue req.headers[header] = self.headers[header] # Add in any cached items with self.cache_lock: req.cache = self.session if self.session.has_key('user'): req._user = self.session['user'] # Execute the application try: # Run the request self.request['app'].handle(req, resp) # Handle any caching with self.cache_lock: if req.user: self.session['user'] = req.user for item in req.cache: self.session[item] = req.cache[item] # Return the response if 'json' in resp.content_type: for line in resp.app_iter: if not self.socket.connected: log.error('Client unexpectedly disconnected') return if line: for item in line.split('\r\n'): if item: data = json.loads(item) self.emit('data', {'msg_id': msg_id, 'msg': data}) else: self.emit('data', {'msg_id': msg_id, 'msg': resp.body}) except HTTPException, e: self.emit('err', {'msg_id': msg_id, 'code': e.code, 'msg': str(e)}) log.error('Error "%s" processing command: %s %s %s' % (str(e), method, args, path)) except Exception, e: self.emit('err', {'msg_id': msg_id, 'code': 500, 'msg': str(e)}) log.exception('Unhandled Error processing: %s' % args)
def test_path_with_object_id_with_slash(self): my_obj_id = "bucket_name/key_name/foo.avi" (handler, obj_id) = self.url_mapper.parse_path(Request.blank("/foo/%s" % my_obj_id)) assert(handler.__class__.__name__ == "SimpleHandler") assert(obj_id == my_obj_id)
def test_path_with_trailing_slash(self): (handler, obj_id) = self.url_mapper.parse_path(Request.blank("/foo/")) assert(handler.__class__.__name__ == "SimpleHandler") assert(obj_id == None)
def test_path_with_object_id(self): my_obj_id = "2934823-423423432-asdf34AA-5498574298.avi" (handler, obj_id) = self.url_mapper.parse_path(Request.blank("/foo/%s" % my_obj_id)) assert(handler.__class__.__name__ == "SimpleHandler") assert(obj_id == my_obj_id)
def test_path_with_object_id_with_slash(self): my_obj_id = "bucket_name/key_name/foo.avi" (handler, obj_id) = self.url_mapper.parse_path( Request.blank("/foo/%s" % my_obj_id)) assert (handler.__class__.__name__ == "SimpleHandler") assert (obj_id == my_obj_id)
def _request(self, method, args, path='/'): """Generic Request All request args must contain at least: :msg_id: The message ID to correspond back when returning a response :model: The name of the model corresponding to this request (this corresponds to the "name" attribtute in handlers.yaml) Requests may also contain: :id: ID of the object to request :params: Any GET/POST parameters to pass in. The proper parameters are always used determined by what request type this is :post: POST parameters to send (ignores request method) :get: GET parameters to send (ignores request method) """ try: # Sanity Checking if args: msg_id = args.get('msg_id') if not args.has_key('msg_id'): self.emit('err', { 'code': 400, 'msg': 'No msg_id provided' }) return if not args.has_key('model'): self.emit('err', {'code': 400, 'msg': 'No model provided'}) return path = self.request['routes'].get(args['model'], args['model']) log.info('%s: %s => %s' % (method, args['model'], path)) else: log.info('%s %s' % (method, path)) msg_id = 0 # Add in any GET/POST parameters post_params = None get_params = None if args: if method == 'POST': post_params = args.get('params') else: get_params = args.get('params') if args.has_key('get'): get_params = args.get('get') if args.has_key('post'): post_params = args.get('post') # Set up the Request and Response # objects resp = Response() environ = self.environ.copy() environ['REQUEST_METHOD'] = method.upper() if args: # If an ID is specified, add that to the path if args.has_key('id'): path += '/' + args['id'] # Also allow a parameter if args.has_key('param'): path += '/' + args['param'] # Set the path environ['PATH_INFO'] = path # Add in any GET paramters if get_params: environ['QUERY_STRING'] = urllib.urlencode(get_params) # Set up authorization if self.request.has_key('AUTH'): username = self.request['AUTH'].get('username') password = self.request['AUTH'].get('password') auth_header = ':'.join([username, password]) auth_header = 'BASIC %s' % auth_header.encode('base64') environ['HTTP_AUTHORIZATION'] = auth_header req = Request(environ) req.accept = self.headers.get( 'accept', req.headers.get('X-Application-Accept', 'application/json')) # Add in any POST params if post_params: req.content_type = 'application/x-www-form-urlencoded' req.body = urllib.urlencode(post_params) for header in self.headers: # We already handled the accept header above if header == 'accept': continue req.headers[header] = self.headers[header] # Add in any cached items with self.cache_lock: req.cache = self.session if self.session.has_key('user'): req._user = self.session['user'] # Execute the application try: # Run the request self.request['app'].handle(req, resp) # Handle any caching with self.cache_lock: if req.user: self.session['user'] = req.user for item in req.cache: self.session[item] = req.cache[item] # Return the response if 'json' in resp.content_type: for line in resp.app_iter: if not self.socket.connected: log.error('Client unexpectedly disconnected') return if line: for item in line.split('\r\n'): if item: data = json.loads(item) self.emit('data', { 'msg_id': msg_id, 'msg': data }) else: self.emit('data', {'msg_id': msg_id, 'msg': resp.body}) except HTTPException, e: self.emit('err', { 'msg_id': msg_id, 'code': e.code, 'msg': str(e) }) log.error('Error "%s" processing command: %s %s %s' % (str(e), method, args, path)) except Exception, e: self.emit('err', { 'msg_id': msg_id, 'code': 500, 'msg': str(e) }) log.exception('Unhandled Error processing: %s' % args)
def test_handle_post_with_args_and_id(self): r = Request.blank("/foo/my_object_id?bar=biz&diz=dazzle") r.method = "POST" content = self.url_mapper.handle(r, Response()) assert(content.body == "<string>POST: my_object_id</string>")