Exemple #1
0
 def import_services(self, service_list):
     # Fix that eliminates the need for exec()
     # contributed by: Tamás Gulácsi
     for service in service_list:
         m = __import__(service)
         sfile = inspect.getsourcefile(m)
         for skey, smi in global_service_collection().services.items():
             for method_name, lmi in list(smi.methods.items()):
                 task_rtype = getattr(lmi, '_task_rtype', None)
                 if task_rtype != None:
                     if skey[0] == sfile:
                         cls = getattr(m, skey[1])
                         setattr(cls, "%s_progress" % method_name,
                                 tt.taskProgress)
                         lmi.sinfo.add_method(
                             tt.taskProgress, *(int, ),
                             **dict(
                                 list(tt.taskProgress_kw.items()) +
                                 [('override_method_name',
                                   "%s_progress" % method_name)]))
                         setattr(cls, "%s_result" % method_name,
                                 tt.taskResult)
                         lmi.sinfo.add_method(
                             tt.taskResult, *(int, ), **{
                                 'override_method_name':
                                 "%s_result" % method_name,
                                 'rtype': task_rtype
                             })
                         setattr(
                             cls, "_task_%s" % method_name,
                             copyFunction(getattr(cls, method_name),
                                          "_task_%s" % method_name))
                         setattr(cls, method_name,
                                 copyFunction(tt.taskStarter, method_name))
Exemple #2
0
def NamedServiceView(service_name,interface,request=request):
    from ladon.ladonizer.collection import global_service_collection
    '''获取请求的service实例'''
    service_search = global_service_collection().services_by_name(service_name)
    if not len(service_search):
        return  getJSResponse(u'Service "%s" has not been exposed' % service_name)
    else:
        sinst = service_search[0]
        return ServiceInstanceView(request,sinst,interface)
Exemple #3
0
def NamedServiceView(service_name, interface, request=request):
    from ladon.ladonizer.collection import global_service_collection
    '''获取请求的service实例'''
    service_search = global_service_collection().services_by_name(service_name)
    if not len(service_search):
        return getJSResponse(u'Service "%s" has not been exposed' %
                             service_name)
    else:
        sinst = service_search[0]
        return ServiceInstanceView(request, sinst, interface)
Exemple #4
0
def NamedSoapView(service_name,request=request):
    from ladon.ladonizer.collection import global_service_collection
    '''获取请求的service实例'''
    service_search = global_service_collection().services_by_name(service_name)
    if not len(service_search):
        return  getJSResponse(u'Service "%s" has not been exposed' % service_name)
    else:
        sinst = service_search[0]
        service_info = generate_service(sinst)
        ex = DJANGO_MODEL and '_django' or ''
        return render_to_response('service_index%s.html'%ex, RequestContext(request,service_info))
Exemple #5
0
def NamedSoapView(service_name, request=request):
    from ladon.ladonizer.collection import global_service_collection
    '''获取请求的service实例'''
    service_search = global_service_collection().services_by_name(service_name)
    if not len(service_search):
        return getJSResponse(u'Service "%s" has not been exposed' %
                             service_name)
    else:
        sinst = service_search[0]
        service_info = generate_service(sinst)
        ex = DJANGO_MODEL and '_django' or ''
        return render_to_response('service_index%s.html' % ex,
                                  RequestContext(request, service_info))
