Exemple #1
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)
Exemple #2
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)