[CalendarServer-changes] [8516] CalendarServer/trunk/calendarserver/push
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jan 12 15:50:36 PST 2012
Revision: 8516
http://trac.macosforge.org/projects/calendarserver/changeset/8516
Author: sagen at apple.com
Date: 2012-01-12 15:50:36 -0800 (Thu, 12 Jan 2012)
Log Message:
-----------
Adding better message handling to APNProvider.dataReceived( )
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/push/applepush.py
CalendarServer/trunk/calendarserver/push/test/test_applepush.py
Modified: CalendarServer/trunk/calendarserver/push/applepush.py
===================================================================
--- CalendarServer/trunk/calendarserver/push/applepush.py 2012-01-12 18:25:41 UTC (rev 8515)
+++ CalendarServer/trunk/calendarserver/push/applepush.py 2012-01-12 23:50:36 UTC (rev 8516)
@@ -199,6 +199,8 @@
255 : "None (unknown)",
}
+ MESSAGE_LENGTH = 6
+
def makeConnection(self, transport):
self.identifier = 0
# self.log_debug("ProviderProtocol makeConnection")
@@ -206,6 +208,7 @@
def connectionMade(self):
self.log_debug("ProviderProtocol connectionMade")
+ self.buffer = ""
# Store a reference to ourself on the factory so the service can
# later call us
self.factory.connection = self
@@ -217,11 +220,30 @@
self.factory.connection = None
def dataReceived(self, data, fn=None):
+ """
+ Buffer and divide up received data into error messages which are
+ always 6 bytes long
+ """
+
+ if fn is None:
+ fn = self.processError
+
self.log_debug("ProviderProtocol dataReceived %d bytes" % (len(data),))
- command, status, identifier = struct.unpack("!BBI", data)
- if command == self.COMMAND_ERROR:
- self.processError(status, identifier)
+ self.buffer += data
+ while len(self.buffer) >= self.MESSAGE_LENGTH:
+ message = self.buffer[:self.MESSAGE_LENGTH]
+ self.buffer = self.buffer[self.MESSAGE_LENGTH:]
+
+ try:
+ command, status, identifier = struct.unpack("!BBI", message)
+ if command == self.COMMAND_ERROR:
+ fn(status, identifier)
+ except Exception, e:
+ self.log_warn("ProviderProtocol could not process error: %s (%s)" %
+ (message.encode("hex"), e))
+
+
def processError(self, status, identifier):
"""
Handles an error message we've received from on feedback channel.
Modified: CalendarServer/trunk/calendarserver/push/test/test_applepush.py
===================================================================
--- CalendarServer/trunk/calendarserver/push/test/test_applepush.py 2012-01-12 18:25:41 UTC (rev 8515)
+++ CalendarServer/trunk/calendarserver/push/test/test_applepush.py 2012-01-12 23:50:36 UTC (rev 8516)
@@ -108,11 +108,37 @@
rawData[45:])
self.assertEquals(payload[0], '{"key" : "%s"}' % (key1,))
+ def errorTestFunction(status, identifier):
+ history.append((status, identifier))
+ return succeed(None)
+
# Simulate an error
- errorData = struct.pack("!BBI", APNProviderProtocol.COMMAND_ERROR, 1, 1)
- yield connector.receiveData(errorData)
+ history = []
+ errorData = struct.pack("!BBI", APNProviderProtocol.COMMAND_ERROR, 1, 2)
+ yield connector.receiveData(errorData, fn=errorTestFunction)
clock.advance(301)
+ # Simulate multiple errors and dataReceived called
+ # with amounts of data not fitting message boundaries
+ # Send 1st 4 bytes
+ history = []
+ errorData = struct.pack("!BBIBBI",
+ APNProviderProtocol.COMMAND_ERROR, 3, 4,
+ APNProviderProtocol.COMMAND_ERROR, 5, 6,
+ )
+ yield connector.receiveData(errorData[:4], fn=errorTestFunction)
+ # Send remaining bytes
+ yield connector.receiveData(errorData[4:], fn=errorTestFunction)
+ self.assertEquals(history, [(3, 4), (5, 6)])
+ # Buffer is empty
+ self.assertEquals(len(connector.service.protocol.buffer), 0)
+
+ # Sending 7 bytes
+ yield connector.receiveData("!" * 7, fn=errorTestFunction)
+ # Buffer has 1 byte remaining
+ self.assertEquals(len(connector.service.protocol.buffer), 1)
+
+
# Prior to feedback, there are 2 subscriptions
txn = self.store.newTransaction()
subscriptions = (yield txn.apnSubscriptionsByToken(token))
@@ -131,7 +157,7 @@
# Simulate feedback with multiple tokens, and dataReceived called
# with amounts of data not fitting message boundaries
history = []
- def testFunction(timestamp, token):
+ def feedbackTestFunction(timestamp, token):
history.append((timestamp, token))
return succeed(None)
timestamp = 2000
@@ -141,15 +167,15 @@
timestamp, len(binaryToken), binaryToken,
)
# Send 1st 10 bytes
- yield connector.receiveData(feedbackData[:10], fn=testFunction)
+ yield connector.receiveData(feedbackData[:10], fn=feedbackTestFunction)
# Send remaining bytes
- yield connector.receiveData(feedbackData[10:], fn=testFunction)
+ yield connector.receiveData(feedbackData[10:], fn=feedbackTestFunction)
self.assertEquals(history, [(timestamp, token), (timestamp, token)])
# Buffer is empty
self.assertEquals(len(connector.service.protocol.buffer), 0)
# Sending 39 bytes
- yield connector.receiveData("!" * 39, fn=testFunction)
+ yield connector.receiveData("!" * 39, fn=feedbackTestFunction)
# Buffer has 1 byte remaining
self.assertEquals(len(connector.service.protocol.buffer), 1)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120112/40601e42/attachment-0001.html>
More information about the calendarserver-changes
mailing list