Beispiel #1
0
 def parse_response(self, response):
     headers = dict((k.upper(), v) for k, v in response.getheaders())
     jsonwsp_response = JSONWSPResponse(response.status, response.reason,
                                        headers)
     jsonwsp_charset = probe_charset(jsonwsp_response.headers)
     content_type = response.getheader('content-type')
     content_type = content_type.replace('\n', '')
     multipart_match = rx_detect_multipart.findall(content_type)
     if len(multipart_match):
         multipart = multipart_match[0]
         boundary_match = rx_detect_boundary.findall(content_type)
         if len(boundary_match):
             boundary = boundary_match[0]
             mpr = MultiPartReader(20000, boundary.encode(jsonwsp_charset),
                                   response)
             mpr.read_chunk()
             while not mpr.eos:
                 mpr.read_chunk()
             for cid, cinfo in mpr.attachments_by_id.items():
                 jsonwsp_response.attachments[PORTABLE_STRING(
                     cid, jsonwsp_charset)] = attachment(
                         open(cinfo['path'], 'rb'), cinfo['size'],
                         cinfo['headers'], jsonwsp_charset)
             resdata = mpr.interface_request
             jsonwsp_response.response_body = resdata
     else:
         resdata = response.read()
         jsonwsp_response.response_body = resdata
     return jsonwsp_response
    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]
Beispiel #3
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]
Beispiel #4
0
def ServiceInstanceView(request, sinst, interface):
    from ladon.interfaces import name_to_interface
    from ladon.server.dispatcher import Dispatcher
    from ladon.server.customresponse import CustomResponse
    from ladon.tools.multiparthandler import MultiPartReader, MultiPartWriter
    try:
        '''检验请求的协议是否合法 soap/jsonwsp'''
        ifclass = name_to_interface(interface)
        if ifclass:
            charset = get_charset(request.environ, default='UTF-8')
            dispatcher = Dispatcher(sinst, ifclass, charset, 0)  #获得此服务调度器
            if dispatcher and dispatcher.iface:
                if request.path.endswith(
                        'description/') or request.path.endswith(
                            'description'):
                    '''描述视图'''
                    content_type = dispatcher.iface.description_content_type()
                    service_url = 'http://%s%s' % (
                        request.environ["HTTP_HOST"],
                        request.path.replace('/description/', '').replace(
                            '/description', ''))
                    m_content = dispatcher.iface.description(
                        service_url, charset)
                    return HttpResponse(m_content, content_type=content_type)
                else:
                    '''执行视图'''
                    if request.method == "POST":
                        content_type = dispatcher.iface.response_content_type()
                        environ = request.environ

                        content_length = int(environ.get(
                            'CONTENT_LENGTH', '0'))
                        multipart, boundary = parse_environ(environ)
                        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 = get_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:
                            if DJANGO_MODEL:
                                request_data = request.raw_post_data
                            else:
                                request_data = environ['wsgi.input'].read(
                                    content_length)
                        if EnvelopeDebug:
                            print '>>>receive envelope: \n'
                            print request_data
                            print '<<<'

                        response_part = dispatcher.dispatch_request(
                            request_data, environ)  #解析、返回信封

                        if EnvelopeDebug:
                            print '>>>return envelope: \n'
                            print response_part
                            print '<<<'
                        if isinstance(response_part, CustomResponse):
                            ''' 返回自定义视图 '''
                            response_headers = response_part.response_headers()
                            response = HttpResponse(
                                response_part.response_data(),
                                content_type=content_type)
                            for k, v in response_headers:
                                response._iterator[k.lower()] = (k, v)
                            return response
                        elif len(environ['response_attachments'].
                                 attachments_by_cid
                                 ):  #返回文件的标记 response_attachments
                            ''' 文件下载 '''
                            # Attachments present - Send multipart response
                            import tempfile
                            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')

                            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 HttpResponse(
                                        iter(lambda: output.read(block_size),
                                             ''),
                                        content_type=content_type)

                        else:
                            ''' 返回文本内容 '''
                            # No attachments - Send normal response
                            return HttpResponse(response_part,
                                                content_type=content_type)
                        if 'attachments_by_id' in environ:
                            for a_id, a_info in environ[
                                    'attachments_by_id'].items():
                                os.unlink(a_info['path'])
                    else:
                        return getJSResponse(
                            u'Requests for %s interface must be posted' %
                            interface)
            else:
                return getJSResponse(
                    u'There is something error in The interface "%s"' %
                    interface)
        else:
            return getJSResponse(
                u'The interface name "%s" has not been defined' % interface)
    except:
        import traceback
        traceback.print_exc()
        return HttpResponseServerError(
            u'An Error occured while processing the request')