* Fixed: Responses still pending when a connection closed were not calling their onComplete targets.
* Fixed: BLIPTestClient target failed to build because it didn't link against zlib.
* If TCPListener.bonjourServiceName is changed while the listener is open, it now re-publishes the service with the new name.
* Added a TCPListener.bonjourService property.
* Added a BLIPMessage.representedObject property.
* Fixed a memory leak.
1.1 --- a/BLIP/BLIPMessage.h Mon Jun 23 14:02:31 2008 -0700
1.2 +++ b/BLIP/BLIPMessage.h Sun Jul 13 10:42:50 2008 -0700
1.3 @@ -45,6 +45,7 @@
1.4 NSMutableData *_mutableBody;
1.5 BOOL _isMine, _isMutable, _sent, _propertiesAvailable, _complete;
1.6 SInt32 _bytesWritten;
1.7 + id _representedObject;
1.8 };
1.9
1.10 /** The BLIPConnection associated with this message. */
1.11 @@ -88,6 +89,10 @@
1.12 The UTF-8 character encoding is used to convert. */
1.13 @property (copy) NSString *bodyString;
1.14
1.15 +/** An arbitrary object that you can associate with this message for your own purposes.
1.16 + The message retains it, but doesn't do anything else with it. */
1.17 +@property (retain) id representedObject;
1.18 +
1.19 #pragma mark PROPERTIES:
1.20
1.21 /** The message's properties, a dictionary-like object.
2.1 --- a/BLIP/BLIPMessage.m Mon Jun 23 14:02:31 2008 -0700
2.2 +++ b/BLIP/BLIPMessage.m Sun Jul 13 10:42:50 2008 -0700
2.3 @@ -93,7 +93,8 @@
2.4
2.5
2.6 @synthesize connection=_connection, number=_number, isMine=_isMine, isMutable=_isMutable,
2.7 - _bytesWritten, sent=_sent, propertiesAvailable=_propertiesAvailable, complete=_complete;
2.8 + _bytesWritten, sent=_sent, propertiesAvailable=_propertiesAvailable, complete=_complete,
2.9 + representedObject=_representedObject;
2.10
2.11
2.12 - (void) _setFlag: (BLIPMessageFlags)flag value: (BOOL)value
3.1 --- a/BLIP/BLIPRequest.m Mon Jun 23 14:02:31 2008 -0700
3.2 +++ b/BLIP/BLIPRequest.m Sun Jul 13 10:42:50 2008 -0700
3.3 @@ -175,7 +175,7 @@
3.4 if( ! (_flags & kBLIP_ERR) )
3.5 return nil;
3.6
3.7 - NSMutableDictionary *userInfo = [[self.properties allProperties] mutableCopy];
3.8 + NSMutableDictionary *userInfo = [[[self.properties allProperties] mutableCopy] autorelease];
3.9 NSString *domain = [userInfo objectForKey: @"Error-Domain"];
3.10 int code = [[userInfo objectForKey: @"Error-Code"] intValue];
3.11 if( domain==nil || code==0 ) {
3.12 @@ -255,7 +255,7 @@
3.13 - (void) _connectionClosed
3.14 {
3.15 [super _connectionClosed];
3.16 - if( !_isMine ) {
3.17 + if( !_isMine && !_complete ) {
3.18 // Change incoming response to an error:
3.19 _isMutable = YES;
3.20 [_properties autorelease];
3.21 @@ -263,6 +263,7 @@
3.22 [self _setError: BLIPMakeError(kBLIPError_Disconnected,
3.23 @"Connection closed before response was received")];
3.24 _isMutable = NO;
3.25 + self.complete = YES; // Calls onComplete target
3.26 }
3.27 }
3.28
4.1 --- a/BLIP/BLIPTest.m Mon Jun 23 14:02:31 2008 -0700
4.2 +++ b/BLIP/BLIPTest.m Sun Jul 13 10:42:50 2008 -0700
4.3 @@ -36,6 +36,7 @@
4.4 #define kListenerRequiresSSL NO
4.5 #define kListenerRequiresClientCert NO
4.6 #define kListenerCloseAfter 50
4.7 +#define kClientAcceptCloseRequest YES
4.8
4.9
4.10 static SecIdentityRef GetClientIdentity(void) {
4.11 @@ -196,7 +197,7 @@
4.12
4.13 - (BOOL) connectionReceivedCloseRequest: (BLIPConnection*)connection
4.14 {
4.15 - BOOL response = NO;
4.16 + BOOL response = kClientAcceptCloseRequest;
4.17 Log(@"***** %@ received a close request; returning %i",connection,response);
4.18 return response;
4.19 }
5.1 --- a/MYNetwork.xcodeproj/project.pbxproj Mon Jun 23 14:02:31 2008 -0700
5.2 +++ b/MYNetwork.xcodeproj/project.pbxproj Sun Jul 13 10:42:50 2008 -0700
5.3 @@ -70,6 +70,7 @@
5.4 277905280DE9E5BC00C6D295 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 270461910DE4975C003D9D3F /* CoreServices.framework */; };
5.5 277905300DE9ED9100C6D295 /* MYUtilitiesTest_main.m in Sources */ = {isa = PBXBuildFile; fileRef = 270462C10DE4A64B003D9D3F /* MYUtilitiesTest_main.m */; };
5.6 2779053B0DE9EDAA00C6D295 /* BLIPTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 270460FE0DE49030003D9D3F /* BLIPTest.m */; };
5.7 + 277ECFBC0E2A73A100D756BB /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2704618B0DE49652003D9D3F /* libz.dylib */; };
5.8 27D5EC070DE5FEDE00CD84FA /* BLIPRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D5EC060DE5FEDE00CD84FA /* BLIPRequest.m */; };
5.9 27E0DBF00DF3450F00E7F648 /* GTMNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 27E0DBEF0DF3450F00E7F648 /* GTMNSData+zlib.m */; };
5.10 27E0DBF10DF3450F00E7F648 /* GTMNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 27E0DBEF0DF3450F00E7F648 /* GTMNSData+zlib.m */; };
5.11 @@ -165,6 +166,7 @@
5.12 isa = PBXFrameworksBuildPhase;
5.13 buildActionMask = 2147483647;
5.14 files = (
5.15 + 277ECFBC0E2A73A100D756BB /* libz.dylib in Frameworks */,
5.16 );
5.17 runOnlyForDeploymentPostprocessing = 0;
5.18 };
6.1 --- a/TCP/TCPListener.h Mon Jun 23 14:02:31 2008 -0700
6.2 +++ b/TCP/TCPListener.h Sun Jul 13 10:42:50 2008 -0700
6.3 @@ -98,6 +98,9 @@
6.4 /** Current error status of Bonjour service advertising. See NSNetServicesError for error codes. */
6.5 @property (readonly) NSInteger /*NSNetServicesError*/ bonjourError;
6.6
6.7 +/** The NSNetService being published. */
6.8 +@property (readonly) NSNetService* bonjourService;
6.9 +
6.10
6.11 @end
6.12
7.1 --- a/TCP/TCPListener.m Mon Jun 23 14:02:31 2008 -0700
7.2 +++ b/TCP/TCPListener.m Sun Jul 13 10:42:50 2008 -0700
7.3 @@ -23,6 +23,8 @@
7.4 CFDataRef address, const void *data, void *info);
7.5
7.6 @interface TCPListener()
7.7 +- (void) _openBonjour;
7.8 +- (void) _closeBonjour;
7.9 @property BOOL bonjourPublished;
7.10 @property NSInteger bonjourError;
7.11 - (void) _updateTXTRecord;
7.12 @@ -51,8 +53,9 @@
7.13
7.14
7.15 @synthesize delegate=_delegate, port=_port, useIPv6=_useIPv6,
7.16 - bonjourServiceType=_bonjourServiceType, bonjourServiceName=_bonjourServiceName,
7.17 + bonjourServiceType=_bonjourServiceType,
7.18 bonjourPublished=_bonjourPublished, bonjourError=_bonjourError,
7.19 + bonjourService=_netService,
7.20 pickAvailablePort=_pickAvailablePort;
7.21
7.22
7.23 @@ -62,7 +65,7 @@
7.24 }
7.25
7.26
7.27 -// Stores the last error from CFSocketCreate or CFSocketSetAddress into *ouError.
7.28 +// Stores the last error from CFSocketCreate or CFSocketSetAddress into *outError.
7.29 static void* getLastCFSocketError( NSError **outError ) {
7.30 if( outError )
7.31 *outError = [NSError errorWithDomain: NSPOSIXErrorDomain code: errno userInfo: nil];
7.32 @@ -160,23 +163,7 @@
7.33 }
7.34 }
7.35
7.36 - // Open Bonjour:
7.37 - if( _bonjourServiceType && !_netService) {
7.38 - // instantiate the NSNetService object that will advertise on our behalf.
7.39 - _netService = [[NSNetService alloc] initWithDomain: @"local."
7.40 - type: _bonjourServiceType
7.41 - name: _bonjourServiceName ?:@""
7.42 - port: _port];
7.43 - if( _netService ) {
7.44 - [_netService setDelegate:self];
7.45 - if( _bonjourTXTRecord )
7.46 - [self _updateTXTRecord];
7.47 - [_netService publish];
7.48 - } else {
7.49 - self.bonjourError = -1;
7.50 - Warn(@"%@: Failed to create NSNetService",self);
7.51 - }
7.52 - }
7.53 + [self _openBonjour];
7.54
7.55 LogTo(TCP,@"%@ is open",self);
7.56 [self tellDelegate: @selector(listenerDidOpen:) withObject: nil];
7.57 @@ -192,14 +179,7 @@
7.58 - (void) close
7.59 {
7.60 if( _ipv4socket ) {
7.61 - if( _netService ) {
7.62 - [_netService stop];
7.63 - [_netService release];
7.64 - _netService = nil;
7.65 - self.bonjourPublished = NO;
7.66 - }
7.67 - self.bonjourError = 0;
7.68 -
7.69 + [self _closeBonjour];
7.70 _ipv4socket = closeSocket(_ipv4socket);
7.71 _ipv6socket = closeSocket(_ipv6socket);
7.72
7.73 @@ -266,6 +246,51 @@
7.74 #pragma mark BONJOUR:
7.75
7.76
7.77 +- (void) _openBonjour
7.78 +{
7.79 + if( self.isOpen && _bonjourServiceType && !_netService) {
7.80 + // instantiate the NSNetService object that will advertise on our behalf.
7.81 + _netService = [[NSNetService alloc] initWithDomain: @"local."
7.82 + type: _bonjourServiceType
7.83 + name: _bonjourServiceName ?:@""
7.84 + port: _port];
7.85 + if( _netService ) {
7.86 + [_netService setDelegate:self];
7.87 + if( _bonjourTXTRecord )
7.88 + [self _updateTXTRecord];
7.89 + [_netService publish];
7.90 + } else {
7.91 + self.bonjourError = -1;
7.92 + Warn(@"%@: Failed to create NSNetService",self);
7.93 + }
7.94 + }
7.95 +}
7.96 +
7.97 +- (void) _closeBonjour
7.98 +{
7.99 + if( _netService ) {
7.100 + [_netService stop];
7.101 + [_netService release];
7.102 + _netService = nil;
7.103 + self.bonjourPublished = NO;
7.104 + }
7.105 + if( self.bonjourError )
7.106 + self.bonjourError = 0;
7.107 +}
7.108 +
7.109 +
7.110 +- (NSString*) bonjourServiceName {return _bonjourServiceName;}
7.111 +
7.112 +- (void) setBonjourServiceName: (NSString*)name
7.113 +{
7.114 + if( ! $equal(name,_bonjourServiceName) ) {
7.115 + [self _closeBonjour];
7.116 + setObj(&_bonjourServiceName,name);
7.117 + [self _openBonjour];
7.118 + }
7.119 +}
7.120 +
7.121 +
7.122 - (NSDictionary*) bonjourTXTRecord
7.123 {
7.124 return _bonjourTXTRecord;