1.1 --- a/1_0_to_1_1_diffs.diff Thu Jul 02 17:51:35 2009 -0700
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,425 +0,0 @@
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