1_0_to_1_1_diffs.diff
changeset 51 de59ce19f42e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/1_0_to_1_1_diffs.diff	Tue Jun 23 11:44:30 2009 -0700
     1.3 @@ -0,0 +1,425 @@
     1.4 +diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPConnection.h
     1.5 +--- a/BLIP/BLIPConnection.h	Thu Jun 19 10:22:19 2008 -0700
     1.6 ++++ b/BLIP/BLIPConnection.h	Mon Jun 23 14:02:31 2008 -0700
     1.7 +@@ -20,6 +20,7 @@
     1.8 + @interface BLIPConnection : TCPConnection
     1.9 + {
    1.10 +     BLIPDispatcher *_dispatcher;
    1.11 ++    BOOL _blipClosing;
    1.12 + }
    1.13 + 
    1.14 + /** The delegate object that will be called when the connection opens, closes or receives messages. */
    1.15 +@@ -73,6 +74,13 @@
    1.16 + /** Called when a BLIPResponse (to one of your requests) is received from the peer.
    1.17 +     This is called <i>after</i> the response object's onComplete target, if any, is invoked.*/
    1.18 + - (void) connection: (BLIPConnection*)connection receivedResponse: (BLIPResponse*)response;
    1.19 ++
    1.20 ++/** Called when the peer wants to close the connection. Return YES to allow, NO to prevent. */
    1.21 ++- (BOOL) connectionReceivedCloseRequest: (BLIPConnection*)connection;
    1.22 ++
    1.23 ++/** Called if the peer refuses a close request. 
    1.24 ++    The typical error is kBLIPError_Forbidden. */
    1.25 ++- (void) connection: (BLIPConnection*)connection closeRequestFailedWithError: (NSError*)error;
    1.26 + @end
    1.27 + 
    1.28 + 
    1.29 +diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPConnection.m
    1.30 +--- a/BLIP/BLIPConnection.m	Thu Jun 19 10:22:19 2008 -0700
    1.31 ++++ b/BLIP/BLIPConnection.m	Mon Jun 23 14:02:31 2008 -0700
    1.32 +@@ -8,6 +8,7 @@
    1.33 + 
    1.34 + #import "BLIPConnection.h"
    1.35 + #import "BLIP_Internal.h"
    1.36 ++#import "TCP_Internal.h"
    1.37 + #import "BLIPReader.h"
    1.38 + #import "BLIPWriter.h"
    1.39 + #import "BLIPDispatcher.h"
    1.40 +@@ -15,6 +16,7 @@
    1.41 + #import "Logging.h"
    1.42 + #import "Test.h"
    1.43 + #import "ExceptionUtils.h"
    1.44 ++#import "Target.h"
    1.45 + 
    1.46 + 
    1.47 + NSString* const BLIPErrorDomain = @"BLIP";
    1.48 +@@ -33,10 +35,14 @@
    1.49 + }
    1.50 + 
    1.51 + 
    1.52 ++@interface BLIPConnection ()
    1.53 ++- (void) _handleCloseRequest: (BLIPRequest*)request;
    1.54 ++@end
    1.55 + 
    1.56 + 
    1.57 + @implementation BLIPConnection
    1.58 + 
    1.59 ++
    1.60 + - (void) dealloc
    1.61 + {
    1.62 +     [_dispatcher release];
    1.63 +@@ -48,6 +54,11 @@
    1.64 + - (id<BLIPConnectionDelegate>) delegate                     {return (id)_delegate;}
    1.65 + - (void) setDelegate: (id<BLIPConnectionDelegate>)delegate  {_delegate = delegate;}
    1.66 + 
    1.67 ++
    1.68 ++#pragma mark -
    1.69 ++#pragma mark RECEIVING:
    1.70 ++
    1.71 ++
    1.72 + - (BLIPDispatcher*) dispatcher
    1.73 + {
    1.74 +     if( ! _dispatcher ) {
    1.75 +@@ -58,11 +69,23 @@
    1.76 + }
    1.77 + 
    1.78 + 
    1.79 ++- (void) _dispatchMetaRequest: (BLIPRequest*)request
    1.80 ++{
    1.81 ++    NSString* profile = request.profile;
    1.82 ++    if( [profile isEqualToString: kBLIPProfile_Bye] )
    1.83 ++        [self _handleCloseRequest: request];
    1.84 ++    else
    1.85 ++        [request respondWithErrorCode: kBLIPError_NotFound message: @"Unknown meta profile"];
    1.86 ++}
    1.87 ++
    1.88 ++
    1.89 + - (void) _dispatchRequest: (BLIPRequest*)request
    1.90 + {
    1.91 +     LogTo(BLIP,@"Received all of %@",request.descriptionWithProperties);
    1.92 +     @try{
    1.93 +-        if( ! [self.dispatcher dispatchMessage: request] )
    1.94 ++        if( request._flags & kBLIP_Meta )
    1.95 ++            [self _dispatchMetaRequest: request];
    1.96 ++        else if( ! [self.dispatcher dispatchMessage: request] )
    1.97 +             [self tellDelegate: @selector(connection:receivedRequest:) withObject: request];
    1.98 +         if( ! request.noReply && ! request.repliedTo ) {
    1.99 +             LogTo(BLIP,@"Returning default empty response to %@",request);
   1.100 +@@ -81,6 +104,10 @@
   1.101 + }
   1.102 + 
   1.103 + 
   1.104 ++#pragma mark -
   1.105 ++#pragma mark SENDING:
   1.106 ++
   1.107 ++
   1.108 + - (BLIPRequest*) request
   1.109 + {
   1.110 +     return [[[BLIPRequest alloc] _initWithConnection: self body: nil properties: nil] autorelease];
   1.111 +@@ -103,11 +130,61 @@
   1.112 + }
   1.113 + 
   1.114 + 
   1.115 ++#pragma mark -
   1.116 ++#pragma mark CLOSING:
   1.117 ++
   1.118 ++
   1.119 ++- (void) _beginClose
   1.120 ++{
   1.121 ++    // Override of TCPConnection method. Instead of closing the socket, send a 'bye' request:
   1.122 ++    if( ! _blipClosing ) {
   1.123 ++        LogTo(BLIPVerbose,@"Sending close request...");
   1.124 ++        BLIPRequest *r = [self request];
   1.125 ++        [r _setFlag: kBLIP_Meta value: YES];
   1.126 ++        r.profile = kBLIPProfile_Bye;
   1.127 ++        BLIPResponse *response = [r send];
   1.128 ++        response.onComplete = $target(self,_receivedCloseResponse:);
   1.129 ++    }
   1.130 ++    // Put the writer in close mode, to prevent client from sending any more requests:
   1.131 ++    [self.writer close];
   1.132 ++}
   1.133 ++
   1.134 ++- (void) _receivedCloseResponse: (BLIPResponse*)response
   1.135 ++{
   1.136 ++    NSError *error = response.error;
   1.137 ++    LogTo(BLIPVerbose,@"Received close response: error=%@",error);
   1.138 ++    if( error ) {
   1.139 ++        [self _unclose];
   1.140 ++        [self tellDelegate: @selector(connection:closeRequestFailedWithError:) withObject: error];
   1.141 ++    } else {
   1.142 ++        // Now finally close the socket:
   1.143 ++        [super _beginClose];
   1.144 ++    }
   1.145 ++}
   1.146 ++
   1.147 ++
   1.148 ++- (void) _handleCloseRequest: (BLIPRequest*)request
   1.149 ++{
   1.150 ++    LogTo(BLIPVerbose,@"Received a close request");
   1.151 ++    if( [_delegate respondsToSelector: @selector(connectionReceivedCloseRequest:)] )
   1.152 ++        if( ! [_delegate connectionReceivedCloseRequest: self] ) {
   1.153 ++            LogTo(BLIPVerbose,@"Responding with denial of close request");
   1.154 ++            [request respondWithErrorCode: kBLIPError_Forbidden message: @"Close request denied"];
   1.155 ++            return;
   1.156 ++        }
   1.157 ++    
   1.158 ++    LogTo(BLIPVerbose,@"Close request accepted");
   1.159 ++    _blipClosing = YES; // this prevents _beginClose from sending a close request back
   1.160 ++    [self close];
   1.161 ++}
   1.162 ++
   1.163 ++
   1.164 + @end
   1.165 + 
   1.166 + 
   1.167 + 
   1.168 + 
   1.169 ++#pragma mark -
   1.170 + @implementation BLIPListener
   1.171 + 
   1.172 + - (id) initWithPort: (UInt16)port
   1.173 +diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPMessage.m
   1.174 +--- a/BLIP/BLIPMessage.m	Thu Jun 19 10:22:19 2008 -0700
   1.175 ++++ b/BLIP/BLIPMessage.m	Mon Jun 23 14:02:31 2008 -0700
   1.176 +@@ -74,6 +74,8 @@
   1.177 +         [desc appendString: @", urgent"];
   1.178 +     if( _flags & kBLIP_NoReply )
   1.179 +         [desc appendString: @", noreply"];
   1.180 ++    if( _flags & kBLIP_Meta )
   1.181 ++        [desc appendString: @", META"];
   1.182 +     [desc appendString: @"]"];
   1.183 +     return desc;
   1.184 + }
   1.185 +@@ -103,6 +105,8 @@
   1.186 +         _flags &= ~flag;
   1.187 + }
   1.188 + 
   1.189 ++- (BLIPMessageFlags) _flags                 {return _flags;}
   1.190 ++
   1.191 + - (BOOL) compressed                         {return (_flags & kBLIP_Compressed) != 0;}
   1.192 + - (BOOL) urgent                             {return (_flags & kBLIP_Urgent) != 0;}
   1.193 + - (void) setCompressed: (BOOL)compressed    {[self _setFlag: kBLIP_Compressed value: compressed];}
   1.194 +diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPReader.m
   1.195 +--- a/BLIP/BLIPReader.m	Thu Jun 19 10:22:19 2008 -0700
   1.196 ++++ b/BLIP/BLIPReader.m	Mon Jun 23 14:02:31 2008 -0700
   1.197 +@@ -93,7 +93,7 @@
   1.198 + 
   1.199 + - (BOOL) isBusy
   1.200 + {
   1.201 +-    return _curBytesRead > 0;
   1.202 ++    return _curBytesRead > 0 || _pendingRequests.count > 0 || _pendingResponses.count > 0;
   1.203 + }
   1.204 + 
   1.205 + 
   1.206 +diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPRequest.m
   1.207 +--- a/BLIP/BLIPRequest.m	Thu Jun 19 10:22:19 2008 -0700
   1.208 ++++ b/BLIP/BLIPRequest.m	Mon Jun 23 14:02:31 2008 -0700
   1.209 +@@ -199,6 +199,8 @@
   1.210 +         setObj(&_mutableBody,nil);
   1.211 +         
   1.212 +         BLIPMutableProperties *errorProps = [self.properties mutableCopy];
   1.213 ++        if( ! errorProps )
   1.214 ++            errorProps = [[BLIPMutableProperties alloc] init];
   1.215 +         NSDictionary *userInfo = error.userInfo;
   1.216 +         for( NSString *key in userInfo ) {
   1.217 +             id value = $castIf(NSString,[userInfo objectForKey: key]);
   1.218 +@@ -227,8 +229,12 @@
   1.219 + {
   1.220 +     Assert(_connection,@"%@ has no connection to send over",self);
   1.221 +     Assert(!_sent,@"%@ was already sent",self);
   1.222 ++    BLIPWriter *writer = (BLIPWriter*)_connection.writer;
   1.223 ++    Assert(writer,@"%@'s connection has no writer (already closed?)",self);
   1.224 +     [self _encode];
   1.225 +-    return (self.sent = [(BLIPWriter*)_connection.writer sendMessage: self]);
   1.226 ++    BOOL sent = self.sent = [writer sendMessage: self];
   1.227 ++    Assert(sent);
   1.228 ++    return sent;
   1.229 + }
   1.230 + 
   1.231 + 
   1.232 +diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPTest.m
   1.233 +--- a/BLIP/BLIPTest.m	Thu Jun 19 10:22:19 2008 -0700
   1.234 ++++ b/BLIP/BLIPTest.m	Mon Jun 23 14:02:31 2008 -0700
   1.235 +@@ -35,6 +35,7 @@
   1.236 + #define kClientUsesSSLCert          NO
   1.237 + #define kListenerRequiresSSL        NO
   1.238 + #define kListenerRequiresClientCert NO
   1.239 ++#define kListenerCloseAfter         50
   1.240 + 
   1.241 + 
   1.242 + static SecIdentityRef GetClientIdentity(void) {
   1.243 +@@ -100,36 +101,38 @@
   1.244 + 
   1.245 + - (void) sendAMessage
   1.246 + {
   1.247 +-    if(_pending.count<100) {
   1.248 +-        Log(@"** Sending another %i messages...", kNBatchedMessages);
   1.249 +-        for( int i=0; i<kNBatchedMessages; i++ ) {
   1.250 +-            size_t size = random() % 32768;
   1.251 +-            NSMutableData *body = [NSMutableData dataWithLength: size];
   1.252 +-            UInt8 *bytes = body.mutableBytes;
   1.253 +-            for( size_t i=0; i<size; i++ )
   1.254 +-                bytes[i] = i % 256;
   1.255 +-            
   1.256 +-            BLIPRequest *q = [_conn requestWithBody: body
   1.257 +-                                         properties: $dict({@"Content-Type", @"application/octet-stream"},
   1.258 +-                                                           {@"User-Agent", @"BLIPConnectionTester"},
   1.259 +-                                                           {@"Date", [[NSDate date] description]},
   1.260 +-                                                           {@"Size",$sprintf(@"%u",size)})];
   1.261 +-            Assert(q);
   1.262 +-            if( kUseCompression && (random()%2==1) )
   1.263 +-                q.compressed = YES;
   1.264 +-            if( random()%16 > 12 )
   1.265 +-                q.urgent = YES;
   1.266 +-            BLIPResponse *response = [q send];
   1.267 +-            Assert(response);
   1.268 +-            Assert(q.number>0);
   1.269 +-            Assert(response.number==q.number);
   1.270 +-            [_pending setObject: $object(size) forKey: $object(q.number)];
   1.271 +-            response.onComplete = $target(self,responseArrived:);
   1.272 ++    if( _conn.status==kTCP_Open || _conn.status==kTCP_Opening ) {
   1.273 ++        if(_pending.count<100) {
   1.274 ++            Log(@"** Sending another %i messages...", kNBatchedMessages);
   1.275 ++            for( int i=0; i<kNBatchedMessages; i++ ) {
   1.276 ++                size_t size = random() % 32768;
   1.277 ++                NSMutableData *body = [NSMutableData dataWithLength: size];
   1.278 ++                UInt8 *bytes = body.mutableBytes;
   1.279 ++                for( size_t i=0; i<size; i++ )
   1.280 ++                    bytes[i] = i % 256;
   1.281 ++                
   1.282 ++                BLIPRequest *q = [_conn requestWithBody: body
   1.283 ++                                             properties: $dict({@"Content-Type", @"application/octet-stream"},
   1.284 ++                                                               {@"User-Agent", @"BLIPConnectionTester"},
   1.285 ++                                                               {@"Date", [[NSDate date] description]},
   1.286 ++                                                               {@"Size",$sprintf(@"%u",size)})];
   1.287 ++                Assert(q);
   1.288 ++                if( kUseCompression && (random()%2==1) )
   1.289 ++                    q.compressed = YES;
   1.290 ++                if( random()%16 > 12 )
   1.291 ++                    q.urgent = YES;
   1.292 ++                BLIPResponse *response = [q send];
   1.293 ++                Assert(response);
   1.294 ++                Assert(q.number>0);
   1.295 ++                Assert(response.number==q.number);
   1.296 ++                [_pending setObject: $object(size) forKey: $object(q.number)];
   1.297 ++                response.onComplete = $target(self,responseArrived:);
   1.298 ++            }
   1.299 ++        } else {
   1.300 ++            Warn(@"There are %u pending messages; waiting for the listener to catch up...",_pending.count);
   1.301 +         }
   1.302 +-    } else {
   1.303 +-        Warn(@"There are %u pending messages; waiting for the listener to catch up...",_pending.count);
   1.304 ++        [self performSelector: @selector(sendAMessage) withObject: nil afterDelay: kSendInterval];
   1.305 +     }
   1.306 +-    [self performSelector: @selector(sendAMessage) withObject: nil afterDelay: kSendInterval];
   1.307 + }
   1.308 + 
   1.309 + - (void) responseArrived: (BLIPResponse*)response
   1.310 +@@ -191,6 +194,13 @@
   1.311 +     Log(@"Now %u replies pending", _pending.count);
   1.312 + }
   1.313 + 
   1.314 ++- (BOOL) connectionReceivedCloseRequest: (BLIPConnection*)connection
   1.315 ++{
   1.316 ++    BOOL response = NO;
   1.317 ++    Log(@"***** %@ received a close request; returning %i",connection,response);
   1.318 ++    return response;
   1.319 ++}
   1.320 ++
   1.321 + 
   1.322 + @end
   1.323 + 
   1.324 +@@ -217,6 +227,7 @@
   1.325 + @interface BLIPTestListener : NSObject <TCPListenerDelegate, BLIPConnectionDelegate>
   1.326 + {
   1.327 +     BLIPListener *_listener;
   1.328 ++    int _nReceived;
   1.329 + }
   1.330 + 
   1.331 + @end
   1.332 +@@ -277,6 +288,7 @@
   1.333 + - (void) connectionDidOpen: (TCPConnection*)connection
   1.334 + {
   1.335 +     Log(@"** %@ didOpen [SSL=%@]",connection,connection.actualSecurityLevel);
   1.336 ++    _nReceived = 0;
   1.337 + }
   1.338 + - (BOOL) connection: (TCPConnection*)connection authorizeSSLPeer: (SecCertificateRef)peerCert
   1.339 + {
   1.340 +@@ -312,6 +324,22 @@
   1.341 +     AssertEq([[request valueOfProperty: @"Size"] intValue], size);
   1.342 + 
   1.343 +     [request respondWithData: body contentType: request.contentType];
   1.344 ++    
   1.345 ++    if( ++ _nReceived == kListenerCloseAfter ) {
   1.346 ++        Log(@"********** Closing BLIPTestListener after %i requests",_nReceived);
   1.347 ++        [connection close];
   1.348 ++    }
   1.349 ++}
   1.350 ++
   1.351 ++- (BOOL) connectionReceivedCloseRequest: (BLIPConnection*)connection;
   1.352 ++{
   1.353 ++    Log(@"***** %@ received a close request",connection);
   1.354 ++    return YES;
   1.355 ++}
   1.356 ++
   1.357 ++- (void) connection: (BLIPConnection*)connection closeRequestFailedWithError: (NSError*)error
   1.358 ++{
   1.359 ++    Log(@"***** %@'s close request failed: %@",connection,error);
   1.360 + }
   1.361 + 
   1.362 + 
   1.363 +diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIPWriter.m
   1.364 +--- a/BLIP/BLIPWriter.m	Thu Jun 19 10:22:19 2008 -0700
   1.365 ++++ b/BLIP/BLIPWriter.m	Mon Jun 23 14:02:31 2008 -0700
   1.366 +@@ -79,10 +79,6 @@
   1.367 + 
   1.368 + - (BOOL) sendMessage: (BLIPMessage*)message
   1.369 + {
   1.370 +-    if( _shouldClose ) {
   1.371 +-        Warn(@"%@: Attempt to send a message after the connection has started closing",self);
   1.372 +-        return NO;
   1.373 +-    }
   1.374 +     Assert(!message.sent,@"message has already been sent");
   1.375 +     [self _queueMessage: message isNew: YES];
   1.376 +     return YES;
   1.377 +@@ -91,12 +87,14 @@
   1.378 + 
   1.379 + - (BOOL) sendRequest: (BLIPRequest*)q response: (BLIPResponse*)response
   1.380 + {
   1.381 +-    if( !_shouldClose ) {
   1.382 +-        [q _assignedNumber: ++_numRequestsSent];
   1.383 +-        if( response ) {
   1.384 +-            [response _assignedNumber: _numRequestsSent];
   1.385 +-            [(BLIPReader*)self.reader _addPendingResponse: response];
   1.386 +-        }
   1.387 ++    if( _shouldClose ) {
   1.388 ++        Warn(@"%@: Attempt to send a request after the connection has started closing: %@",self,q);
   1.389 ++        return NO;
   1.390 ++    }
   1.391 ++    [q _assignedNumber: ++_numRequestsSent];
   1.392 ++    if( response ) {
   1.393 ++        [response _assignedNumber: _numRequestsSent];
   1.394 ++        [(BLIPReader*)self.reader _addPendingResponse: response];
   1.395 +     }
   1.396 +     return [self sendMessage: q];
   1.397 + }
   1.398 +diff -r 70590cc555aa -r 16454d63d4c2 BLIP/BLIP_Internal.h
   1.399 +--- a/BLIP/BLIP_Internal.h	Thu Jun 19 10:22:19 2008 -0700
   1.400 ++++ b/BLIP/BLIP_Internal.h	Mon Jun 23 14:02:31 2008 -0700
   1.401 +@@ -29,6 +29,7 @@
   1.402 +     kBLIP_Urgent    = 0x0020,       // please send sooner/faster
   1.403 +     kBLIP_NoReply   = 0x0040,       // no RPY needed
   1.404 +     kBLIP_MoreComing= 0x0080,       // More frames coming (Applies only to individual frame)
   1.405 ++    kBLIP_Meta      = 0x0100,       // Special message type, handled internally (hello, bye, ...)
   1.406 + };
   1.407 + typedef UInt16 BLIPMessageFlags;
   1.408 + 
   1.409 +@@ -41,7 +42,10 @@
   1.410 +     UInt16           size;          // total size of frame, _including_ this header
   1.411 + } BLIPFrameHeader;
   1.412 + 
   1.413 +-#define kBLIPFrameHeaderMagicNumber 0x9B34F205
   1.414 ++#define kBLIPFrameHeaderMagicNumber 0x9B34F206
   1.415 ++
   1.416 ++#define kBLIPProfile_Hi  @"Hi"      // Used for Profile header in meta greeting message
   1.417 ++#define kBLIPProfile_Bye @"Bye"     // Used for Profile header in meta close-request message
   1.418 + 
   1.419 + 
   1.420 + @interface BLIPConnection ()
   1.421 +@@ -52,6 +56,7 @@
   1.422 + 
   1.423 + @interface BLIPMessage ()
   1.424 + @property BOOL sent, propertiesAvailable, complete;
   1.425 ++- (BLIPMessageFlags) _flags;
   1.426 + - (void) _setFlag: (BLIPMessageFlags)flag value: (BOOL)value;
   1.427 + - (void) _encode;
   1.428 + @end