Example #1
0
    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())
Example #2
0
    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())
Example #3
0
    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>")
Example #4
0
	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>")
Example #5
0
    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>")
Example #6
0
	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)
Example #7
0
 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)
Example #8
0
 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)
Example #9
0
 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)
Example #10
0
 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>")
Example #11
0
	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)
Example #12
0
	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)
Example #13
0
	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)
Example #14
0
	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)
Example #15
0
	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)
Example #16
0
 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)
Example #17
0
    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)
Example #18
0
	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>")