From d404112a8882a53b72864afde3e3291eaf63ac29 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Latour Date: Sun, 27 Apr 2014 19:19:55 -0700 Subject: [PATCH] #46 Added "error" argument to -startWithOptions: --- GCDWebServer/Core/GCDWebServer.h | 8 ++-- GCDWebServer/Core/GCDWebServer.m | 39 ++++++++++++------- GCDWebServer/Core/GCDWebServerPrivate.h | 4 ++ .../Requests/GCDWebServerFileRequest.m | 10 ++--- .../Responses/GCDWebServerFileResponse.m | 10 ++--- Mac/main.m | 2 +- 6 files changed, 39 insertions(+), 34 deletions(-) diff --git a/GCDWebServer/Core/GCDWebServer.h b/GCDWebServer/Core/GCDWebServer.h index e80e485..7075313 100644 --- a/GCDWebServer/Core/GCDWebServer.h +++ b/GCDWebServer/Core/GCDWebServer.h @@ -288,9 +288,9 @@ extern NSString* const GCDWebServerAuthenticationMethod_DigestAccess; * Starts the server with explicit options. This method is the designated way * to start the server. * - * Returns NO if the server failed to start. + * Returns NO if the server failed to start and sets "error" argument if not NULL. */ -- (BOOL)startWithOptions:(NSDictionary*)options; +- (BOOL)startWithOptions:(NSDictionary*)options error:(NSError**)error; /** * Stops the server and prevents it to accepts new HTTP requests. @@ -355,11 +355,11 @@ extern NSString* const GCDWebServerAuthenticationMethod_DigestAccess; * 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. + * Returns NO if the server failed to start and sets "error" argument if not NULL. * * @warning This method must be used from the main thread only. */ -- (BOOL)runWithOptions:(NSDictionary*)options; +- (BOOL)runWithOptions:(NSDictionary*)options error:(NSError**)error; #endif diff --git a/GCDWebServer/Core/GCDWebServer.m b/GCDWebServer/Core/GCDWebServer.m index eaee5b5..df72547 100644 --- a/GCDWebServer/Core/GCDWebServer.m +++ b/GCDWebServer/Core/GCDWebServer.m @@ -367,7 +367,7 @@ static inline NSString* _EncodeBase64(NSString* string) { return ARC_AUTORELEASE([[NSString alloc] initWithData:[data base64EncodedDataWithOptions:0] encoding:NSASCIIStringEncoding]); } -- (BOOL)_start { +- (BOOL)_start:(NSError**)error { DCHECK(_source == NULL); NSUInteger port = [_GetOption(_options, GCDWebServerOption_Port, @0) unsignedIntegerValue]; NSString* name = _GetOption(_options, GCDWebServerOption_BonjourName, @""); @@ -473,8 +473,8 @@ static inline NSString* _EncodeBase64(NSString* string) { CFNetServiceClientContext context = {0, (ARC_BRIDGE void*)self, NULL, NULL, NULL}; CFNetServiceSetClient(_service, _NetServiceClientCallBack, &context); CFNetServiceScheduleWithRunLoop(_service, CFRunLoopGetMain(), kCFRunLoopCommonModes); - CFStreamError error = {0}; - CFNetServiceRegisterWithOptions(_service, 0, &error); + CFStreamError streamError = {0}; + CFNetServiceRegisterWithOptions(_service, 0, &streamError); } else { LOG_ERROR(@"Failed creating CFNetService"); } @@ -488,15 +488,24 @@ static inline NSString* _EncodeBase64(NSString* string) { }); } } else { - LOG_ERROR(@"Failed listening on socket: %s (%i)", strerror(errno), errno); + LOG_ERROR(@"Failed starting listening socket: %s (%i)", strerror(errno), errno); + if (error) { + *error = GCDWebServerMakePosixError(errno); + } close(listeningSocket); } } else { - LOG_ERROR(@"Failed binding socket: %s (%i)", strerror(errno), errno); + LOG_ERROR(@"Failed binding listening socket: %s (%i)", strerror(errno), errno); + if (error) { + *error = GCDWebServerMakePosixError(errno); + } close(listeningSocket); } } else { - LOG_ERROR(@"Failed creating socket: %s (%i)", strerror(errno), errno); + LOG_ERROR(@"Failed creating listening socket: %s (%i)", strerror(errno), errno); + if (error) { + *error = GCDWebServerMakePosixError(errno); + } } return (_source ? YES : NO); } @@ -548,20 +557,20 @@ static inline NSString* _EncodeBase64(NSString* string) { DCHECK([NSThread isMainThread]); LOG_DEBUG(@"Will enter foreground"); if (!_source) { - [self _start]; // TODO: There's probably nothing we can do on failure + [self _start:NULL]; // TODO: There's probably nothing we can do on failure } } #endif -- (BOOL)startWithOptions:(NSDictionary*)options { +- (BOOL)startWithOptions:(NSDictionary*)options error:(NSError**)error { if (_options == nil) { _options = [options copy]; #if TARGET_OS_IPHONE _suspendInBackground = [_GetOption(_options, GCDWebServerOption_AutomaticallySuspendInBackground, @YES) boolValue]; - if (((_suspendInBackground == NO) || ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground)) && ![self _start]) + if (((_suspendInBackground == NO) || ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground)) && ![self _start:error]) #else - if (![self _start]) + if (![self _start:error]) #endif { ARC_RELEASE(_options); @@ -643,7 +652,7 @@ static inline NSString* _EncodeBase64(NSString* string) { NSMutableDictionary* options = [NSMutableDictionary dictionary]; [options setObject:[NSNumber numberWithInteger:port] forKey:GCDWebServerOption_Port]; [options setValue:name forKey:GCDWebServerOption_BonjourName]; - return [self startWithOptions:options]; + return [self startWithOptions:options error:NULL]; } #if !TARGET_OS_IPHONE @@ -652,16 +661,16 @@ static inline NSString* _EncodeBase64(NSString* string) { NSMutableDictionary* options = [NSMutableDictionary dictionary]; [options setObject:[NSNumber numberWithInteger:port] forKey:GCDWebServerOption_Port]; [options setValue:name forKey:GCDWebServerOption_BonjourName]; - return [self runWithOptions:options]; + return [self runWithOptions:options error:NULL]; } -- (BOOL)runWithOptions:(NSDictionary*)options { +- (BOOL)runWithOptions:(NSDictionary*)options error:(NSError**)error { DCHECK([NSThread isMainThread]); BOOL success = NO; _run = YES; void (*handler)(int) = signal(SIGINT, _SignalHandler); if (handler != SIG_ERR) { - if ([self startWithOptions:options]) { + if ([self startWithOptions:options error:error]) { while (_run) { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, true); } @@ -957,7 +966,7 @@ static void _LogResult(NSString* format, ...) { - (NSInteger)runTestsWithOptions:(NSDictionary*)options inDirectory:(NSString*)path { NSArray* ignoredHeaders = @[@"Date", @"Etag"]; // Dates are always different by definition and ETags depend on file system node IDs NSInteger result = -1; - if ([self startWithOptions:options]) { + if ([self startWithOptions:options error:NULL]) { result = 0; NSArray* files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL]; diff --git a/GCDWebServer/Core/GCDWebServerPrivate.h b/GCDWebServer/Core/GCDWebServerPrivate.h index ce9d86d..b8adbaa 100644 --- a/GCDWebServer/Core/GCDWebServerPrivate.h +++ b/GCDWebServer/Core/GCDWebServerPrivate.h @@ -114,6 +114,10 @@ static inline BOOL GCDWebServerIsValidByteRange(NSRange range) { return ((range.location != NSNotFound) || (range.length > 0)); } +static inline NSError* GCDWebServerMakePosixError(int code) { + return [NSError errorWithDomain:NSPOSIXErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithUTF8String:strerror(code)]}]; +} + extern void GCDWebServerInitializeFunctions(); extern NSString* GCDWebServerNormalizeHeaderValue(NSString* value); extern NSString* GCDWebServerTruncateHeaderValue(NSString* value); diff --git a/GCDWebServer/Requests/GCDWebServerFileRequest.m b/GCDWebServer/Requests/GCDWebServerFileRequest.m index c7ab46f..1b4484a 100644 --- a/GCDWebServer/Requests/GCDWebServerFileRequest.m +++ b/GCDWebServer/Requests/GCDWebServerFileRequest.m @@ -34,10 +34,6 @@ } @end -static inline NSError* _MakePosixError(int code) { - return [NSError errorWithDomain:NSPOSIXErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"%s", strerror(code)]}]; -} - @implementation GCDWebServerFileRequest @synthesize temporaryPath=_temporaryPath; @@ -59,7 +55,7 @@ static inline NSError* _MakePosixError(int code) { - (BOOL)open:(NSError**)error { _file = open([_temporaryPath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (_file <= 0) { - *error = _MakePosixError(errno); + *error = GCDWebServerMakePosixError(errno); return NO; } return YES; @@ -67,7 +63,7 @@ static inline NSError* _MakePosixError(int code) { - (BOOL)writeData:(NSData*)data error:(NSError**)error { if (write(_file, data.bytes, data.length) != (ssize_t)data.length) { - *error = _MakePosixError(errno); + *error = GCDWebServerMakePosixError(errno); return NO; } return YES; @@ -75,7 +71,7 @@ static inline NSError* _MakePosixError(int code) { - (BOOL)close:(NSError**)error { if (close(_file) < 0) { - *error = _MakePosixError(errno); + *error = GCDWebServerMakePosixError(errno); return NO; } #ifdef __GCDWEBSERVER_ENABLE_TESTING__ diff --git a/GCDWebServer/Responses/GCDWebServerFileResponse.m b/GCDWebServer/Responses/GCDWebServerFileResponse.m index cf85ac4..423d8b2 100644 --- a/GCDWebServer/Responses/GCDWebServerFileResponse.m +++ b/GCDWebServer/Responses/GCDWebServerFileResponse.m @@ -40,10 +40,6 @@ } @end -static inline NSError* _MakePosixError(int code) { - return [NSError errorWithDomain:NSPOSIXErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"%s", strerror(code)]}]; -} - @implementation GCDWebServerFileResponse + (instancetype)responseWithFile:(NSString*)path { @@ -142,11 +138,11 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) { - (BOOL)open:(NSError**)error { _file = open([_path fileSystemRepresentation], O_NOFOLLOW | O_RDONLY); if (_file <= 0) { - *error = _MakePosixError(errno); + *error = GCDWebServerMakePosixError(errno); return NO; } if (lseek(_file, _offset, SEEK_SET) != (off_t)_offset) { - *error = _MakePosixError(errno); + *error = GCDWebServerMakePosixError(errno); close(_file); return NO; } @@ -158,7 +154,7 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) { NSMutableData* data = [[NSMutableData alloc] initWithLength:length]; ssize_t result = read(_file, data.mutableBytes, length); if (result < 0) { - *error = _MakePosixError(errno); + *error = GCDWebServerMakePosixError(errno); return nil; } if (result > 0) { diff --git a/Mac/main.m b/Mac/main.m index 4af3a78..c8a7624 100644 --- a/Mac/main.m +++ b/Mac/main.m @@ -359,7 +359,7 @@ int main(int argc, const char* argv[]) { [options setObject:GCDWebServerAuthenticationMethod_DigestAccess forKey:GCDWebServerOption_AuthenticationMethod]; } } - if ([webServer runWithOptions:options]) { + if ([webServer runWithOptions:options error:NULL]) { result = 0; } }