Exemple #6
0
	def decorator(f):
		def injector(*args,**kw):
			"""
			The Ladon inner injection function is called from the dispatcher. It does run-time type
			checking against the types registered with the service method. If everything is OK the
			user method is called. The result of the userspace-method is then checked before it is
			passed back to the dispatcher.
			"""
			
			# Get the LadonMethodInfo object generated at parsetime which is stored as a member
			# on the function object
			lmi = injector._ladon_method_info
			# Reference the incomming arguments in callargs (filter out the function reference)
			callargs = args[1:]
			
			for argidx in range(len(callargs)):
				# Check the type of each argument against the type which the method has been 
				# registered to take in the order-wise corresponding argument
				if not validate_type(lmi._arg_types[argidx],callargs[argidx]):
					# Raise ArgTypeMismatch
					raise ArgTypeMismatch(
						lmi.sinfo,
						lmi._func_name,
						lmi._arg_names[argidx],
						lmi._arg_types[argidx],
						type(callargs[argidx]))
			
			# Call the userspace service method (**kw will be used to transport Ladon info
			# and tools all the way to userspace of the service method. I.e. the TypeConverter
			# is passed with the keyword "LADON_METHOD_TC")
			res = f(*args,**kw)
			
			# Check the return type
			if not validate_type(lmi._rtype,res):
				# Raise Arg-type mismatch 
				raise ReturnTypeMismatch(lmi.sinfo,lmi._func_name,lmi._rtype,type(res))
			
			# Return the result to the dispatcher
			return res
		
		# Register the service method and all the types required by it 
		ladon_method_info = global_service_collection().add_service_method(f,*def_args,**def_kw)
		
		# store the LadonMethodInfo object directly on the fuction object
		injector._ladon_method_info = ladon_method_info
		injector.__doc__ = ladon_method_info._doc
		injector.func_name = ladon_method_info._func_name
		return injector
Exemple #7
0
    def decorator(f):
        def injector(*args, **kw):
            """
			The Ladon inner injection function is called from the dispatcher. It does run-time type
			checking against the types registered with the service method. If everything is OK the
			user method is called. The result of the userspace-method is then checked before it is
			passed back to the dispatcher.
			"""

            # Get the LadonMethodInfo object generated at parsetime which is stored as a member
            # on the function object
            lmi = injector._ladon_method_info
            # Reference the incomming arguments in callargs (filter out the function reference)
            callargs = args[1:]

            for argidx in range(len(callargs)):
                # Check the type of each argument against the type which the method has been
                # registered to take in the order-wise corresponding argument
                if not validate_type(lmi._arg_types[argidx], callargs[argidx]):
                    # Raise ArgTypeMismatch
                    raise ArgTypeMismatch(lmi.sinfo, lmi._func_name,
                                          lmi._arg_names[argidx],
                                          lmi._arg_types[argidx],
                                          type(callargs[argidx]))

            # Call the userspace service method (**kw will be used to transport Ladon info
            # and tools all the way to userspace of the service method. I.e. the TypeConverter
            # is passed with the keyword "LADON_METHOD_TC")
            res = f(*args, **kw)

            # Check the return type
            if not validate_type(lmi._rtype, res):
                # Raise Arg-type mismatch
                raise ReturnTypeMismatch(lmi.sinfo, lmi._func_name, lmi._rtype,
                                         type(res))

            # Return the result to the dispatcher
            return res

        # Register the service method and all the types required by it
        ladon_method_info = global_service_collection().add_service_method(
            f, *def_args, **def_kw)

        # store the LadonMethodInfo object directly on the fuction object
        injector._ladon_method_info = ladon_method_info
        injector.__doc__ = ladon_method_info._doc
        injector.func_name = ladon_method_info._func_name
        return injector
Exemple #8
0
def ServiceList(request=request):
    from ladon.ladonizer.collection import global_service_collection
    '''获取请求的service实例'''
    services = global_service_collection().services
    catalog_name = u"PyWebSV Web服务接口"
    catalog_desc = u'''1. 一个在python (Django或Mole) 环境下快速构建 webservice 的工具库<br><br>
    2. 同时提供 SOAP 和 JSON 的支持,前端即可通过JS来调用,JSON调用<a href='/rpc_static/demo1.jpg'>Demo</a>,SOAP调用<a href='/rpc_static/demo2.jpg'>Demo</a><br><br>
    3. 打开调试模式即可在线在web界面调用接口方法 ( 通过js走Json通道 )<br><br>
    '''
    catalog_info = {
        'catalog_name': catalog_name,
        'catalog_desc': catalog_desc,
        'charset': 'utf-8',
        'services': services.values()
    }
    ex = DJANGO_MODEL and '_django' or ''
    return render_to_response('service_list%s.html'%ex, RequestContext(request,catalog_info))
