# HG changeset patch # User morrowa # Date 1246589891 25200 # Node ID 6c3b5372a307f86ee0bd389a4b8191ad0e7ad2ac # Parent f240f9023393fa4ca8cac2f96b4fddbd11b3d97d Removed unnecessary files. Toned down logging. Added null logging handler to BLIP so client code doesn't have to use logging. Modified test drivers to work against Cocoa versions. diff -r f240f9023393 -r 6c3b5372a307 1_0_to_1_1_diffs.diff --- a/1_0_to_1_1_diffs.diff Thu Jul 02 17:51:35 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,425 +0,0 @@ -diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPConnection.h ---- a/BLIP/BLIPConnection.h Thu Jun 19 10:22:19 2008 -0700 -+++ b/BLIP/BLIPConnection.h Mon Jun 23 14:02:31 2008 -0700 -@@ -20,6 +20,7 @@ - @interface BLIPConnection : TCPConnection - { - BLIPDispatcher *_dispatcher; -+ BOOL _blipClosing; - } - - /** The delegate object that will be called when the connection opens, closes or receives messages. */ -@@ -73,6 +74,13 @@ - /** Called when a BLIPResponse (to one of your requests) is received from the peer. - This is called after the response object's onComplete target, if any, is invoked.*/ - - (void) connection: (BLIPConnection*)connection receivedResponse: (BLIPResponse*)response; -+ -+/** Called when the peer wants to close the connection. Return YES to allow, NO to prevent. */ -+- (BOOL) connectionReceivedCloseRequest: (BLIPConnection*)connection; -+ -+/** Called if the peer refuses a close request. -+ The typical error is kBLIPError_Forbidden. */ -+- (void) connection: (BLIPConnection*)connection closeRequestFailedWithError: (NSError*)error; - @end - - -diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPConnection.m ---- a/BLIP/BLIPConnection.m Thu Jun 19 10:22:19 2008 -0700 -+++ b/BLIP/BLIPConnection.m Mon Jun 23 14:02:31 2008 -0700 -@@ -8,6 +8,7 @@ - - #import "BLIPConnection.h" - #import "BLIP_Internal.h" -+#import "TCP_Internal.h" - #import "BLIPReader.h" - #import "BLIPWriter.h" - #import "BLIPDispatcher.h" -@@ -15,6 +16,7 @@ - #import "Logging.h" - #import "Test.h" - #import "ExceptionUtils.h" -+#import "Target.h" - - - NSString* const BLIPErrorDomain = @"BLIP"; -@@ -33,10 +35,14 @@ - } - - -+@interface BLIPConnection () -+- (void) _handleCloseRequest: (BLIPRequest*)request; -+@end - - - @implementation BLIPConnection - -+ - - (void) dealloc - { - [_dispatcher release]; -@@ -48,6 +54,11 @@ - - (id) delegate {return (id)_delegate;} - - (void) setDelegate: (id)delegate {_delegate = delegate;} - -+ -+#pragma mark - -+#pragma mark RECEIVING: -+ -+ - - (BLIPDispatcher*) dispatcher - { - if( ! _dispatcher ) { -@@ -58,11 +69,23 @@ - } - - -+- (void) _dispatchMetaRequest: (BLIPRequest*)request -+{ -+ NSString* profile = request.profile; -+ if( [profile isEqualToString: kBLIPProfile_Bye] ) -+ [self _handleCloseRequest: request]; -+ else -+ [request respondWithErrorCode: kBLIPError_NotFound message: @"Unknown meta profile"]; -+} -+ -+ - - (void) _dispatchRequest: (BLIPRequest*)request - { - LogTo(BLIP,@"Received all of %@",request.descriptionWithProperties); - @try{ -- if( ! [self.dispatcher dispatchMessage: request] ) -+ if( request._flags & kBLIP_Meta ) -+ [self _dispatchMetaRequest: request]; -+ else if( ! [self.dispatcher dispatchMessage: request] ) - [self tellDelegate: @selector(connection:receivedRequest:) withObject: request]; - if( ! request.noReply && ! request.repliedTo ) { - LogTo(BLIP,@"Returning default empty response to %@",request); -@@ -81,6 +104,10 @@ - } - - -+#pragma mark - -+#pragma mark SENDING: -+ -+ - - (BLIPRequest*) request - { - return [[[BLIPRequest alloc] _initWithConnection: self body: nil properties: nil] autorelease]; -@@ -103,11 +130,61 @@ - } - - -+#pragma mark - -+#pragma mark CLOSING: -+ -+ -+- (void) _beginClose -+{ -+ // Override of TCPConnection method. Instead of closing the socket, send a 'bye' request: -+ if( ! _blipClosing ) { -+ LogTo(BLIPVerbose,@"Sending close request..."); -+ BLIPRequest *r = [self request]; -+ [r _setFlag: kBLIP_Meta value: YES]; -+ r.profile = kBLIPProfile_Bye; -+ BLIPResponse *response = [r send]; -+ response.onComplete = $target(self,_receivedCloseResponse:); -+ } -+ // Put the writer in close mode, to prevent client from sending any more requests: -+ [self.writer close]; -+} -+ -+- (void) _receivedCloseResponse: (BLIPResponse*)response -+{ -+ NSError *error = response.error; -+ LogTo(BLIPVerbose,@"Received close response: error=%@",error); -+ if( error ) { -+ [self _unclose]; -+ [self tellDelegate: @selector(connection:closeRequestFailedWithError:) withObject: error]; -+ } else { -+ // Now finally close the socket: -+ [super _beginClose]; -+ } -+} -+ -+ -+- (void) _handleCloseRequest: (BLIPRequest*)request -+{ -+ LogTo(BLIPVerbose,@"Received a close request"); -+ if( [_delegate respondsToSelector: @selector(connectionReceivedCloseRequest:)] ) -+ if( ! [_delegate connectionReceivedCloseRequest: self] ) { -+ LogTo(BLIPVerbose,@"Responding with denial of close request"); -+ [request respondWithErrorCode: kBLIPError_Forbidden message: @"Close request denied"]; -+ return; -+ } -+ -+ LogTo(BLIPVerbose,@"Close request accepted"); -+ _blipClosing = YES; // this prevents _beginClose from sending a close request back -+ [self close]; -+} -+ -+ - @end - - - - -+#pragma mark - - @implementation BLIPListener - - - (id) initWithPort: (UInt16)port -diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPMessage.m ---- a/BLIP/BLIPMessage.m Thu Jun 19 10:22:19 2008 -0700 -+++ b/BLIP/BLIPMessage.m Mon Jun 23 14:02:31 2008 -0700 -@@ -74,6 +74,8 @@ - [desc appendString: @", urgent"]; - if( _flags & kBLIP_NoReply ) - [desc appendString: @", noreply"]; -+ if( _flags & kBLIP_Meta ) -+ [desc appendString: @", META"]; - [desc appendString: @"]"]; - return desc; - } -@@ -103,6 +105,8 @@ - _flags &= ~flag; - } - -+- (BLIPMessageFlags) _flags {return _flags;} -+ - - (BOOL) compressed {return (_flags & kBLIP_Compressed) != 0;} - - (BOOL) urgent {return (_flags & kBLIP_Urgent) != 0;} - - (void) setCompressed: (BOOL)compressed {[self _setFlag: kBLIP_Compressed value: compressed];} -diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPReader.m ---- a/BLIP/BLIPReader.m Thu Jun 19 10:22:19 2008 -0700 -+++ b/BLIP/BLIPReader.m Mon Jun 23 14:02:31 2008 -0700 -@@ -93,7 +93,7 @@ - - - (BOOL) isBusy - { -- return _curBytesRead > 0; -+ return _curBytesRead > 0 || _pendingRequests.count > 0 || _pendingResponses.count > 0; - } - - -diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPRequest.m ---- a/BLIP/BLIPRequest.m Thu Jun 19 10:22:19 2008 -0700 -+++ b/BLIP/BLIPRequest.m Mon Jun 23 14:02:31 2008 -0700 -@@ -199,6 +199,8 @@ - setObj(&_mutableBody,nil); - - BLIPMutableProperties *errorProps = [self.properties mutableCopy]; -+ if( ! errorProps ) -+ errorProps = [[BLIPMutableProperties alloc] init]; - NSDictionary *userInfo = error.userInfo; - for( NSString *key in userInfo ) { - id value = $castIf(NSString,[userInfo objectForKey: key]); -@@ -227,8 +229,12 @@ - { - Assert(_connection,@"%@ has no connection to send over",self); - Assert(!_sent,@"%@ was already sent",self); -+ BLIPWriter *writer = (BLIPWriter*)_connection.writer; -+ Assert(writer,@"%@'s connection has no writer (already closed?)",self); - [self _encode]; -- return (self.sent = [(BLIPWriter*)_connection.writer sendMessage: self]); -+ BOOL sent = self.sent = [writer sendMessage: self]; -+ Assert(sent); -+ return sent; - } - - -diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPTest.m ---- a/BLIP/BLIPTest.m Thu Jun 19 10:22:19 2008 -0700 -+++ b/BLIP/BLIPTest.m Mon Jun 23 14:02:31 2008 -0700 -@@ -35,6 +35,7 @@ - #define kClientUsesSSLCert NO - #define kListenerRequiresSSL NO - #define kListenerRequiresClientCert NO -+#define kListenerCloseAfter 50 - - - static SecIdentityRef GetClientIdentity(void) { -@@ -100,36 +101,38 @@ - - - (void) sendAMessage - { -- if(_pending.count<100) { -- Log(@"** Sending another %i messages...", kNBatchedMessages); -- for( int i=0; i 12 ) -- q.urgent = YES; -- BLIPResponse *response = [q send]; -- Assert(response); -- Assert(q.number>0); -- Assert(response.number==q.number); -- [_pending setObject: $object(size) forKey: $object(q.number)]; -- response.onComplete = $target(self,responseArrived:); -+ if( _conn.status==kTCP_Open || _conn.status==kTCP_Opening ) { -+ if(_pending.count<100) { -+ Log(@"** Sending another %i messages...", kNBatchedMessages); -+ for( int i=0; i 12 ) -+ q.urgent = YES; -+ BLIPResponse *response = [q send]; -+ Assert(response); -+ Assert(q.number>0); -+ Assert(response.number==q.number); -+ [_pending setObject: $object(size) forKey: $object(q.number)]; -+ response.onComplete = $target(self,responseArrived:); -+ } -+ } else { -+ Warn(@"There are %u pending messages; waiting for the listener to catch up...",_pending.count); - } -- } else { -- Warn(@"There are %u pending messages; waiting for the listener to catch up...",_pending.count); -+ [self performSelector: @selector(sendAMessage) withObject: nil afterDelay: kSendInterval]; - } -- [self performSelector: @selector(sendAMessage) withObject: nil afterDelay: kSendInterval]; - } - - - (void) responseArrived: (BLIPResponse*)response -@@ -191,6 +194,13 @@ - Log(@"Now %u replies pending", _pending.count); - } - -+- (BOOL) connectionReceivedCloseRequest: (BLIPConnection*)connection -+{ -+ BOOL response = NO; -+ Log(@"***** %@ received a close request; returning %i",connection,response); -+ return response; -+} -+ - - @end - -@@ -217,6 +227,7 @@ - @interface BLIPTestListener : NSObject - { - BLIPListener *_listener; -+ int _nReceived; - } - - @end -@@ -277,6 +288,7 @@ - - (void) connectionDidOpen: (TCPConnection*)connection - { - Log(@"** %@ didOpen [SSL=%@]",connection,connection.actualSecurityLevel); -+ _nReceived = 0; - } - - (BOOL) connection: (TCPConnection*)connection authorizeSSLPeer: (SecCertificateRef)peerCert - { -@@ -312,6 +324,22 @@ - AssertEq([[request valueOfProperty: @"Size"] intValue], size); - - [request respondWithData: body contentType: request.contentType]; -+ -+ if( ++ _nReceived == kListenerCloseAfter ) { -+ Log(@"********** Closing BLIPTestListener after %i requests",_nReceived); -+ [connection close]; -+ } -+} -+ -+- (BOOL) connectionReceivedCloseRequest: (BLIPConnection*)connection; -+{ -+ Log(@"***** %@ received a close request",connection); -+ return YES; -+} -+ -+- (void) connection: (BLIPConnection*)connection closeRequestFailedWithError: (NSError*)error -+{ -+ Log(@"***** %@'s close request failed: %@",connection,error); - } - - -diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPWriter.m ---- a/BLIP/BLIPWriter.m Thu Jun 19 10:22:19 2008 -0700 -+++ b/BLIP/BLIPWriter.m Mon Jun 23 14:02:31 2008 -0700 -@@ -79,10 +79,6 @@ - - - (BOOL) sendMessage: (BLIPMessage*)message - { -- if( _shouldClose ) { -- Warn(@"%@: Attempt to send a message after the connection has started closing",self); -- return NO; -- } - Assert(!message.sent,@"message has already been sent"); - [self _queueMessage: message isNew: YES]; - return YES; -@@ -91,12 +87,14 @@ - - - (BOOL) sendRequest: (BLIPRequest*)q response: (BLIPResponse*)response - { -- if( !_shouldClose ) { -- [q _assignedNumber: ++_numRequestsSent]; -- if( response ) { -- [response _assignedNumber: _numRequestsSent]; -- [(BLIPReader*)self.reader _addPendingResponse: response]; -- } -+ if( _shouldClose ) { -+ Warn(@"%@: Attempt to send a request after the connection has started closing: %@",self,q); -+ return NO; -+ } -+ [q _assignedNumber: ++_numRequestsSent]; -+ if( response ) { -+ [response _assignedNumber: _numRequestsSent]; -+ [(BLIPReader*)self.reader _addPendingResponse: response]; - } - return [self sendMessage: q]; - } -diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIP_Internal.h ---- a/BLIP/BLIP_Internal.h Thu Jun 19 10:22:19 2008 -0700 -+++ b/BLIP/BLIP_Internal.h Mon Jun 23 14:02:31 2008 -0700 -@@ -29,6 +29,7 @@ - kBLIP_Urgent = 0x0020, // please send sooner/faster - kBLIP_NoReply = 0x0040, // no RPY needed - kBLIP_MoreComing= 0x0080, // More frames coming (Applies only to individual frame) -+ kBLIP_Meta = 0x0100, // Special message type, handled internally (hello, bye, ...) - }; - typedef UInt16 BLIPMessageFlags; - -@@ -41,7 +42,10 @@ - UInt16 size; // total size of frame, _including_ this header - } BLIPFrameHeader; - --#define kBLIPFrameHeaderMagicNumber 0x9B34F205 -+#define kBLIPFrameHeaderMagicNumber 0x9B34F206 -+ -+#define kBLIPProfile_Hi @"Hi" // Used for Profile header in meta greeting message -+#define kBLIPProfile_Bye @"Bye" // Used for Profile header in meta close-request message - - - @interface BLIPConnection () -@@ -52,6 +56,7 @@ - - @interface BLIPMessage () - @property BOOL sent, propertiesAvailable, complete; -+- (BLIPMessageFlags) _flags; - - (void) _setFlag: (BLIPMessageFlags)flag value: (BOOL)value; - - (void) _encode; - @end diff -r f240f9023393 -r 6c3b5372a307 Python/BLIP.py --- a/Python/BLIP.py Thu Jul 02 17:51:35 2009 -0700 +++ b/Python/BLIP.py Thu Jul 02 19:58:11 2009 -0700 @@ -45,8 +45,14 @@ kMsgProfile_Hi = "Hi" kMsgProfile_Bye = "Bye" +# Logging Setup +class NullLoggingHandler(logging.Handler): + def emit(self, record): + pass log = logging.getLogger('BLIP') +# This line prevents the "No handlers found" warning if the calling code does not use logging. +log.addHandler(NullLoggingHandler()) log.propagate = True diff -r f240f9023393 -r 6c3b5372a307 Python/BLIPConnectionTest.py --- a/Python/BLIPConnectionTest.py Thu Jul 02 17:51:35 2009 -0700 +++ b/Python/BLIPConnectionTest.py Thu Jul 02 19:58:11 2009 -0700 @@ -18,7 +18,7 @@ kSendInterval = 0.2 -kNBatchedMessages = 10 +kNBatchedMessages = 4 # send only 40 requests total kUrgentEvery = 4 def randbool(): @@ -75,5 +75,5 @@ asyncore.loop() # got to give it time to negotiate close; this call should exit eventually if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.INFO) unittest.main() diff -r f240f9023393 -r 6c3b5372a307 Python/BLIPListenerTest.py --- a/Python/BLIPListenerTest.py Thu Jul 02 17:51:35 2009 -0700 +++ b/Python/BLIPListenerTest.py Thu Jul 02 19:58:11 2009 -0700 @@ -17,8 +17,13 @@ class BLIPListenerTest(unittest.TestCase): def testListener(self): + def handleConnection(conn): + logging.info("Got new connection: %r", conn) + conn.ListenerTestNumRequests = 0 + def handleRequest(request): logging.info("Got request!: %r",request) + request.connection.ListenerTestNumRequests += 1 body = request.body assert len(body)<32768 assert request.contentType == 'application/octet-stream' @@ -31,8 +36,11 @@ response.body = request.body response['Content-Type'] = request.contentType response.send() + if request.connection.ListenerTestNumRequests >= 50: + request.connection.close() listener = Listener(46353) + listener.onConnected = handleConnection listener.onRequest = handleRequest logging.info("Listener is waiting...") @@ -42,5 +50,5 @@ logging.info("KeyboardInterrupt") if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.INFO) unittest.main() diff -r f240f9023393 -r 6c3b5372a307 Python/CloseTestPing.py --- a/Python/CloseTestPing.py Thu Jul 02 17:51:35 2009 -0700 +++ b/Python/CloseTestPing.py Thu Jul 02 19:58:11 2009 -0700 @@ -24,7 +24,7 @@ req.response.onComplete = self.handleResponse req.send() - asyncore.loop(timeout=0, count=5) + asyncore.loop(timeout=0, count=5) # give things time to send self.connection.close() @@ -32,5 +32,5 @@ if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.INFO) unittest.main() diff -r f240f9023393 -r 6c3b5372a307 Python/CloseTestPong.py --- a/Python/CloseTestPong.py Thu Jul 02 17:51:35 2009 -0700 +++ b/Python/CloseTestPong.py Thu Jul 02 19:58:11 2009 -0700 @@ -34,5 +34,5 @@ if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(level=logging.INFO) unittest.main() diff -r f240f9023393 -r 6c3b5372a307 Python/asynchatPing.py --- a/Python/asynchatPing.py Thu Jul 02 17:51:35 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -# asynchatPing -# Uses asynchat -# Not related to BLIP - just to aid in my understanding of what's going on -# Sends "Ping", waits for "Pong" - -import socket -import asyncore -import asynchat - -kNumPings = 10 - -class asynchatPing(asynchat.async_chat): - def __init__(self, address): - asynchat.async_chat.__init__(self) - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.connect(address) - self.set_terminator("Pong") - self.pingsSent = self.pongsGot = 0 - self.donePing = self.donePong = False - - def handle_connect(self): - print "Connected" - - def handle_close(self): - print "Closed" - asynchat.async_chat.handle_close(self) - - def collect_incoming_data(self, data): - """discard data""" - pass - - def found_terminator(self): - """when we get a Pong""" - print "Received 'Pong'" - self.pongsGot += 1 - if self.pongsGot == kNumPings: - print "Done ponging" - self.donePong = True - self.close_when_done() - - def ping(self): - if not self.donePing: - self.push("Ping") - print "Sent 'Ping'" - self.pingsSent += 1 - if self.pingsSent == kNumPings: - print "Done pinging" - self.donePing = True - - def run(self): - timeout = 0 - while not self.donePing: - self.ping() - asyncore.loop(timeout=timeout, count=1) - asyncore.loop() - print "Done!" - -if __name__ == '__main__': - ping = asynchatPing( ('localhost', 1337) ) - ping.run() diff -r f240f9023393 -r 6c3b5372a307 Python/asynchatPong.py --- a/Python/asynchatPong.py Thu Jul 02 17:51:35 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -# asynchatPong -# Listener using asynchat -# Not related to BLIP - just to aid in my understanding of what's going on -# Sends "Pong" when it gets "Ping" - -import sys -import traceback -import socket -import asyncore -import asynchat - -class asynchatPongListener(asyncore.dispatcher): - def __init__(self, port): - asyncore.dispatcher.__init__(self) - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.bind( ('', port) ) - self.listen(2) - self.shouldAccept = True - - def handle_accept(self): - if self.shouldAccept: - sock, addr = self.accept() - self.conn = asynchatPong(sock, self) - self.shouldAccept = False - - def handle_error(self): - (typ,val,trace) = sys.exc_info() - print "Listener caught: %s %s\n%s" % (typ,val,traceback.format_exc()) - self.close() - - def handle_close(self): - print "Listener got close" - asyncore.dispatcher.handle_close(self) - -class asynchatPong(asynchat.async_chat): - def __init__(self, socket, listener): - asynchat.async_chat.__init__(self, socket) - self._listener = listener - self.set_terminator("Ping") - - def collect_incoming_data(self, data): - """called when arbitrary amount of data arrives. we just eat it""" - pass - - def found_terminator(self): - """called when the terminator we set is found""" - print "Found 'Ping'" - self.push("Pong") - print "Sent 'Pong'" - - def handle_close(self): - print "Closed; closing listener" - self._listener.close() - asynchat.async_chat.handle_close(self) - - -if __name__ == '__main__': - pong = asynchatPongListener(1337) - asyncore.loop()