diff idavoll/gateway.py @ 209:7f3ffb7a1a9e

Add support for node deletion with redirect.
author Ralph Meijer <ralphm@ik.nu>
date Fri, 30 Jan 2009 14:35:05 +0000
parents 274a45d2a5ab
children 2a0a6a671776
line wrap: on
line diff
--- a/idavoll/gateway.py	Tue Sep 09 14:54:33 2008 +0000
+++ b/idavoll/gateway.py	Fri Jan 30 14:35:05 2009 +0000
@@ -171,10 +171,7 @@
         Respond to a POST request to create a new node.
         """
 
-        def respond(result):
-            return http.Response(responsecode.NO_CONTENT)
-
-        def getNode():
+        def gotStream(_):
             if request.args.get('uri'):
                 jid, nodeIdentifier = getServiceAndNode(request.args['uri'][0])
                 return defer.succeed(nodeIdentifier)
@@ -182,6 +179,20 @@
                 raise http.HTTPError(http.Response(responsecode.BAD_REQUEST,
                                                    "No URI given"))
 
+        def doDelete(nodeIdentifier, data):
+            if data:
+                params = simplejson.loads(''.join(data))
+                redirectURI = params.get('redirect_uri')
+            else:
+                redirectURI = None
+
+            return self.backend.deleteNode(nodeIdentifier, self.owner,
+                                           redirectURI)
+
+        def respond(result):
+            return http.Response(responsecode.NO_CONTENT)
+
+
         def trapNotFound(failure):
             failure.trap(error.NodeNotFound)
             return http.StatusResponse(responsecode.NOT_FOUND,
@@ -192,8 +203,10 @@
             return http.StatusResponse(responsecode.BAD_REQUEST,
                     "Malformed XMPP URI: %s" % failure.value.message)
 
-        d = getNode()
-        d.addCallback(self.backend.deleteNode, self.owner)
+        data = []
+        d = readStream(request.stream, data.append)
+        d.addCallback(gotStream)
+        d.addCallback(doDelete, data)
         d.addCallback(respond)
         d.addErrback(trapNotFound)
         d.addErrback(trapXMPPURIParseError)
@@ -473,11 +486,14 @@
 
         service = event.sender
         nodeIdentifier = event.nodeIdentifier
-        self.callCallbacks(service, nodeIdentifier, eventType='DELETED')
+        redirectURI = event.redirectURI
+        self.callCallbacks(service, nodeIdentifier, eventType='DELETED',
+                           redirectURI=redirectURI)
 
 
     def _postTo(self, callbacks, service, nodeIdentifier,
-                      payload=None, contentType=None, eventType=None):
+                      payload=None, contentType=None, eventType=None,
+                      redirectURI=None):
 
         if not callbacks:
             return
@@ -495,6 +511,11 @@
         if eventType:
             headers['Event'] = eventType
 
+        if redirectURI:
+            headers['Link'] = '<%s>; rel=alternate' % (
+                              redirectURI.encode('utf-8'),
+                              )
+
         def postNotification(callbackURI):
             d = client.getPage(str(callbackURI),
                                    method='POST',
@@ -507,7 +528,8 @@
 
 
     def callCallbacks(self, service, nodeIdentifier,
-                            payload=None, contentType=None, eventType=None):
+                            payload=None, contentType=None, eventType=None,
+                            redirectURI=None):
 
         def eb(failure):
             failure.trap(error.NoCallbacks)
@@ -516,7 +538,7 @@
 
         d = self.storage.getCallbacks(service, nodeIdentifier)
         d.addCallback(self._postTo, service, nodeIdentifier, payload,
-                                    contentType, eventType)
+                                    contentType, eventType, redirectURI)
         d.addErrback(eb)
         d.addErrback(log.err)
 
@@ -708,7 +730,10 @@
 
     def http_POST(self, request):
         p = WebStreamParser()
-        d = p.parse(request.stream)
+        if not request.headers.hasHeader('Event'):
+            d = p.parse(request.stream)
+        else:
+            d = defer.succeed(None)
         d.addCallback(self.callback, request.headers)
         d.addCallback(lambda _: http.Response(responsecode.NO_CONTENT))
         return d
@@ -769,6 +794,25 @@
         return f.deferred.addCallback(simplejson.loads)
 
 
+    def delete(self, xmppURI, redirectURI=None):
+        query = {'uri': xmppURI}
+
+        if redirectURI:
+            params = {'redirect_uri': redirectURI}
+            postdata = simplejson.dumps(params)
+            headers = {'Content-Type': MIME_JSON}
+        else:
+            postdata = None
+            headers = None
+
+        f = getPageWithFactory(self._makeURI('delete', query),
+                    method='POST',
+                    postdata=postdata,
+                    headers=headers,
+                    agent=self.agent)
+        return f.deferred
+
+
     def publish(self, entry, xmppURI=None):
         query = xmppURI and {'uri': xmppURI}