#46 Added "error" argument to -startWithOptions:

This commit is contained in:
Pierre-Olivier Latour 2014-04-27 19:19:55 -07:00
parent dd3f539f74
commit d404112a88
6 changed files with 39 additions and 34 deletions

View File

@ -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

View File

@ -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];

View File

@ -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);

View File

@ -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__

View File

@ -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) {

View File

@ -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;
}
}