diff -r 000000000000 -r 6d1392a3e0a6 1_0_to_1_1_diffs.diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/1_0_to_1_1_diffs.diff Tue Jun 23 13:52:28 2009 -0700
@@ -0,0 +1,425 @@
+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