Skip to main content

Zope support for Flash messages (AMF)

Project description

AMF/Flash Support in Zope 2

Introduction

This package allows you to query Zope 2 from a flash using Flex with Actionscript 2 or Actionscript 3 throught AMF0 or AMF3.

We are just providing here the Zope layer. The lower layer has been done using the PyAMF package (see http://pyamf.org).

Let’s write a simple AMF view that echoes various types of input:

>>> 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

Now we’ll register it as a Flash view. For now we’ll just register the view for folder objects and call it on the default folder of the user:

>>> 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>
... """)

We create some helper functions. For Requests:

>>> 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()

For Responses:

>>> 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))

Basic Types

String

>>> 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'>)

List

>>> 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'>)

Dictionary

>>> 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'>)

Without return

>>> 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'>)

Tuple

>>> 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'>)

Datetime

>>> 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'>)

Multi Parameters

>>> 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'>)

Errors

>>> 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...
...

User authentication

Try to access our protected view without providing login/pass in 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'>)

Now try to access with 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'>)

Path in service

>>> 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'>)

Changelog

0.2 - (2008-11-25)

  • Handle path change in service

  • register crossdomain.xml view

0.1 - (2008-11-17)

  • Initial release

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

z3c.amf-0.2.tar.gz (22.4 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page