对flash消息的zope支持(amf)
z3c.amf的Python项目详细描述
Zope 2中的AMF/Flash支持
简介
这个包允许您使用flex从flash中查询zope 2
动作脚本2或动作脚本3到AMF0或AMF3。
我们只是在这里提供Zope层。下层已经完成
使用pyamf包(请参见http://pyamf.org)。
让我们编写一个简单的AMF视图,它可以响应各种类型的输入:
>>> from Products.Five import BrowserView
>>> from datetime import datetime
>>> import elementtree.ElementTree as etree
>>> class EchoView(BrowserView):
...
... def echoString(self, value):
... return "%s" % value
...
... def echoProtectedString(self, value):
... return "%s" % value
...
... def echoList(self, value):
... return list(value)
...
... def echoDict(self, value):
... return dict(value)
...
... def echoVoid(self, value):
... pass
...
... def echoTuple(self, value):
... return tuple(value)
...
... def echoParams(self, value1, value2):
... return "%s-%s" % (value1, value2)
...
... def echoDate(self):
... return datetime(2008, 11, 17, 11, 11)
...
... def echoXML(self, value):
... root = etree.Element("html")
... body = etree.SubElement(root, 'body')
... body.text = value
... return root
现在我们将其注册为flash视图。现在我们只需注册
查看文件夹对象并在用户的默认文件夹上调用它:
>>> from zope.configuration import xmlconfig
>>> ignored = xmlconfig.string("""
... <configure
... xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser"
... xmlns:flash="http://namespaces.zope.org/flash"
... >
...
... <include package="z3c.amf" file="meta.zcml" />
... <include package="Products.Five" file="meta.zcml" />
... <include package="z3c.amf" />
...
... <flash:view
... for="OFS.interfaces.IFolder"
... methods="echoString echoList echoDict echoVoid echoTuple
... echoDate echoXML echoParams"
... class="z3c.amf.README.EchoView"
... permission="zope.Public"
... />
...
... <flash:view
... for="OFS.interfaces.IFolder"
... methods="echoProtectedString"
... class="z3c.amf.README.EchoView"
... permission="zope2.FlashAccess"
... />
...
... </configure>
... """)
我们创建了一些助手函数。
对于请求:
>>> def createAMFRequest(target, body, username=None, password=None, multiParameters=False):
... envelope = remoting.Envelope(pyamf.AMF0, pyamf.ClientTypes.Flash9)
... if username is not None and password is not None:
... envelope.headers['Credentials'] = dict(userid=unicode(username),
... password=unicode(password))
... if multiParameters:
... request = remoting.Request(target, body, envelope)
... else:
... request = remoting.Request(target, [body], envelope)
... envelope[u'/1'] = request
... amfRequest = remoting.encode(envelope)
... amfRequest.seek(0)
... return amfRequest.read()
回复:
>>> import pyamf
>>> from pyamf import remoting
>>> def printAMFResponse(response):
... context = pyamf.amf0.Context
... requests = remoting.decode(response.body, context())
... for name, value in requests.items():
... print (name, value, type(value.body))
基本类型
字符串
>>> amfRequest = createAMFRequest(target='echoString', body='Hello World!')
>>> amfRequest
'\x00\x03\x00\x00\x00\x01\x00\nechoString\x00\x02/1\x00\x00\x00\x00\n\x00\x00\x00\x01\x02\x00\x0cHello World!'
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>Hello World!</Response>, <type 'unicode'>)
列表
>>> amfRequest = createAMFRequest(target='echoList', body=[u'Hé', u'Ho'])
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>[u'H\xc3\xa9', u'Ho']</Response>,
<type 'list'>)
词典
>>> amfRequest = createAMFRequest(target='echoDict',
... body={'fruit': 'orange'})
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>{u'fruit': u'orange'}</Response>,
<class 'pyamf.ASObject'>)
无返回
>>> amfRequest = createAMFRequest(target='echoVoid', body='Hello World!')
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>None</Response>, <type 'NoneType'>)
元组
>>> amfRequest = createAMFRequest(target='echoTuple', body=['foo', 'bar'])
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>[u'foo', u'bar']</Response>,
<type 'list'>)
日期时间
>>> amfRequest = createAMFRequest(target='echoDate', body=None)
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>2008-11-17 11:11:00</Response>,
<type 'datetime.datetime'>)
XML
>>> amfRequest = createAMFRequest(target='echoXML', body='It works!')
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult><Element html at ...></Response>,
<type 'instance'>)
多参数
>>> amfRequest = createAMFRequest(target='echoParams', body=['foo', 'bar'],
... multiParameters=True)
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>foo-bar</Response>, <type 'unicode'>)
错误
>>> amfRequest = createAMFRequest(target='echoUnknown', body=['foo', 'bar'])
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onStatus><ErrorFault level=error code=NotFound type=Resource not found...
...
用户认证
尝试访问我们的受保护视图,而不提供flash中的登录/通行证:
>>> amfRequest = createAMFRequest(target='echoProtectedString',
... body='It works!')
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onStatus><ErrorFault level=error code=zExceptions.unauthorized.Unauthorized type=Not authorized></Response>,
<class 'pyamf.remoting.ErrorFault'>)
现在尝试使用login/pass进行访问:
>>> from Testing.ZopeTestCase import user_name, user_password
>>> amfRequest = createAMFRequest(target='echoProtectedString',
... body="Hello World!", username=user_name,
... password=user_password)
>>> response = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 200
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>Hello World!</Response>, <type 'unicode'>)
运行路径
>>> amfRequest = createAMFRequest(target='test_folder_1_.echoProtectedString',
... body='It works!', username=user_name,
... password=user_password)
>>> response = http(r"""
... POST / HTTP/1.0
... Content-Length: 200
... Content-Type: application/x-amf
...
... %s""" % amfRequest)
>>> printAMFResponse(response)
(u'/1', <Response status=/onResult>It works!</Response>, <type 'unicode'>)
简介
这个包允许您使用flex从flash中查询zope 2 动作脚本2或动作脚本3到AMF0或AMF3。
我们只是在这里提供Zope层。下层已经完成 使用pyamf包(请参见http://pyamf.org)。
让我们编写一个简单的AMF视图,它可以响应各种类型的输入:
>>> from Products.Five import BrowserView >>> from datetime import datetime >>> import elementtree.ElementTree as etree >>> class EchoView(BrowserView): ... ... def echoString(self, value): ... return "%s" % value ... ... def echoProtectedString(self, value): ... return "%s" % value ... ... def echoList(self, value): ... return list(value) ... ... def echoDict(self, value): ... return dict(value) ... ... def echoVoid(self, value): ... pass ... ... def echoTuple(self, value): ... return tuple(value) ... ... def echoParams(self, value1, value2): ... return "%s-%s" % (value1, value2) ... ... def echoDate(self): ... return datetime(2008, 11, 17, 11, 11) ... ... def echoXML(self, value): ... root = etree.Element("html") ... body = etree.SubElement(root, 'body') ... body.text = value ... return root
现在我们将其注册为flash视图。现在我们只需注册 查看文件夹对象并在用户的默认文件夹上调用它:
>>> from zope.configuration import xmlconfig >>> ignored = xmlconfig.string(""" ... <configure ... xmlns="http://namespaces.zope.org/zope" ... xmlns:browser="http://namespaces.zope.org/browser" ... xmlns:flash="http://namespaces.zope.org/flash" ... > ... ... <include package="z3c.amf" file="meta.zcml" /> ... <include package="Products.Five" file="meta.zcml" /> ... <include package="z3c.amf" /> ... ... <flash:view ... for="OFS.interfaces.IFolder" ... methods="echoString echoList echoDict echoVoid echoTuple ... echoDate echoXML echoParams" ... class="z3c.amf.README.EchoView" ... permission="zope.Public" ... /> ... ... <flash:view ... for="OFS.interfaces.IFolder" ... methods="echoProtectedString" ... class="z3c.amf.README.EchoView" ... permission="zope2.FlashAccess" ... /> ... ... </configure> ... """)
我们创建了一些助手函数。 对于请求:
>>> def createAMFRequest(target, body, username=None, password=None, multiParameters=False): ... envelope = remoting.Envelope(pyamf.AMF0, pyamf.ClientTypes.Flash9) ... if username is not None and password is not None: ... envelope.headers['Credentials'] = dict(userid=unicode(username), ... password=unicode(password)) ... if multiParameters: ... request = remoting.Request(target, body, envelope) ... else: ... request = remoting.Request(target, [body], envelope) ... envelope[u'/1'] = request ... amfRequest = remoting.encode(envelope) ... amfRequest.seek(0) ... return amfRequest.read()
回复:
>>> import pyamf >>> from pyamf import remoting >>> def printAMFResponse(response): ... context = pyamf.amf0.Context ... requests = remoting.decode(response.body, context()) ... for name, value in requests.items(): ... print (name, value, type(value.body))
基本类型
字符串
>>> amfRequest = createAMFRequest(target='echoString', body='Hello World!') >>> amfRequest '\x00\x03\x00\x00\x00\x01\x00\nechoString\x00\x02/1\x00\x00\x00\x00\n\x00\x00\x00\x01\x02\x00\x0cHello World!' >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>Hello World!</Response>, <type 'unicode'>)
列表
>>> amfRequest = createAMFRequest(target='echoList', body=[u'Hé', u'Ho']) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>[u'H\xc3\xa9', u'Ho']</Response>, <type 'list'>)
词典
>>> amfRequest = createAMFRequest(target='echoDict', ... body={'fruit': 'orange'}) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>{u'fruit': u'orange'}</Response>, <class 'pyamf.ASObject'>)
无返回
>>> amfRequest = createAMFRequest(target='echoVoid', body='Hello World!') >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>None</Response>, <type 'NoneType'>)
元组
>>> amfRequest = createAMFRequest(target='echoTuple', body=['foo', 'bar']) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>[u'foo', u'bar']</Response>, <type 'list'>)
日期时间
>>> amfRequest = createAMFRequest(target='echoDate', body=None) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>2008-11-17 11:11:00</Response>, <type 'datetime.datetime'>)
XML
>>> amfRequest = createAMFRequest(target='echoXML', body='It works!') >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult><Element html at ...></Response>, <type 'instance'>)
多参数
>>> amfRequest = createAMFRequest(target='echoParams', body=['foo', 'bar'], ... multiParameters=True) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>foo-bar</Response>, <type 'unicode'>)
错误
>>> amfRequest = createAMFRequest(target='echoUnknown', body=['foo', 'bar']) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onStatus><ErrorFault level=error code=NotFound type=Resource not found... ...
用户认证
尝试访问我们的受保护视图,而不提供flash中的登录/通行证:
>>> amfRequest = createAMFRequest(target='echoProtectedString', ... body='It works!') >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 102 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onStatus><ErrorFault level=error code=zExceptions.unauthorized.Unauthorized type=Not authorized></Response>, <class 'pyamf.remoting.ErrorFault'>)
现在尝试使用login/pass进行访问:
>>> from Testing.ZopeTestCase import user_name, user_password >>> amfRequest = createAMFRequest(target='echoProtectedString', ... body="Hello World!", username=user_name, ... password=user_password) >>> response = http(r""" ... POST /test_folder_1_ HTTP/1.0 ... Content-Length: 200 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>Hello World!</Response>, <type 'unicode'>)
运行路径
>>> amfRequest = createAMFRequest(target='test_folder_1_.echoProtectedString', ... body='It works!', username=user_name, ... password=user_password) >>> response = http(r""" ... POST / HTTP/1.0 ... Content-Length: 200 ... Content-Type: application/x-amf ... ... %s""" % amfRequest) >>> printAMFResponse(response) (u'/1', <Response status=/onResult>It works!</Response>, <type 'unicode'>)
更改日志
0.2-(2008-11-25)
- 处理服务中的路径更改
- 注册crossdomain.xml视图
0.1-(2008-11-17)
- 初始版本