# HG changeset patch # User Jens Alfke # Date 1215970970 25200 # Node ID 8b883753394abf3f5c2c05a43ef5badbb1e3641b # Parent 16454d63d4c24a2b8e87c97deb28a0b65ab78f43 * 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. diff -r 16454d63d4c2 -r 8b883753394a BLIP/BLIPMessage.h --- a/BLIP/BLIPMessage.h Mon Jun 23 14:02:31 2008 -0700 +++ b/BLIP/BLIPMessage.h Sun Jul 13 10:42:50 2008 -0700 @@ -45,6 +45,7 @@ NSMutableData *_mutableBody; BOOL _isMine, _isMutable, _sent, _propertiesAvailable, _complete; SInt32 _bytesWritten; + id _representedObject; }; /** The BLIPConnection associated with this message. */ @@ -88,6 +89,10 @@ The UTF-8 character encoding is used to convert. */ @property (copy) NSString *bodyString; +/** An arbitrary object that you can associate with this message for your own purposes. + The message retains it, but doesn't do anything else with it. */ +@property (retain) id representedObject; + #pragma mark PROPERTIES: /** The message's properties, a dictionary-like object. diff -r 16454d63d4c2 -r 8b883753394a BLIP/BLIPMessage.m --- a/BLIP/BLIPMessage.m Mon Jun 23 14:02:31 2008 -0700 +++ b/BLIP/BLIPMessage.m Sun Jul 13 10:42:50 2008 -0700 @@ -93,7 +93,8 @@ @synthesize connection=_connection, number=_number, isMine=_isMine, isMutable=_isMutable, - _bytesWritten, sent=_sent, propertiesAvailable=_propertiesAvailable, complete=_complete; + _bytesWritten, sent=_sent, propertiesAvailable=_propertiesAvailable, complete=_complete, + representedObject=_representedObject; - (void) _setFlag: (BLIPMessageFlags)flag value: (BOOL)value diff -r 16454d63d4c2 -r 8b883753394a BLIP/BLIPRequest.m --- a/BLIP/BLIPRequest.m Mon Jun 23 14:02:31 2008 -0700 +++ b/BLIP/BLIPRequest.m Sun Jul 13 10:42:50 2008 -0700 @@ -175,7 +175,7 @@ if( ! (_flags & kBLIP_ERR) ) return nil; - NSMutableDictionary *userInfo = [[self.properties allProperties] mutableCopy]; + NSMutableDictionary *userInfo = [[[self.properties allProperties] mutableCopy] autorelease]; NSString *domain = [userInfo objectForKey: @"Error-Domain"]; int code = [[userInfo objectForKey: @"Error-Code"] intValue]; if( domain==nil || code==0 ) { @@ -255,7 +255,7 @@ - (void) _connectionClosed { [super _connectionClosed]; - if( !_isMine ) { + if( !_isMine && !_complete ) { // Change incoming response to an error: _isMutable = YES; [_properties autorelease]; @@ -263,6 +263,7 @@ [self _setError: BLIPMakeError(kBLIPError_Disconnected, @"Connection closed before response was received")]; _isMutable = NO; + self.complete = YES; // Calls onComplete target } } diff -r 16454d63d4c2 -r 8b883753394a BLIP/BLIPTest.m --- a/BLIP/BLIPTest.m Mon Jun 23 14:02:31 2008 -0700 +++ b/BLIP/BLIPTest.m Sun Jul 13 10:42:50 2008 -0700 @@ -36,6 +36,7 @@ #define kListenerRequiresSSL NO #define kListenerRequiresClientCert NO #define kListenerCloseAfter 50 +#define kClientAcceptCloseRequest YES static SecIdentityRef GetClientIdentity(void) { @@ -196,7 +197,7 @@ - (BOOL) connectionReceivedCloseRequest: (BLIPConnection*)connection { - BOOL response = NO; + BOOL response = kClientAcceptCloseRequest; Log(@"***** %@ received a close request; returning %i",connection,response); return response; } diff -r 16454d63d4c2 -r 8b883753394a MYNetwork.xcodeproj/project.pbxproj --- a/MYNetwork.xcodeproj/project.pbxproj Mon Jun 23 14:02:31 2008 -0700 +++ b/MYNetwork.xcodeproj/project.pbxproj Sun Jul 13 10:42:50 2008 -0700 @@ -70,6 +70,7 @@ 277905280DE9E5BC00C6D295 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 270461910DE4975C003D9D3F /* CoreServices.framework */; }; 277905300DE9ED9100C6D295 /* MYUtilitiesTest_main.m in Sources */ = {isa = PBXBuildFile; fileRef = 270462C10DE4A64B003D9D3F /* MYUtilitiesTest_main.m */; }; 2779053B0DE9EDAA00C6D295 /* BLIPTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 270460FE0DE49030003D9D3F /* BLIPTest.m */; }; + 277ECFBC0E2A73A100D756BB /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2704618B0DE49652003D9D3F /* libz.dylib */; }; 27D5EC070DE5FEDE00CD84FA /* BLIPRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D5EC060DE5FEDE00CD84FA /* BLIPRequest.m */; }; 27E0DBF00DF3450F00E7F648 /* GTMNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 27E0DBEF0DF3450F00E7F648 /* GTMNSData+zlib.m */; }; 27E0DBF10DF3450F00E7F648 /* GTMNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 27E0DBEF0DF3450F00E7F648 /* GTMNSData+zlib.m */; }; @@ -165,6 +166,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 277ECFBC0E2A73A100D756BB /* libz.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; diff -r 16454d63d4c2 -r 8b883753394a TCP/TCPListener.h --- a/TCP/TCPListener.h Mon Jun 23 14:02:31 2008 -0700 +++ b/TCP/TCPListener.h Sun Jul 13 10:42:50 2008 -0700 @@ -98,6 +98,9 @@ /** Current error status of Bonjour service advertising. See NSNetServicesError for error codes. */ @property (readonly) NSInteger /*NSNetServicesError*/ bonjourError; +/** The NSNetService being published. */ +@property (readonly) NSNetService* bonjourService; + @end diff -r 16454d63d4c2 -r 8b883753394a TCP/TCPListener.m --- a/TCP/TCPListener.m Mon Jun 23 14:02:31 2008 -0700 +++ b/TCP/TCPListener.m Sun Jul 13 10:42:50 2008 -0700 @@ -23,6 +23,8 @@ CFDataRef address, const void *data, void *info); @interface TCPListener() +- (void) _openBonjour; +- (void) _closeBonjour; @property BOOL bonjourPublished; @property NSInteger bonjourError; - (void) _updateTXTRecord; @@ -51,8 +53,9 @@ @synthesize delegate=_delegate, port=_port, useIPv6=_useIPv6, - bonjourServiceType=_bonjourServiceType, bonjourServiceName=_bonjourServiceName, + bonjourServiceType=_bonjourServiceType, bonjourPublished=_bonjourPublished, bonjourError=_bonjourError, + bonjourService=_netService, pickAvailablePort=_pickAvailablePort; @@ -62,7 +65,7 @@ } -// Stores the last error from CFSocketCreate or CFSocketSetAddress into *ouError. +// Stores the last error from CFSocketCreate or CFSocketSetAddress into *outError. static void* getLastCFSocketError( NSError **outError ) { if( outError ) *outError = [NSError errorWithDomain: NSPOSIXErrorDomain code: errno userInfo: nil]; @@ -160,23 +163,7 @@ } } - // Open Bonjour: - if( _bonjourServiceType && !_netService) { - // instantiate the NSNetService object that will advertise on our behalf. - _netService = [[NSNetService alloc] initWithDomain: @"local." - type: _bonjourServiceType - name: _bonjourServiceName ?:@"" - port: _port]; - if( _netService ) { - [_netService setDelegate:self]; - if( _bonjourTXTRecord ) - [self _updateTXTRecord]; - [_netService publish]; - } else { - self.bonjourError = -1; - Warn(@"%@: Failed to create NSNetService",self); - } - } + [self _openBonjour]; LogTo(TCP,@"%@ is open",self); [self tellDelegate: @selector(listenerDidOpen:) withObject: nil]; @@ -192,14 +179,7 @@ - (void) close { if( _ipv4socket ) { - if( _netService ) { - [_netService stop]; - [_netService release]; - _netService = nil; - self.bonjourPublished = NO; - } - self.bonjourError = 0; - + [self _closeBonjour]; _ipv4socket = closeSocket(_ipv4socket); _ipv6socket = closeSocket(_ipv6socket); @@ -266,6 +246,51 @@ #pragma mark BONJOUR: +- (void) _openBonjour +{ + if( self.isOpen && _bonjourServiceType && !_netService) { + // instantiate the NSNetService object that will advertise on our behalf. + _netService = [[NSNetService alloc] initWithDomain: @"local." + type: _bonjourServiceType + name: _bonjourServiceName ?:@"" + port: _port]; + if( _netService ) { + [_netService setDelegate:self]; + if( _bonjourTXTRecord ) + [self _updateTXTRecord]; + [_netService publish]; + } else { + self.bonjourError = -1; + Warn(@"%@: Failed to create NSNetService",self); + } + } +} + +- (void) _closeBonjour +{ + if( _netService ) { + [_netService stop]; + [_netService release]; + _netService = nil; + self.bonjourPublished = NO; + } + if( self.bonjourError ) + self.bonjourError = 0; +} + + +- (NSString*) bonjourServiceName {return _bonjourServiceName;} + +- (void) setBonjourServiceName: (NSString*)name +{ + if( ! $equal(name,_bonjourServiceName) ) { + [self _closeBonjour]; + setObj(&_bonjourServiceName,name); + [self _openBonjour]; + } +} + + - (NSDictionary*) bonjourTXTRecord { return _bonjourTXTRecord;