Exemple #9
0
def ServiceList(request=request):
    from ladon.ladonizer.collection import global_service_collection
    '''获取请求的service实例'''
    services = global_service_collection().services
    catalog_name = u"PyWebSV Web服务接口"
    catalog_desc = u'''1. 一个在python (Django或Mole) 环境下快速构建 webservice 的工具库<br><br>
    2. 同时提供 SOAP 和 JSON 的支持,前端即可通过JS来调用,JSON调用<a href='/rpc_static/demo1.jpg'>Demo</a>,SOAP调用<a href='/rpc_static/demo2.jpg'>Demo</a><br><br>
    3. 打开调试模式即可在线在web界面调用接口方法 ( 通过js走Json通道 )<br><br>
    '''
    catalog_info = {
        'catalog_name': catalog_name,
        'catalog_desc': catalog_desc,
        'charset': 'utf-8',
        'services': services.values()
    }
    ex = DJANGO_MODEL and '_django' or ''
    return render_to_response('service_list%s.html' % ex,
                              RequestContext(request, catalog_info))
Exemple #10
0
    def __call__(self, environ, start_response):
        status = '200 OK'
        response_headers = []
        content_type = 'text/plain'
        output = ''
        charset = probe_charset(environ, default='UTF-8')
        languages = probe_language(environ, default=['en'])

        try:
            fault_hint = 'Processing request (further details)'
            sname, ifname, action, multipart, boundary = self.parse_environ(
                environ)
            client_path = probe_client_path(environ)
            query = parse_qs(environ['QUERY_STRING'])
            if sname in self.reserved_roots:
                fault_hint = 'Attempting to fetch server-side static skin-data at location: "%s"' % environ[
                    'PATH_INFO']
                if sname == 'skins':
                    data = read_data_file(start_response, environ['PATH_INFO'],
                                          self.path_list)
                    return [data]

            sinst = ifclass = None
            if ifname:
                fault_hint = 'Searching for the interface called "%s"' % ifname
                ifclass = name_to_interface(ifname)
                if not ifclass:
                    raise UndefinedInterfaceName(
                        ifname,
                        'The interface name "%s" has not been defined' %
                        ifname)

            if sname:
                fault_hint = 'Searching for the service-class: "%s"' % sname
                service_search = global_service_collection().services_by_name(
                    sname)
                if not len(service_search):
                    raise UndefinedService(
                        ifname, 'Service "%s" has not been exposed' % sname)
                sinst = service_search[0]

            dispatcher = None
            if sinst and ifclass:
                fault_hint = 'Instantiating dispatcher for "%s"' % sname
                dispatcher = Dispatcher(sinst, ifclass, charset, languages,
                                        self.logging)
            elif not sname:
                fault_hint = 'Generating service catalog'
                content_type = 'text/html'
                skin = query.get('skin', [None])[0]
                output = self.generate_catalog_html(
                    global_service_collection().services, client_path,
                    self.catalog_name, self.catalog_desc, charset, languages,
                    skin)
            elif sinst and not ifname:
                fault_hint = 'Generating service API HTML for "%s"' % sname
                content_type = 'text/html'
                skin = query.get('skin', [None])[0]
                output = self.generate_service_html(sinst, client_path,
                                                    charset, languages, skin)

            if dispatcher and dispatcher.iface:
                if action == 'description':
                    fault_hint = 'Generating "%s" description for "%s"' % (
                        ifname, sname)
                    content_type = dispatcher.iface.description_content_type()
                    service_url = client_path[0:client_path.find('/description'
                                                                 )]
                    output += dispatcher.iface.description(
                        service_url, charset,
                        **dict(map(lambda x: (x[0], x[1][0]), query.items())))
                else:
                    fault_hint = 'Checking method call request via "%s" on "%s"' % (
                        ifname, sname)
                    allowed_methods = ['POST']
                    if environ[
                            'REQUEST_METHOD'] not in allowed_methods or not environ.get(
                                'CONTENT_LENGTH', ''):
                        message = 'Requests for %s %s interface must be posted' % (
                            sname, ifname)
                        status = '405 %s' % message
                        response_headers.append(
                            ('Allow', ','.join(allowed_methods)))
                        output += message
                    else:
                        fault_hint = 'Preparing "%s" call to "%s"' % (ifname,
                                                                      sname)
                        content_type = dispatcher.iface.response_content_type()
                        content_length = int(environ['CONTENT_LENGTH'])
                        if multipart and boundary:
                            fault_hint = 'Parsing incoming multipart request and attachments'
                            mph = MultiPartReader(20000,
                                                  boundary.encode(charset),
                                                  environ['wsgi.input'],
                                                  content_length)
                            mph.read_chunk()
                            while not mph.eos:
                                mph.read_chunk()
                            encapsulated_charset = probe_charset(
                                mph.interface_request_headers, default=None)
                            request_data = mph.interface_request
                            if encapsulated_charset:
                                # If a specific charset is/usr/local/bin/rdesktop specified for the interface request multipart
                                # let this charset superseed the charset globally specified for the request.
                                dispatcher.response_encoding = encapsulated_charset

                            environ['attachments'] = mph.attachments
                            environ[
                                'attachments_by_id'] = mph.attachments_by_id
                        else:
                            request_data = environ['wsgi.input'].read(
                                content_length)
                        fault_hint = 'Passing request on to the dispatcher'
                        response_part = dispatcher.dispatch_request(
                            request_data, environ)
                        if isinstance(response_part, CustomResponse):
                            response_headers += response_part.response_headers(
                            )
                            start_response(status, response_headers)
                            return response_part.response_data()
                        elif len(environ['response_attachments'].
                                 attachments_by_cid):
                            # Attachments present - Send multipart response
                            response_temp_fname = tempfile.mktemp()
                            temp_buffer = open(response_temp_fname, 'wb')
                            mpw = MultiPartWriter(temp_buffer,
                                                  header_encoding=charset)
                            mpw.add_attachment(
                                response_part,
                                '%s, charset=%s' % (content_type, charset),
                                'rpc-part')
                            for cid, a in environ[
                                    'response_attachments'].attachments_by_cid.items(
                                    ):
                                mpw.add_attachment(a,
                                                   'application/octet-stream',
                                                   cid, a.headers)
                            mpw.done()
                            temp_buffer.close()
                            content_length = str(
                                os.stat(response_temp_fname).st_size)
                            output = open(response_temp_fname, 'rb')
                            if sys.version_info[0] == 2:
                                content_type = "multipart/related; boundary=" + mpw.boundary
                            elif sys.version_info[0] >= 3:
                                content_type = "multipart/related; boundary=" + str(
                                    mpw.boundary, 'iso-8859-1')

                        else:
                            # No attachments - Send normal response
                            output = response_part

            if 'attachments' in environ:
                for a_id, a_info in environ['attachments'].items():
                    if os.path.exists(a_info['path']):
                        os.unlink(a_info['path'])

        except Exception as e:
            status = '500 An Error occured while processing the request'
            content_type = 'text/plain'
            strio = StringIO()
            traceback.print_exc(file=strio)
            output = strio.getvalue()
            output += "\nHint: " + fault_hint

        if not hasattr(output, 'read'):
            # not file-like object
            content_length = str(len(output))

        response_headers += [('Content-Type',
                              "%s; charset=%s" % (content_type, charset)),
                             ('Content-Length', content_length)]
        start_response(status, response_headers)

        if hasattr(output, 'read'):
            # File-like object
            block_size = 4096
            if 'wsgi.file_wrapper' in environ:
                return environ['wsgi.file_wrapper'](output, block_size)
            else:
                return iter(lambda: output.read(block_size), '')

        if sys.version_info[0] >= 3:
            # Python 3 support
            if type(output) == str:
                output = bytes(output, charset)

        return [output]
