Эх сурвалжийг харах

#46 Added "error" argument to -startWithOptions:

Pierre-Olivier Latour 11 жил өмнө
parent
commit
d404112a88

+ 4 - 4
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
 

+ 24 - 15
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];

+ 4 - 0
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);

+ 3 - 7
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__

+ 3 - 7
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) {

+ 1 - 1
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;
         }
       }