From 8ab53f74d5fa4ddc8656823dfeae5d42f7bdea19 Mon Sep 17 00:00:00 2001 From: jaanus Date: Fri, 16 May 2014 11:18:47 +0200 Subject: [PATCH] Can specify a custom Bonjour service type for the server. --- GCDWebServer/Core/GCDWebServer.h | 39 ++++++++++++++++++++++++++++++++ GCDWebServer/Core/GCDWebServer.m | 22 ++++++++++++++++-- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/GCDWebServer/Core/GCDWebServer.h b/GCDWebServer/Core/GCDWebServer.h index 93dba4a..540d166 100644 --- a/GCDWebServer/Core/GCDWebServer.h +++ b/GCDWebServer/Core/GCDWebServer.h @@ -83,6 +83,13 @@ extern NSString* const GCDWebServerOption_Port; */ extern NSString* const GCDWebServerOption_BonjourName; +/** + * The Bonjour service type used by the GCDWebServer (NSString). + * + * The default value is "_http._tcp", standard HTTP web server. + */ +extern NSString* const GCDWebServerOption_BonjourType; + /** * The maximum number of incoming HTTP requests that can be queued waiting to * be handled before new ones are dropped (NSNumber / NSUInteger). @@ -266,6 +273,14 @@ extern NSString* const GCDWebServerAuthenticationMethod_DigestAccess; */ @property(nonatomic, readonly) NSString* bonjourName; +/** + * Returns the Bonjour service type used by the server. + * + * @warning This property is only valid if the server is running and Bonjour + * registration has successfully completed, which can take up to a few seconds. + */ +@property(nonatomic, readonly) NSString* bonjourType; + /** * This method is the designated initializer for the class. */ @@ -341,6 +356,18 @@ extern NSString* const GCDWebServerAuthenticationMethod_DigestAccess; */ - (BOOL)startWithPort:(NSUInteger)port bonjourName:(NSString*)name; +/** + * Starts the server on a given port and with a specific Bonjour name and type. + * Pass a nil Bonjour name to disable Bonjour entirely or an empty string to + * use the computer / device name. + * Pass a nil or empty string to Bonjour type to use the standard + * HTTP web server type "_http._tcp". + * + * Returns NO if the server failed to start. + */ +- (BOOL)startWithPort:(NSUInteger)port bonjourName:(NSString*)name bonjourType:(NSString*)bonjourType; + + #if !TARGET_OS_IPHONE /** @@ -354,6 +381,18 @@ extern NSString* const GCDWebServerAuthenticationMethod_DigestAccess; */ - (BOOL)runWithPort:(NSUInteger)port bonjourName:(NSString*)name; +/** + * Runs the server synchronously using -startWithPort:bonjourName:bonjourType: + * until a SIGINT signal is received i.e. Ctrl-C. This method is intended + * to be used by command line tools. + * + * Returns NO if the server failed to start. + * + * @warning This method must be used from the main thread only. + */ +- (BOOL)runWithPort:(NSUInteger)port bonjourName:(NSString*)name bonjourType:(NSString*)bonjourType; + + /** * Runs the server synchronously using -startWithOptions: until a SIGTERM or * SIGINT signal is received i.e. Ctrl-C in Terminal. This method is intended to diff --git a/GCDWebServer/Core/GCDWebServer.m b/GCDWebServer/Core/GCDWebServer.m index 43682f6..072eded 100644 --- a/GCDWebServer/Core/GCDWebServer.m +++ b/GCDWebServer/Core/GCDWebServer.m @@ -45,6 +45,7 @@ NSString* const GCDWebServerOption_Port = @"Port"; NSString* const GCDWebServerOption_BonjourName = @"BonjourName"; +NSString* const GCDWebServerOption_BonjourType = @"BonjourType"; NSString* const GCDWebServerOption_MaxPendingConnections = @"MaxPendingConnections"; NSString* const GCDWebServerOption_ServerName = @"ServerName"; NSString* const GCDWebServerOption_AuthenticationMethod = @"AuthenticationMethod"; @@ -342,6 +343,11 @@ static void _DisconnectTimerCallBack(CFRunLoopTimerRef timer, void* info) { return name && CFStringGetLength(name) ? ARC_BRIDGE_RELEASE(CFStringCreateCopy(kCFAllocatorDefault, name)) : nil; } +- (NSString*)bonjourType { + CFStringRef type = _service ? CFNetServiceGetType(_service) : NULL; + return type && CFStringGetLength(type) ? ARC_BRIDGE_RELEASE(CFStringCreateCopy(kCFAllocatorDefault, type)) : nil; +} + - (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)handlerBlock { DCHECK(_options == nil); GCDWebServerHandler* handler = [[GCDWebServerHandler alloc] initWithMatchBlock:matchBlock processBlock:handlerBlock]; @@ -388,6 +394,7 @@ static inline NSString* _EncodeBase64(NSString* string) { DCHECK(_source == NULL); NSUInteger port = [_GetOption(_options, GCDWebServerOption_Port, @0) unsignedIntegerValue]; NSString* name = _GetOption(_options, GCDWebServerOption_BonjourName, @""); + NSString* bonjourType = _GetOption(_options, GCDWebServerOption_BonjourType, @"_http._tcp"); NSUInteger maxPendingConnections = [_GetOption(_options, GCDWebServerOption_MaxPendingConnections, @16) unsignedIntegerValue]; int listeningSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (listeningSocket > 0) { @@ -485,7 +492,7 @@ static inline NSString* _EncodeBase64(NSString* string) { } if (name) { - _service = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), CFSTR("_http._tcp"), (ARC_BRIDGE CFStringRef)name, (SInt32)_port); + _service = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), (ARC_BRIDGE CFStringRef)bonjourType, (ARC_BRIDGE CFStringRef)name, (SInt32)_port); if (_service) { CFNetServiceClientContext context = {0, (ARC_BRIDGE void*)self, NULL, NULL, NULL}; CFNetServiceSetClient(_service, _NetServiceClientCallBack, &context); @@ -674,18 +681,29 @@ static inline NSString* _EncodeBase64(NSString* string) { } - (BOOL)startWithPort:(NSUInteger)port bonjourName:(NSString*)name { + return [self startWithPort:port bonjourName:name bonjourType:nil]; +} + +- (BOOL)startWithPort:(NSUInteger)port bonjourName:(NSString*)name bonjourType:(NSString *)bonjourType { NSMutableDictionary* options = [NSMutableDictionary dictionary]; [options setObject:[NSNumber numberWithInteger:port] forKey:GCDWebServerOption_Port]; [options setValue:name forKey:GCDWebServerOption_BonjourName]; + if (bonjourType.length) { [options setObject:bonjourType forKey:GCDWebServerOption_BonjourType]; } return [self startWithOptions:options error:NULL]; } #if !TARGET_OS_IPHONE -- (BOOL)runWithPort:(NSUInteger)port bonjourName:(NSString*)name { +- (BOOL)runWithPort:(NSUInteger)port bonjourName:(NSString*)name +{ + return [self runWithPort:port bonjourName:name bonjourType:nil]; +} + +- (BOOL)runWithPort:(NSUInteger)port bonjourName:(NSString*)name bonjourType:(NSString*)bonjourType { NSMutableDictionary* options = [NSMutableDictionary dictionary]; [options setObject:[NSNumber numberWithInteger:port] forKey:GCDWebServerOption_Port]; [options setValue:name forKey:GCDWebServerOption_BonjourName]; + if (bonjourType.length) { [options setObject:bonjourType forKey:GCDWebServerOption_BonjourType]; } return [self runWithOptions:options error:NULL]; }