Exemple #11
0
	def __call__(self,environ, start_response):
		''' wsgi 应用执行 '''
		status = '200 OK'
		response_headers = []
		content_type = 'text/plain'
		output = ''
		charset = probe_charset(environ,default='UTF-8')

		try:
			self.import_services(self.service_list)
			''' 得到客户端请求的信息 '''
			sname,ifname,action,multipart,boundary = self.parse_environ(environ)
			client_path = probe_client_path(environ)
			print 'Jone@-------',sname,ifname,action,multipart,boundary
			print 'Jone@-------',client_path
			sinst = ifclass = None
			if ifname:
				'''检验请求的协议是否合法 soap/jsonwsp'''
				ifclass = name_to_interface(ifname)
				if not ifclass:
					raise UndefinedInterfaceName(ifname,'The interface name "%s" has not been defined' % ifname)

			if sname:
				'''获取请求的service实例'''
				service_search = global_service_collection().services_by_name(sname)
				if not len(service_search):
					raise UndefinedService(ifname,'Service "%s" has not been exposed' % sname)
				sinst = service_search[0]
				
			'''{'doc_lines': ['This service does the math, and serves as example for new potential Ladon users.'],
			 'methods': {'add': <ladon.ladonizer.collection.LadonMethodInfo object at 0x01069EB0>},
			 'servicename': 'Calculator',
			 'sourcefile': 'E:\\open-source\\ladon-0.7.0\\jone_demo\\examples\\services\\calculator.py'}'''
			 
			dispatcher = None
			if sinst and ifclass:
				dispatcher = Dispatcher(sinst,ifclass,charset)
			elif not sname:
				''' 首页'''
				content_type = 'text/html'
				output = self.generate_catalog_html(
					global_service_collection().services,
					client_path,
					self.catalog_name,
					self.catalog_desc,charset)
			elif sinst and not ifname:
				'''service 实例首页'''
				content_type = 'text/html'
				query = parse_qs(urlparse(client_path).query)
				skin = query.get('skin', [None])[0]
				output = self.generate_service_html(sinst,client_path,charset,skin)
			
			if dispatcher and dispatcher.iface:
				if action=='description':
					content_type = dispatcher.iface.description_content_type()
					service_url = client_path[0:client_path.find('/description')]
					output += dispatcher.iface.description(service_url,charset)
				else:
					allowed_methods = ['POST']
					if environ['REQUEST_METHOD'] not in allowed_methods or not environ.get('CONTENT_LENGTH', ''):
						message = 'Requests for %s %s interface must be posted' % (sname,ifname)
						status = '405 %s' % message
						response_headers.append(('Allow', ','.join(allowed_methods)))
						output += message
					else:
						content_type = dispatcher.iface.response_content_type()
						content_length = int(environ['CONTENT_LENGTH'])
						if multipart and boundary:
							mph = MultiPartReader(20000,boundary.encode(charset),environ['wsgi.input'],content_length)
							mph.read_chunk()
							while not mph.eos:
								mph.read_chunk()
							encapsulated_charset = probe_charset(mph.interface_request_headers,default=None)
							request_data = mph.interface_request
							if encapsulated_charset:
								# If a specific charset is/usr/local/bin/rdesktop specified for the interface request multipart
								# let this charset superseed the charset globally specified for the request.
								dispatcher.response_encoding = encapsulated_charset
							
							environ['attachments'] = mph.attachments
							environ['attachments_by_id'] = mph.attachments_by_id
						else:
							request_data = environ['wsgi.input'].read(content_length)
						response_part = dispatcher.dispatch_request(request_data,environ)
						if isinstance(response_part,CustomResponse):
							print 'AAAAAAAAAAAAAAA'
							response_headers += response_part.response_headers()
							start_response(status, response_headers)
							return response_part.response_data()
						elif len(environ['response_attachments'].attachments_by_cid):
							print 'BBBBBBBBBBBBBBB'
							# Attachments present - Send multipart response
							response_temp_fname = tempfile.mktemp()
							temp_buffer = open(response_temp_fname,'wb')
							mpw = MultiPartWriter(temp_buffer)
							mpw.add_attachment(response_part,'%s, charset=%s' % (content_type,charset),'rpc-part')
							for cid,a in environ['response_attachments'].attachments_by_cid.items():
								mpw.add_attachment(a,'application/octet-stram',cid,a.headers)
							mpw.done()
							temp_buffer.close()
							content_length = str(os.stat(response_temp_fname).st_size)
							output = open(response_temp_fname,'rb')
							if sys.version_info[0]==2:
								content_type = "multipart/related; boundary=" + mpw.boundary
							elif sys.version_info[0]>=3:
								content_type = "multipart/related; boundary=" + str(mpw.boundary,'iso-8859-1')
							
						else:
							print 'CCCCCCCCCCCCCCCCCCC'
							# No attachments - Send normal response
							output = response_part
		
		except Exception as e:
			status = '500 An Error occured while processing the request' 
			content_type = 'text/plain'
			strio = StringIO()
			traceback.print_exc(file=strio)
			output = strio.getvalue()
		
		if 'attachments_by_id' in environ:
			for a_id,a_info in environ['attachments_by_id'].items():
				os.unlink(a_info['path'])

		if not hasattr(output,'read'):
			# not file-like object
			content_length = str(len(output))

		response_headers += [
			('Content-Type', "%s; charset=%s" % (content_type,charset)),
			('Content-Length', content_length)
		]
		start_response(status, response_headers)

		if hasattr(output,'read'):
			# File-like object
			block_size = 4096
			if 'wsgi.file_wrapper' in environ:
				return environ['wsgi.file_wrapper'](output, block_size)
			else:
				return iter(lambda: output.read(block_size), '')
		
		if sys.version_info[0]>=3:
			# Python 3 support
			if type(output)==str:
				output = bytes(output,charset)

		return [output]
    def __call__(self, environ, start_response):
        ''' wsgi 应用执行 '''
        status = '200 OK'
        response_headers = []
        content_type = 'text/plain'
        output = ''
        charset = probe_charset(environ, default='UTF-8')

        try:
            self.import_services(self.service_list)
            ''' 得到客户端请求的信息 '''
            sname, ifname, action, multipart, boundary = self.parse_environ(
                environ)
            client_path = probe_client_path(environ)
            print 'Jone@-------', sname, ifname, action, multipart, boundary
            print 'Jone@-------', client_path
            sinst = ifclass = None
            if ifname:
                '''检验请求的协议是否合法 soap/jsonwsp'''
                ifclass = name_to_interface(ifname)
                if not ifclass:
                    raise UndefinedInterfaceName(
                        ifname,
                        'The interface name "%s" has not been defined' %
                        ifname)

            if sname:
                '''获取请求的service实例'''
                service_search = global_service_collection().services_by_name(
                    sname)
                if not len(service_search):
                    raise UndefinedService(
                        ifname, 'Service "%s" has not been exposed' % sname)
                sinst = service_search[0]
            '''{'doc_lines': ['This service does the math, and serves as example for new potential Ladon users.'],
			 'methods': {'add': <ladon.ladonizer.collection.LadonMethodInfo object at 0x01069EB0>},
			 'servicename': 'Calculator',
			 'sourcefile': 'E:\\open-source\\ladon-0.7.0\\jone_demo\\examples\\services\\calculator.py'}'''

            dispatcher = None
            if sinst and ifclass:
                dispatcher = Dispatcher(sinst, ifclass, charset)
            elif not sname:
                ''' 首页'''
                content_type = 'text/html'
                output = self.generate_catalog_html(
                    global_service_collection().services, client_path,
                    self.catalog_name, self.catalog_desc, charset)
            elif sinst and not ifname:
                '''service 实例首页'''
                content_type = 'text/html'
                query = parse_qs(urlparse(client_path).query)
                skin = query.get('skin', [None])[0]
                output = self.generate_service_html(sinst, client_path,
                                                    charset, skin)

            if dispatcher and dispatcher.iface:
                if action == 'description':
                    content_type = dispatcher.iface.description_content_type()
                    service_url = client_path[0:client_path.find('/description'
                                                                 )]
                    output += dispatcher.iface.description(
                        service_url, charset)
                else:
                    allowed_methods = ['POST']
                    if environ[
                            'REQUEST_METHOD'] not in allowed_methods or not environ.get(
                                'CONTENT_LENGTH', ''):
                        message = 'Requests for %s %s interface must be posted' % (
                            sname, ifname)
                        status = '405 %s' % message
                        response_headers.append(
                            ('Allow', ','.join(allowed_methods)))
                        output += message
                    else:
                        content_type = dispatcher.iface.response_content_type()
                        content_length = int(environ['CONTENT_LENGTH'])
                        if multipart and boundary:
                            mph = MultiPartReader(20000,
                                                  boundary.encode(charset),
                                                  environ['wsgi.input'],
                                                  content_length)
                            mph.read_chunk()
                            while not mph.eos:
                                mph.read_chunk()
                            encapsulated_charset = probe_charset(
                                mph.interface_request_headers, default=None)
                            request_data = mph.interface_request
                            if encapsulated_charset:
                                # If a specific charset is/usr/local/bin/rdesktop specified for the interface request multipart
                                # let this charset superseed the charset globally specified for the request.
                                dispatcher.response_encoding = encapsulated_charset

                            environ['attachments'] = mph.attachments
                            environ[
                                'attachments_by_id'] = mph.attachments_by_id
                        else:
                            request_data = environ['wsgi.input'].read(
                                content_length)
                        response_part = dispatcher.dispatch_request(
                            request_data, environ)
                        if isinstance(response_part, CustomResponse):
                            print 'AAAAAAAAAAAAAAA'
                            response_headers += response_part.response_headers(
                            )
                            start_response(status, response_headers)
                            return response_part.response_data()
                        elif len(environ['response_attachments'].
                                 attachments_by_cid):
                            print 'BBBBBBBBBBBBBBB'
                            # Attachments present - Send multipart response
                            response_temp_fname = tempfile.mktemp()
                            temp_buffer = open(response_temp_fname, 'wb')
                            mpw = MultiPartWriter(temp_buffer)
                            mpw.add_attachment(
                                response_part,
                                '%s, charset=%s' % (content_type, charset),
                                'rpc-part')
                            for cid, a in environ[
                                    'response_attachments'].attachments_by_cid.items(
                                    ):
                                mpw.add_attachment(a,
                                                   'application/octet-stram',
                                                   cid, a.headers)
                            mpw.done()
                            temp_buffer.close()
                            content_length = str(
                                os.stat(response_temp_fname).st_size)
                            output = open(response_temp_fname, 'rb')
                            if sys.version_info[0] == 2:
                                content_type = "multipart/related; boundary=" + mpw.boundary
                            elif sys.version_info[0] >= 3:
                                content_type = "multipart/related; boundary=" + str(
                                    mpw.boundary, 'iso-8859-1')

                        else:
                            print 'CCCCCCCCCCCCCCCCCCC'
                            # No attachments - Send normal response
                            output = response_part

        except Exception as e:
            status = '500 An Error occured while processing the request'
            content_type = 'text/plain'
            strio = StringIO()
            traceback.print_exc(file=strio)
            output = strio.getvalue()

        if 'attachments_by_id' in environ:
            for a_id, a_info in environ['attachments_by_id'].items():
                os.unlink(a_info['path'])

        if not hasattr(output, 'read'):
            # not file-like object
            content_length = str(len(output))

        response_headers += [('Content-Type',
                              "%s; charset=%s" % (content_type, charset)),
                             ('Content-Length', content_length)]
        start_response(status, response_headers)

        if hasattr(output, 'read'):
            # File-like object
            block_size = 4096
            if 'wsgi.file_wrapper' in environ:
                return environ['wsgi.file_wrapper'](output, block_size)
            else:
                return iter(lambda: output.read(block_size), '')

        if sys.version_info[0] >= 3:
            # Python 3 support
            if type(output) == str:
                output = bytes(output, charset)

        return [output]
