# HG changeset patch # User Jens Alfke # Date 1243202619 25200 # Node ID 20cccc7c26eed98989eb4281cbf4f033c5a9d494 # Parent 2b4ad206707487ada627742a46dbb297a2fe38e5 Misc. tweaks made while porting Chatty to use MYNetwork. * Allow -[BLIPConnection sendRequest:] to re-send an already-sent or received request. * Allow use of the basic -init method for BLIPConnection. * Some new convenience factory methods. * Broke dependencies on Security.framework out into new TCPEndpoint+Certs.m source file, so client apps aren't forced to link against Security. diff -r 2b4ad2067074 -r 20cccc7c26ee BLIP/BLIPConnection.m --- a/BLIP/BLIPConnection.m Sat May 16 14:24:06 2009 -0700 +++ b/BLIP/BLIPConnection.m Sun May 24 15:03:39 2009 -0700 @@ -121,6 +121,12 @@ - (BLIPResponse*) sendRequest: (BLIPRequest*)request { + if (!request.isMine || request.sent) { + // This was an incoming request that I'm being asked to forward or echo; + // or it's an outgoing request being sent to multiple connections. + // Since a particular BLIPRequest can only be sent once, make a copy of it to send: + request = [[request mutableCopy] autorelease]; + } BLIPConnection *itsConnection = request.connection; if( itsConnection==nil ) request.connection = self; @@ -187,9 +193,9 @@ #pragma mark - @implementation BLIPListener -- (id) initWithPort: (UInt16)port +- (id) init { - self = [super initWithPort: port]; + self = [super init]; if (self != nil) { self.connectionClass = [BLIPConnection class]; } diff -r 2b4ad2067074 -r 20cccc7c26ee BLIP/BLIPRequest.h --- a/BLIP/BLIPRequest.h Sat May 16 14:24:06 2009 -0700 +++ b/BLIP/BLIPRequest.h Sun May 24 15:03:39 2009 -0700 @@ -11,7 +11,7 @@ /** A Request, or initiating message, in the BLIP protocol. */ -@interface BLIPRequest : BLIPMessage +@interface BLIPRequest : BLIPMessage { @private BLIPResponse *_response; @@ -25,6 +25,10 @@ + (BLIPRequest*) requestWithBody: (NSData*)body; /** Creates an outgoing request. + This is just like requestWithBody: except that you supply a string. */ ++ (BLIPRequest*) requestWithBodyString: (NSString*)bodyString; + +/** Creates an outgoing request. The body or properties may be nil. The request is not associated with any BLIPConnection yet, so you must either set its connection property before calling -send, or pass the request as a parameter to diff -r 2b4ad2067074 -r 20cccc7c26ee BLIP/BLIPRequest.m --- a/BLIP/BLIPRequest.m Sat May 16 14:24:06 2009 -0700 +++ b/BLIP/BLIPRequest.m Sun May 24 15:03:39 2009 -0700 @@ -44,12 +44,27 @@ return [[[self alloc] _initWithConnection: nil body: body properties: nil] autorelease]; } ++ (BLIPRequest*) requestWithBodyString: (NSString*)bodyString { + return [self requestWithBody: [bodyString dataUsingEncoding: NSUTF8StringEncoding]]; +} + + (BLIPRequest*) requestWithBody: (NSData*)body properties: (NSDictionary*)properties { return [[[self alloc] _initWithConnection: nil body: body properties: properties] autorelease]; } +- (id)mutableCopyWithZone:(NSZone *)zone +{ + Assert(self.complete); + BLIPRequest *copy = [[self class] requestWithBody: self.body + properties: self.properties.allProperties]; + copy.compressed = self.compressed; + copy.urgent = self.urgent; + copy.noReply = self.noReply; + return [copy retain]; +} + - (void) dealloc { diff -r 2b4ad2067074 -r 20cccc7c26ee Bonjour/MYBonjourService.h --- a/Bonjour/MYBonjourService.h Sat May 16 14:24:06 2009 -0700 +++ b/Bonjour/MYBonjourService.h Sun May 24 15:03:39 2009 -0700 @@ -7,7 +7,6 @@ // #import "MYDNSService.h" -#import "ConcurrentOperation.h" @class MYBonjourQuery, MYAddressLookup; diff -r 2b4ad2067074 -r 20cccc7c26ee IPAddress.h --- a/IPAddress.h Sat May 16 14:24:06 2009 -0700 +++ b/IPAddress.h Sun May 24 15:03:39 2009 -0700 @@ -25,6 +25,12 @@ be returned instead. */ - (id) initWithHostname: (NSString*)hostname port: (UInt16)port; +/** Creates an IPAddress from a host name (which may be a DNS name or dotted-quad numeric form) + and port number. + If the hostname is not in dotted-quad form, an instance of the subclass HostAddress will + be returned instead. */ ++ (IPAddress*) addressWithHostname: (NSString*)hostname port: (UInt16)port; + /** Initializes an IPAddress from a raw IPv4 address (in network byte order, i.e. big-endian) and port number (in native byte order) */ - (id) initWithIPv4: (UInt32)ipv4 port: (UInt16)port; diff -r 2b4ad2067074 -r 20cccc7c26ee IPAddress.m --- a/IPAddress.m Sat May 16 14:24:06 2009 -0700 +++ b/IPAddress.m Sun May 24 15:03:39 2009 -0700 @@ -56,6 +56,11 @@ return self; } ++ (IPAddress*) addressWithHostname: (NSString*)hostname port: (UInt16)port +{ + return [[[self alloc] initWithHostname: hostname port: port] autorelease]; +} + - (id) initWithIPv4: (UInt32)ipv4 port: (UInt16)port { diff -r 2b4ad2067074 -r 20cccc7c26ee MYNetwork-iPhone.xcodeproj/project.pbxproj --- a/MYNetwork-iPhone.xcodeproj/project.pbxproj Sat May 16 14:24:06 2009 -0700 +++ b/MYNetwork-iPhone.xcodeproj/project.pbxproj Sun May 24 15:03:39 2009 -0700 @@ -41,6 +41,7 @@ 278C1B2F0F9F865800954AE1 /* PortMapperTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 278C1B2D0F9F865800954AE1 /* PortMapperTest.m */; }; 278C1B350F9F86A100954AE1 /* MYUtilities_Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 278C1B330F9F86A100954AE1 /* MYUtilities_Debug.xcconfig */; }; 278C1B360F9F86A100954AE1 /* MYUtilities_Release.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 278C1B340F9F86A100954AE1 /* MYUtilities_Release.xcconfig */; }; + 27C6A22B0FC5D92000EFF2A7 /* TCPEndpoint+Certs.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C6A22A0FC5D92000EFF2A7 /* TCPEndpoint+Certs.m */; }; 27D915BF0FA8EABC002B0DEC /* MYDNSService.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D915BC0FA8EABC002B0DEC /* MYDNSService.m */; }; 27D915C00FA8EABC002B0DEC /* MYAddressLookup.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D915BE0FA8EABC002B0DEC /* MYAddressLookup.m */; }; 27D915C90FA8EAD0002B0DEC /* MYBonjourBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D915C20FA8EAD0002B0DEC /* MYBonjourBrowser.m */; }; @@ -147,6 +148,7 @@ 278C1B2D0F9F865800954AE1 /* PortMapperTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PortMapperTest.m; sourceTree = ""; }; 278C1B330F9F86A100954AE1 /* MYUtilities_Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = MYUtilities_Debug.xcconfig; sourceTree = ""; }; 278C1B340F9F86A100954AE1 /* MYUtilities_Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = MYUtilities_Release.xcconfig; sourceTree = ""; }; + 27C6A22A0FC5D92000EFF2A7 /* TCPEndpoint+Certs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TCPEndpoint+Certs.m"; sourceTree = ""; }; 27D915BB0FA8EABC002B0DEC /* MYDNSService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MYDNSService.h; path = PortMapper/MYDNSService.h; sourceTree = ""; }; 27D915BC0FA8EABC002B0DEC /* MYDNSService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MYDNSService.m; path = PortMapper/MYDNSService.m; sourceTree = ""; }; 27D915BD0FA8EABC002B0DEC /* MYAddressLookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MYAddressLookup.h; path = Bonjour/MYAddressLookup.h; sourceTree = ""; }; @@ -233,6 +235,7 @@ 270E9AA50EE61113003F17CA /* TCPConnection.m */, 270E9AA60EE61113003F17CA /* TCPEndpoint.h */, 270E9AA70EE61113003F17CA /* TCPEndpoint.m */, + 27C6A22A0FC5D92000EFF2A7 /* TCPEndpoint+Certs.m */, 270E9AA80EE61113003F17CA /* TCPListener.h */, 270E9AA90EE61113003F17CA /* TCPListener.m */, 270E9AAA0EE61113003F17CA /* TCPStream.h */, @@ -519,6 +522,7 @@ 27D915CB0FA8EAD0002B0DEC /* MYBonjourQuery.m in Sources */, 27D915CC0FA8EAD0002B0DEC /* MYBonjourRegistration.m in Sources */, 384A72B70FB0062C006A0B19 /* ConcurrentOperation.m in Sources */, + 27C6A22B0FC5D92000EFF2A7 /* TCPEndpoint+Certs.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff -r 2b4ad2067074 -r 20cccc7c26ee MYNetwork.xcodeproj/project.pbxproj --- a/MYNetwork.xcodeproj/project.pbxproj Sat May 16 14:24:06 2009 -0700 +++ b/MYNetwork.xcodeproj/project.pbxproj Sun May 24 15:03:39 2009 -0700 @@ -25,6 +25,9 @@ 270461470DE491A6003D9D3F /* Target.m in Sources */ = {isa = PBXBuildFile; fileRef = 270461460DE491A6003D9D3F /* Target.m */; }; 270461890DE49634003D9D3F /* CollectionUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 270461870DE49634003D9D3F /* CollectionUtils.m */; }; 2706F1D90F9D3EF300292CCF /* SecurityInterface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2706F1D80F9D3EF300292CCF /* SecurityInterface.framework */; }; + 27375DFB0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m in Sources */ = {isa = PBXBuildFile; fileRef = 27375DFA0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m */; }; + 27375DFC0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m in Sources */ = {isa = PBXBuildFile; fileRef = 27375DFA0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m */; }; + 27375DFD0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m in Sources */ = {isa = PBXBuildFile; fileRef = 27375DFA0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m */; }; 273B457B0FA681EE00276298 /* MYBonjourRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = 273B45790FA681EE00276298 /* MYBonjourRegistration.h */; }; 273B457C0FA681EE00276298 /* MYBonjourRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = 273B457A0FA681EE00276298 /* MYBonjourRegistration.m */; }; 273B457D0FA681EE00276298 /* MYBonjourRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = 273B457A0FA681EE00276298 /* MYBonjourRegistration.m */; }; @@ -168,6 +171,7 @@ 270462C10DE4A64B003D9D3F /* MYUtilitiesTest_main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYUtilitiesTest_main.m; sourceTree = ""; }; 270462C30DE4A65B003D9D3F /* BLIP Overview.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "BLIP Overview.txt"; path = "BLIP/BLIP Overview.txt"; sourceTree = ""; wrapsLines = 1; }; 2706F1D80F9D3EF300292CCF /* SecurityInterface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SecurityInterface.framework; path = System/Library/Frameworks/SecurityInterface.framework; sourceTree = SDKROOT; }; + 27375DFA0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TCPEndpoint+Certs.m"; sourceTree = ""; }; 273B45790FA681EE00276298 /* MYBonjourRegistration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYBonjourRegistration.h; sourceTree = ""; }; 273B457A0FA681EE00276298 /* MYBonjourRegistration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYBonjourRegistration.m; sourceTree = ""; }; 274122DD0F9CDD1600F21842 /* MYUtilities_Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = MYUtilities_Debug.xcconfig; sourceTree = ""; }; @@ -337,6 +341,7 @@ 2704610A0DE49030003D9D3F /* TCPConnection.m */, 2704610B0DE49030003D9D3F /* TCPEndpoint.h */, 2704610C0DE49030003D9D3F /* TCPEndpoint.m */, + 27375DFA0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m */, 2704610D0DE49030003D9D3F /* TCPListener.h */, 2704610E0DE49030003D9D3F /* TCPListener.m */, 2704610F0DE49030003D9D3F /* TCPStream.h */, @@ -561,6 +566,7 @@ buildActionMask = 2147483647; files = ( 279DDCD10F9E38DD00D75D91 /* BLIPEchoClient.m in Sources */, + 27375DFC0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -569,6 +575,7 @@ buildActionMask = 2147483647; files = ( 277905240DE9E5BC00C6D295 /* BLIPEchoServer.m in Sources */, + 27375DFD0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -641,6 +648,7 @@ 2780F43A0FA28F4400C0FB83 /* MYBonjourQuery.m in Sources */, 2780F4A30FA2C59000C0FB83 /* MYAddressLookup.m in Sources */, 273B457D0FA681EE00276298 /* MYBonjourRegistration.m in Sources */, + 27375DFB0FC9FB5C0033F8F5 /* TCPEndpoint+Certs.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff -r 2b4ad2067074 -r 20cccc7c26ee TCP/TCPConnection.m --- a/TCP/TCPConnection.m Sat May 16 14:24:06 2009 -0700 +++ b/TCP/TCPConnection.m Sun May 24 15:03:39 2009 -0700 @@ -361,7 +361,8 @@ allow = NO; // Server MUST have a cert! else { SecCertificateRef cert = certs.count ?(SecCertificateRef)[certs objectAtIndex:0] :NULL; - LogTo(TCP,@"%@: Peer cert = %@",self,[TCPEndpoint describeCert: cert]); + if ([TCPEndpoint respondsToSelector: @selector(describeCert:)]) + LogTo(TCP,@"%@: Peer cert = %@",self,[TCPEndpoint describeCert: cert]); if( [_delegate respondsToSelector: @selector(connection:authorizeSSLPeer:)] ) allow = [_delegate connection: self authorizeSSLPeer: cert]; } diff -r 2b4ad2067074 -r 20cccc7c26ee TCP/TCPEndpoint+Certs.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TCP/TCPEndpoint+Certs.m Sun May 24 15:03:39 2009 -0700 @@ -0,0 +1,53 @@ +// +// TCPEndpoint+Certs.m +// MYNetwork-iPhone +// +// Created by Jens Alfke on 5/21/09. +// Copyright 2009 Jens Alfke. All rights reserved. +// + +#import "TCPEndpoint.h" +#import "CollectionUtils.h" +#import + + +/** These are some optional category methods for TCPEndpoint for dumping info about certificates. + They're useful if you're working with SSL connections, but they do link against the Security + framework, so they're moved into this extra file that you can choose to compile into your + project or not. +*/ +@implementation TCPEndpoint (Certificates) + + ++ (NSString*) describeCert: (SecCertificateRef)cert { + if (!cert) + return @"(null)"; + NSString *desc; +#if TARGET_OS_IPHONE && !defined(__SEC_TYPES__) + CFStringRef summary = NULL; + SecCertificateCopySubjectSummary(cert); + desc = $sprintf(@"Certificate[%@]", summary); + if(summary) CFRelease(summary); +#else + CFStringRef name=NULL; + CFArrayRef emails=NULL; + SecCertificateCopyCommonName(cert, &name); + SecCertificateCopyEmailAddresses(cert, &emails); + desc = $sprintf(@"Certificate[\"%@\", <%@>]", + name, [(NSArray*)emails componentsJoinedByString: @">, <"]); + if(name) CFRelease(name); + if(emails) CFRelease(emails); +#endif + return desc; +} + ++ (NSString*) describeIdentity: (SecIdentityRef)identity { + if (!identity) + return @"(null)"; + SecCertificateRef cert; + SecIdentityCopyCertificate(identity, &cert); + return $sprintf(@"Identity[%@]", [self describeCert: cert]); +} + + +@end diff -r 2b4ad2067074 -r 20cccc7c26ee TCP/TCPEndpoint.m --- a/TCP/TCPEndpoint.m Sat May 16 14:24:06 2009 -0700 +++ b/TCP/TCPEndpoint.m Sun May 24 15:03:39 2009 -0700 @@ -69,37 +69,6 @@ } -+ (NSString*) describeCert: (SecCertificateRef)cert { - if (!cert) - return @"(null)"; - NSString *desc; -#if TARGET_OS_IPHONE && !defined(__SEC_TYPES__) - CFStringRef summary = NULL; - SecCertificateCopySubjectSummary(cert); - desc = $sprintf(@"Certificate[%@]", summary); - if(summary) CFRelease(summary); -#else - CFStringRef name=NULL; - CFArrayRef emails=NULL; - SecCertificateCopyCommonName(cert, &name); - SecCertificateCopyEmailAddresses(cert, &emails); - desc = $sprintf(@"Certificate[\"%@\", <%@>]", - name, [(NSArray*)emails componentsJoinedByString: @">, <"]); - if(name) CFRelease(name); - if(emails) CFRelease(emails); -#endif - return desc; -} - -+ (NSString*) describeIdentity: (SecIdentityRef)identity { - if (!identity) - return @"(null)"; - SecCertificateRef cert; - SecIdentityCopyCertificate(identity, &cert); - return $sprintf(@"Identity[%@]", [self describeCert: cert]); -} - - @end diff -r 2b4ad2067074 -r 20cccc7c26ee TCP/TCPListener.m --- a/TCP/TCPListener.m Sat May 16 14:24:06 2009 -0700 +++ b/TCP/TCPListener.m Sun May 24 15:03:39 2009 -0700 @@ -34,9 +34,19 @@ @implementation TCPListener +- (id) init +{ + self = [super init]; + if (self != nil) { + _connectionClass = [TCPConnection class]; + } + return self; +} + + - (id) initWithPort: (UInt16)port { - self = [super init]; + self = [self init]; if (self != nil) { _port = port; }