Exemple #13
0
    def decorator(f):
        def injector(*args, **kw):
            """
			The Ladon inner injection function is called from the dispatcher. It does run-time type
			checking against the types registered with the service method. If everything is OK the
			user method is called. The result of the userspace-method is then checked before it is
			passed back to the dispatcher.
			"""

            if def_kw.get('tasktype', False) == True:
                return f(*args, **kw)

            # Get the LadonMethodInfo object generated at parsetime which is stored as a member
            # on the function object
            lmi = injector._ladon_method_info
            # Reference the incomming arguments in callargs (filter out the function reference)
            callargs = args[1:]

            for argidx in range(len(callargs)):
                # Check the type of each argument against the type which the method has been
                # registered to take in the order-wise corresponding argument
                if not validate_type(lmi._arg_types[argidx], callargs[argidx]):
                    # Raise ArgTypeMismatch
                    raise ArgTypeMismatch(lmi.sinfo, lmi._func_name,
                                          lmi._arg_names[argidx],
                                          lmi._arg_types[argidx],
                                          type(callargs[argidx]))

            # Call the userspace service method (**kw will be used to transport Ladon info
            # and tools all the way to userspace of the service method. I.e. the TypeConverter
            # is passed with the keyword "LADON_METHOD_TC")
            debug_mode = log.get_loglevel() >= 6
            if debug_mode:
                # Build a request_dict for debugging
                req_dict = {}
                for argidx in range(len(callargs)):
                    req_dict[lmi._arg_names[argidx]] = expand_value(
                        callargs[argidx],
                        lmi._arg_types[argidx],
                        service_name=lmi.sinfo.servicename,
                        method_name=lmi._func_name)
                log_line = [
                    'Method:%s.%s' % (lmi.sinfo.servicename, lmi._func_name),
                    'RequestArgs:%s' % str(req_dict),
                    'RequestKeywordArgs:%s' % str(kw)
                ]

            if debug_mode:
                try:
                    start = time.time()
                    res = f(*args, **kw)
                    log_line.insert(
                        0, 'ExecutionTime:%s' % str(time.time() - start))
                except Exception as e:
                    log_line += ['Exception:%s' % str((log.get_traceback(), ))]
                    log.debug('\t%s' % ('\t'.join(log_line)))
                    raise e

                log_line += ['ReturnValue:%s' % str(result_to_dict(lmi, res))]
                log.debug('\t%s' % ('\t'.join(log_line)))

            else:
                res = f(*args, **kw)
            # Check the return type
            if not validate_type(lmi._rtype, res):
                # Raise Arg-type mismatch
                raise ReturnTypeMismatch(lmi.sinfo, lmi._func_name, lmi._rtype,
                                         type(res))

            # Return the result to the dispatcher
            return res

        # Register the service method and all the types required by it
        ladon_method_info = global_service_collection().add_service_method(
            f, *def_args, **def_kw)

        # store the LadonMethodInfo object directly on the fuction object
        injector._ladon_method_info = ladon_method_info
        injector.__doc__ = ladon_method_info._doc
        injector.func_name = ladon_method_info._func_name
        return injector