Use clang-formatter to format source code

This commit is contained in:
Pierre-Olivier Latour
2016-12-27 11:02:19 +09:00
parent 0c51a9b071
commit 83f1c062b5
22 changed files with 849 additions and 711 deletions
+13
View File
@@ -0,0 +1,13 @@
---
Language: Cpp
BasedOnStyle: Google
Standard: Cpp11
ColumnLimit: 0
AlignTrailingComments: false
NamespaceIndentation: All
DerivePointerAlignment: false
AlwaysBreakBeforeMultilineStrings: false
AccessModifierOffset: -2
ObjCSpaceBeforeProtocolList: true
SortIncludes: false
...
+52 -33
View File
@@ -233,7 +233,7 @@ static inline BOOL _IsMacFinder(GCDWebServerRequest* request) {
NSString* creationDateHeader = [request.headers objectForKey:@"X-GCDWebServer-CreationDate"]; NSString* creationDateHeader = [request.headers objectForKey:@"X-GCDWebServer-CreationDate"];
if (creationDateHeader) { if (creationDateHeader) {
NSDate* date = GCDWebServerParseISO8601(creationDateHeader); NSDate* date = GCDWebServerParseISO8601(creationDateHeader);
if (!date || ![[NSFileManager defaultManager] setAttributes:@{NSFileCreationDate: date} ofItemAtPath:absolutePath error:&error]) { if (!date || ![[NSFileManager defaultManager] setAttributes:@{ NSFileCreationDate : date } ofItemAtPath:absolutePath error:&error]) {
return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed setting creation date for directory \"%@\"", relativePath]; return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed setting creation date for directory \"%@\"", relativePath];
} }
} }
@@ -611,7 +611,7 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
@implementation GCDWebDAVServer @implementation GCDWebDAVServer
@synthesize uploadDirectory=_uploadDirectory, allowedFileExtensions=_allowedExtensions, allowHiddenItems=_allowHidden; @synthesize uploadDirectory = _uploadDirectory, allowedFileExtensions = _allowedExtensions, allowHiddenItems = _allowHidden;
@dynamic delegate; @dynamic delegate;
@@ -621,55 +621,74 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
GCDWebDAVServer* __unsafe_unretained server = self; GCDWebDAVServer* __unsafe_unretained server = self;
// 9.1 PROPFIND method // 9.1 PROPFIND method
[self addDefaultHandlerForMethod:@"PROPFIND" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"PROPFIND"
return [server performPROPFIND:(GCDWebServerDataRequest*)request]; requestClass:[GCDWebServerDataRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performPROPFIND:(GCDWebServerDataRequest*)request];
}];
// 9.3 MKCOL Method // 9.3 MKCOL Method
[self addDefaultHandlerForMethod:@"MKCOL" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"MKCOL"
return [server performMKCOL:(GCDWebServerDataRequest*)request]; requestClass:[GCDWebServerDataRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performMKCOL:(GCDWebServerDataRequest*)request];
}];
// 9.4 GET & HEAD methods // 9.4 GET & HEAD methods
[self addDefaultHandlerForMethod:@"GET" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"GET"
return [server performGET:request]; requestClass:[GCDWebServerRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performGET:request];
}];
// 9.6 DELETE method // 9.6 DELETE method
[self addDefaultHandlerForMethod:@"DELETE" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"DELETE"
return [server performDELETE:request]; requestClass:[GCDWebServerRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performDELETE:request];
}];
// 9.7 PUT method // 9.7 PUT method
[self addDefaultHandlerForMethod:@"PUT" requestClass:[GCDWebServerFileRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"PUT"
return [server performPUT:(GCDWebServerFileRequest*)request]; requestClass:[GCDWebServerFileRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performPUT:(GCDWebServerFileRequest*)request];
}];
// 9.8 COPY method // 9.8 COPY method
[self addDefaultHandlerForMethod:@"COPY" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"COPY"
return [server performCOPY:request isMove:NO]; requestClass:[GCDWebServerRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performCOPY:request isMove:NO];
}];
// 9.9 MOVE method // 9.9 MOVE method
[self addDefaultHandlerForMethod:@"MOVE" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"MOVE"
return [server performCOPY:request isMove:YES]; requestClass:[GCDWebServerRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performCOPY:request isMove:YES];
}];
// 9.10 LOCK method // 9.10 LOCK method
[self addDefaultHandlerForMethod:@"LOCK" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"LOCK"
return [server performLOCK:(GCDWebServerDataRequest*)request]; requestClass:[GCDWebServerDataRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performLOCK:(GCDWebServerDataRequest*)request];
}];
// 9.11 UNLOCK method // 9.11 UNLOCK method
[self addDefaultHandlerForMethod:@"UNLOCK" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"UNLOCK"
return [server performUNLOCK:request]; requestClass:[GCDWebServerRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performUNLOCK:request];
}];
// 10.1 OPTIONS method / DAV Header // 10.1 OPTIONS method / DAV Header
[self addDefaultHandlerForMethod:@"OPTIONS" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"OPTIONS"
return [server performOPTIONS:request]; requestClass:[GCDWebServerRequest class]
}]; processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server performOPTIONS:request];
}];
} }
return self; return self;
} }
+4 -4
View File
@@ -575,22 +575,22 @@ extern NSString* const GCDWebServerAuthenticationMethod_DigestAccess;
/** /**
* Logs a message to the logging facility at the VERBOSE level. * Logs a message to the logging facility at the VERBOSE level.
*/ */
- (void)logVerbose:(NSString*)format, ... NS_FORMAT_FUNCTION(1,2); - (void)logVerbose:(NSString*)format, ... NS_FORMAT_FUNCTION(1, 2);
/** /**
* Logs a message to the logging facility at the INFO level. * Logs a message to the logging facility at the INFO level.
*/ */
- (void)logInfo:(NSString*)format, ... NS_FORMAT_FUNCTION(1,2); - (void)logInfo:(NSString*)format, ... NS_FORMAT_FUNCTION(1, 2);
/** /**
* Logs a message to the logging facility at the WARNING level. * Logs a message to the logging facility at the WARNING level.
*/ */
- (void)logWarning:(NSString*)format, ... NS_FORMAT_FUNCTION(1,2); - (void)logWarning:(NSString*)format, ... NS_FORMAT_FUNCTION(1, 2);
/** /**
* Logs a message to the logging facility at the ERROR level. * Logs a message to the logging facility at the ERROR level.
*/ */
- (void)logError:(NSString*)format, ... NS_FORMAT_FUNCTION(1,2); - (void)logError:(NSString*)format, ... NS_FORMAT_FUNCTION(1, 2);
@end @end
+87 -68
View File
@@ -141,7 +141,7 @@ static void _ExecuteMainThreadRunLoopSources() {
@implementation GCDWebServerHandler @implementation GCDWebServerHandler
@synthesize matchBlock=_matchBlock, asyncProcessBlock=_asyncProcessBlock; @synthesize matchBlock = _matchBlock, asyncProcessBlock = _asyncProcessBlock;
- (id)initWithMatchBlock:(GCDWebServerMatchBlock)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock)processBlock { - (id)initWithMatchBlock:(GCDWebServerMatchBlock)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock)processBlock {
if ((self = [super init])) { if ((self = [super init])) {
@@ -195,9 +195,9 @@ static void _ExecuteMainThreadRunLoopSources() {
@implementation GCDWebServer @implementation GCDWebServer
@synthesize delegate=_delegate, handlers=_handlers, port=_port, serverName=_serverName, authenticationRealm=_authenticationRealm, @synthesize delegate = _delegate, handlers = _handlers, port = _port, serverName = _serverName, authenticationRealm = _authenticationRealm,
authenticationBasicAccounts=_authenticationBasicAccounts, authenticationDigestAccounts=_authenticationDigestAccounts, authenticationBasicAccounts = _authenticationBasicAccounts, authenticationDigestAccounts = _authenticationDigestAccounts,
shouldAutomaticallyMapHEADToGET=_mapHEADToGET, dispatchQueuePriority=_dispatchQueuePriority; shouldAutomaticallyMapHEADToGET = _mapHEADToGET, dispatchQueuePriority = _dispatchQueuePriority;
+ (void)initialize { + (void)initialize {
GCDWebServerInitializeFunctions(); GCDWebServerInitializeFunctions();
@@ -356,9 +356,10 @@ static void _ExecuteMainThreadRunLoopSources() {
} }
- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock { - (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock {
[self addHandlerWithMatchBlock:matchBlock asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { [self addHandlerWithMatchBlock:matchBlock
completionBlock(processBlock(request)); asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
}]; completionBlock(processBlock(request));
}];
} }
- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock)processBlock { - (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock)processBlock {
@@ -896,31 +897,37 @@ static inline NSString* _EncodeBase64(NSString* string) {
@implementation GCDWebServer (Handlers) @implementation GCDWebServer (Handlers)
- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block { - (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
[self addDefaultHandlerForMethod:method requestClass:aClass asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { [self addDefaultHandlerForMethod:method
completionBlock(block(request)); requestClass:aClass
}]; asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
completionBlock(block(request));
}];
} }
- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block { - (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block {
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { [self addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
if (![requestMethod isEqualToString:method]) { if (![requestMethod isEqualToString:method]) {
return nil; return nil;
} }
return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]; return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
} asyncProcessBlock:block]; }
asyncProcessBlock:block];
} }
- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block { - (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
[self addHandlerForMethod:method path:path requestClass:aClass asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { [self addHandlerForMethod:method
completionBlock(block(request)); path:path
}]; requestClass:aClass
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
completionBlock(block(request));
}];
} }
- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block { - (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block {
if ([path hasPrefix:@"/"] && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) { if ([path hasPrefix:@"/"] && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) {
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { [self addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
if (![requestMethod isEqualToString:method]) { if (![requestMethod isEqualToString:method]) {
return nil; return nil;
@@ -930,22 +937,26 @@ static inline NSString* _EncodeBase64(NSString* string) {
} }
return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]; return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
} asyncProcessBlock:block]; }
asyncProcessBlock:block];
} else { } else {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
} }
} }
- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block { - (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
[self addHandlerForMethod:method pathRegex:regex requestClass:aClass asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { [self addHandlerForMethod:method
completionBlock(block(request)); pathRegex:regex
}]; requestClass:aClass
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
completionBlock(block(request));
}];
} }
- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block { - (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block {
NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:regex options:NSRegularExpressionCaseInsensitive error:NULL]; NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:regex options:NSRegularExpressionCaseInsensitive error:NULL];
if (expression && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) { if (expression && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) {
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { [self addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
if (![requestMethod isEqualToString:method]) { if (![requestMethod isEqualToString:method]) {
return nil; return nil;
@@ -973,7 +984,8 @@ static inline NSString* _EncodeBase64(NSString* string) {
[request setAttribute:captures forKey:GCDWebServerRequestAttribute_RegexCaptures]; [request setAttribute:captures forKey:GCDWebServerRequestAttribute_RegexCaptures];
return request; return request;
} asyncProcessBlock:block]; }
asyncProcessBlock:block];
} else { } else {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
} }
@@ -984,29 +996,35 @@ static inline NSString* _EncodeBase64(NSString* string) {
@implementation GCDWebServer (GETHandlers) @implementation GCDWebServer (GETHandlers)
- (void)addGETHandlerForPath:(NSString*)path staticData:(NSData*)staticData contentType:(NSString*)contentType cacheAge:(NSUInteger)cacheAge { - (void)addGETHandlerForPath:(NSString*)path staticData:(NSData*)staticData contentType:(NSString*)contentType cacheAge:(NSUInteger)cacheAge {
[self addHandlerForMethod:@"GET" path:path requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"GET"
path:path
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
GCDWebServerResponse* response = [GCDWebServerDataResponse responseWithData:staticData contentType:contentType]; GCDWebServerResponse* response = [GCDWebServerDataResponse responseWithData:staticData contentType:contentType];
response.cacheControlMaxAge = cacheAge; response.cacheControlMaxAge = cacheAge;
return response; return response;
}]; }];
} }
- (void)addGETHandlerForPath:(NSString*)path filePath:(NSString*)filePath isAttachment:(BOOL)isAttachment cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests { - (void)addGETHandlerForPath:(NSString*)path filePath:(NSString*)filePath isAttachment:(BOOL)isAttachment cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests {
[self addHandlerForMethod:@"GET" path:path requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"GET"
path:path
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
GCDWebServerResponse* response = nil; GCDWebServerResponse* response = nil;
if (allowRangeRequests) { if (allowRangeRequests) {
response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange isAttachment:isAttachment]; response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange isAttachment:isAttachment];
[response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"]; [response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
} else { } else {
response = [GCDWebServerFileResponse responseWithFile:filePath isAttachment:isAttachment]; response = [GCDWebServerFileResponse responseWithFile:filePath isAttachment:isAttachment];
} }
response.cacheControlMaxAge = cacheAge; response.cacheControlMaxAge = cacheAge;
return response; return response;
}]; }];
} }
- (GCDWebServerResponse*)_responseWithContentsOfDirectory:(NSString*)path { - (GCDWebServerResponse*)_responseWithContentsOfDirectory:(NSString*)path {
@@ -1042,7 +1060,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
- (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)directoryPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests { - (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)directoryPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests {
if ([basePath hasPrefix:@"/"] && [basePath hasSuffix:@"/"]) { if ([basePath hasPrefix:@"/"] && [basePath hasSuffix:@"/"]) {
GCDWebServer* __unsafe_unretained server = self; GCDWebServer* __unsafe_unretained server = self;
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { [self addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
if (![requestMethod isEqualToString:@"GET"]) { if (![requestMethod isEqualToString:@"GET"]) {
return nil; return nil;
@@ -1052,38 +1070,39 @@ static inline NSString* _EncodeBase64(NSString* string) {
} }
return [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]; return [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
} processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { }
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
GCDWebServerResponse* response = nil; GCDWebServerResponse* response = nil;
NSString* filePath = [directoryPath stringByAppendingPathComponent:[request.path substringFromIndex:basePath.length]]; NSString* filePath = [directoryPath stringByAppendingPathComponent:[request.path substringFromIndex:basePath.length]];
NSString* fileType = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL] fileType]; NSString* fileType = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL] fileType];
if (fileType) { if (fileType) {
if ([fileType isEqualToString:NSFileTypeDirectory]) { if ([fileType isEqualToString:NSFileTypeDirectory]) {
if (indexFilename) { if (indexFilename) {
NSString* indexPath = [filePath stringByAppendingPathComponent:indexFilename]; NSString* indexPath = [filePath stringByAppendingPathComponent:indexFilename];
NSString* indexType = [[[NSFileManager defaultManager] attributesOfItemAtPath:indexPath error:NULL] fileType]; NSString* indexType = [[[NSFileManager defaultManager] attributesOfItemAtPath:indexPath error:NULL] fileType];
if ([indexType isEqualToString:NSFileTypeRegular]) { if ([indexType isEqualToString:NSFileTypeRegular]) {
return [GCDWebServerFileResponse responseWithFile:indexPath]; return [GCDWebServerFileResponse responseWithFile:indexPath];
}
}
response = [server _responseWithContentsOfDirectory:filePath];
} else if ([fileType isEqualToString:NSFileTypeRegular]) {
if (allowRangeRequests) {
response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange];
[response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
} else {
response = [GCDWebServerFileResponse responseWithFile:filePath];
}
} }
} }
response = [server _responseWithContentsOfDirectory:filePath]; if (response) {
} else if ([fileType isEqualToString:NSFileTypeRegular]) { response.cacheControlMaxAge = cacheAge;
if (allowRangeRequests) {
response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange];
[response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
} else { } else {
response = [GCDWebServerFileResponse responseWithFile:filePath]; response = [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_NotFound];
} }
} return response;
}
if (response) {
response.cacheControlMaxAge = cacheAge;
} else {
response = [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_NotFound];
}
return response;
}]; }];
} else { } else {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
} }
@@ -1204,7 +1223,7 @@ static void _LogResult(NSString* format, ...) {
- (NSInteger)runTestsWithOptions:(NSDictionary*)options inDirectory:(NSString*)path { - (NSInteger)runTestsWithOptions:(NSDictionary*)options inDirectory:(NSString*)path {
GWS_DCHECK([NSThread isMainThread]); GWS_DCHECK([NSThread isMainThread]);
NSArray* ignoredHeaders = @[@"Date", @"Etag"]; // Dates are always different by definition and ETags depend on file system node IDs NSArray* ignoredHeaders = @[ @"Date", @"Etag" ]; // Dates are always different by definition and ETags depend on file system node IDs
NSInteger result = -1; NSInteger result = -1;
if ([self startWithOptions:options error:NULL]) { if ([self startWithOptions:options error:NULL]) {
_ExecuteMainThreadRunLoopSources(); _ExecuteMainThreadRunLoopSources();
@@ -1230,7 +1249,7 @@ static void _LogResult(NSString* format, ...) {
if ([responseFile hasPrefix:prefix] && [responseFile hasSuffix:@".response"]) { if ([responseFile hasPrefix:prefix] && [responseFile hasSuffix:@".response"]) {
NSData* responseData = [NSData dataWithContentsOfFile:[path stringByAppendingPathComponent:responseFile]]; NSData* responseData = [NSData dataWithContentsOfFile:[path stringByAppendingPathComponent:responseFile]];
if (responseData) { if (responseData) {
CFHTTPMessageRef expectedResponse = _CreateHTTPMessageFromData(responseData, NO); CFHTTPMessageRef expectedResponse = _CreateHTTPMessageFromData(responseData, NO);
if (expectedResponse) { if (expectedResponse) {
CFHTTPMessageRef actualResponse = _CreateHTTPMessageFromPerformingRequest(requestData, self.port); CFHTTPMessageRef actualResponse = _CreateHTTPMessageFromPerformingRequest(requestData, self.port);
if (actualResponse) { if (actualResponse) {
@@ -1281,7 +1300,7 @@ static void _LogResult(NSString* format, ...) {
if ([expectedBody writeToFile:expectedPath atomically:YES] && [actualBody writeToFile:actualPath atomically:YES]) { if ([expectedBody writeToFile:expectedPath atomically:YES] && [actualBody writeToFile:actualPath atomically:YES]) {
NSTask* task = [[NSTask alloc] init]; NSTask* task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/opendiff"]; [task setLaunchPath:@"/usr/bin/opendiff"];
[task setArguments:@[expectedPath, actualPath]]; [task setArguments:@[ expectedPath, actualPath ]];
[task launch]; [task launch];
} }
} }
+150 -138
View File
@@ -120,62 +120,66 @@ static int32_t _connectionCounter = 0;
- (void)_readHeaders:(NSMutableData*)headersData withCompletionBlock:(ReadHeadersCompletionBlock)block { - (void)_readHeaders:(NSMutableData*)headersData withCompletionBlock:(ReadHeadersCompletionBlock)block {
GWS_DCHECK(_requestMessage); GWS_DCHECK(_requestMessage);
[self _readData:headersData withLength:NSUIntegerMax completionBlock:^(BOOL success) { [self _readData:headersData
withLength:NSUIntegerMax
completionBlock:^(BOOL success) {
if (success) { if (success) {
NSRange range = [headersData rangeOfData:_CRLFCRLFData options:0 range:NSMakeRange(0, headersData.length)]; NSRange range = [headersData rangeOfData:_CRLFCRLFData options:0 range:NSMakeRange(0, headersData.length)];
if (range.location == NSNotFound) { if (range.location == NSNotFound) {
[self _readHeaders:headersData withCompletionBlock:block]; [self _readHeaders:headersData withCompletionBlock:block];
} else {
NSUInteger length = range.location + range.length;
if (CFHTTPMessageAppendBytes(_requestMessage, headersData.bytes, length)) {
if (CFHTTPMessageIsHeaderComplete(_requestMessage)) {
block([headersData subdataWithRange:NSMakeRange(length, headersData.length - length)]);
} else { } else {
GWS_LOG_ERROR(@"Failed parsing request headers from socket %i", _socket); NSUInteger length = range.location + range.length;
block(nil); if (CFHTTPMessageAppendBytes(_requestMessage, headersData.bytes, length)) {
if (CFHTTPMessageIsHeaderComplete(_requestMessage)) {
block([headersData subdataWithRange:NSMakeRange(length, headersData.length - length)]);
} else {
GWS_LOG_ERROR(@"Failed parsing request headers from socket %i", _socket);
block(nil);
}
} else {
GWS_LOG_ERROR(@"Failed appending request headers data from socket %i", _socket);
block(nil);
}
} }
} else { } else {
GWS_LOG_ERROR(@"Failed appending request headers data from socket %i", _socket);
block(nil); block(nil);
} }
}
} else {
block(nil);
}
}]; }];
} }
- (void)_readBodyWithRemainingLength:(NSUInteger)length completionBlock:(ReadBodyCompletionBlock)block { - (void)_readBodyWithRemainingLength:(NSUInteger)length completionBlock:(ReadBodyCompletionBlock)block {
GWS_DCHECK([_request hasBody] && ![_request usesChunkedTransferEncoding]); GWS_DCHECK([_request hasBody] && ![_request usesChunkedTransferEncoding]);
NSMutableData* bodyData = [[NSMutableData alloc] initWithCapacity:kBodyReadCapacity]; NSMutableData* bodyData = [[NSMutableData alloc] initWithCapacity:kBodyReadCapacity];
[self _readData:bodyData withLength:length completionBlock:^(BOOL success) { [self _readData:bodyData
withLength:length
completionBlock:^(BOOL success) {
if (success) { if (success) {
if (bodyData.length <= length) { if (bodyData.length <= length) {
NSError* error = nil; NSError* error = nil;
if ([_request performWriteData:bodyData error:&error]) { if ([_request performWriteData:bodyData error:&error]) {
NSUInteger remainingLength = length - bodyData.length; NSUInteger remainingLength = length - bodyData.length;
if (remainingLength) { if (remainingLength) {
[self _readBodyWithRemainingLength:remainingLength completionBlock:block]; [self _readBodyWithRemainingLength:remainingLength completionBlock:block];
} else {
block(YES);
}
} else {
GWS_LOG_ERROR(@"Failed writing request body on socket %i: %@", _socket, error);
block(NO);
}
} else { } else {
block(YES); GWS_LOG_ERROR(@"Unexpected extra content reading request body on socket %i", _socket);
block(NO);
GWS_DNOT_REACHED();
} }
} else { } else {
GWS_LOG_ERROR(@"Failed writing request body on socket %i: %@", _socket, error);
block(NO); block(NO);
} }
} else {
GWS_LOG_ERROR(@"Unexpected extra content reading request body on socket %i", _socket);
block(NO);
GWS_DNOT_REACHED();
}
} else {
block(NO);
}
}]; }];
} }
static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) { static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
@@ -231,15 +235,17 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
} }
[self _readData:chunkData withLength:NSUIntegerMax completionBlock:^(BOOL success) { [self _readData:chunkData
withLength:NSUIntegerMax
completionBlock:^(BOOL success) {
if (success) { if (success) {
[self _readNextBodyChunk:chunkData completionBlock:block]; [self _readNextBodyChunk:chunkData completionBlock:block];
} else { } else {
block(NO); block(NO);
} }
}]; }];
} }
@end @end
@@ -302,22 +308,24 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
*ptr = '\n'; *ptr = '\n';
data = chunk; data = chunk;
} }
[self _writeData:data withCompletionBlock:^(BOOL success) { [self _writeData:data
withCompletionBlock:^(BOOL success) {
if (success) { if (success) {
[self _writeBodyWithCompletionBlock:block]; [self _writeBodyWithCompletionBlock:block];
} else { } else {
block(NO); block(NO);
} }
}]; }];
} else { } else {
if (_response.usesChunkedTransferEncoding) { if (_response.usesChunkedTransferEncoding) {
[self _writeData:_lastChunkData withCompletionBlock:^(BOOL success) { [self _writeData:_lastChunkData
withCompletionBlock:^(BOOL success) {
block(success); block(success);
}]; }];
} else { } else {
block(YES); block(YES);
} }
@@ -334,7 +342,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
@implementation GCDWebServerConnection @implementation GCDWebServerConnection
@synthesize server=_server, localAddressData=_localAddress, remoteAddressData=_remoteAddress, totalBytesRead=_bytesRead, totalBytesWritten=_bytesWritten; @synthesize server = _server, localAddressData = _localAddress, remoteAddressData = _remoteAddress, totalBytesRead = _bytesRead, totalBytesWritten = _bytesWritten;
+ (void)initialize { + (void)initialize {
if (_CRLFData == nil) { if (_CRLFData == nil) {
@@ -381,9 +389,10 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
if (preflightResponse) { if (preflightResponse) {
[self _finishProcessingRequest:preflightResponse]; [self _finishProcessingRequest:preflightResponse];
} else { } else {
[self processRequest:_request completion:^(GCDWebServerResponse* processResponse) { [self processRequest:_request
[self _finishProcessingRequest:processResponse]; completion:^(GCDWebServerResponse* processResponse) {
}]; [self _finishProcessingRequest:processResponse];
}];
} }
} }
@@ -453,7 +462,6 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} else { } else {
[self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError];
} }
} }
- (void)_readBodyWithLength:(NSUInteger)length initialData:(NSData*)initialData { - (void)_readBodyWithLength:(NSUInteger)length initialData:(NSData*)initialData {
@@ -477,17 +485,18 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
if (length) { if (length) {
[self _readBodyWithRemainingLength:length completionBlock:^(BOOL success) { [self _readBodyWithRemainingLength:length
completionBlock:^(BOOL success) {
NSError* localError = nil; NSError* localError = nil;
if ([_request performClose:&localError]) { if ([_request performClose:&localError]) {
[self _startProcessingRequest]; [self _startProcessingRequest];
} else { } else {
GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error); GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error);
[self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError];
} }
}]; }];
} else { } else {
if ([_request performClose:&error]) { if ([_request performClose:&error]) {
[self _startProcessingRequest]; [self _startProcessingRequest];
@@ -507,98 +516,101 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
NSMutableData* chunkData = [[NSMutableData alloc] initWithData:initialData]; NSMutableData* chunkData = [[NSMutableData alloc] initWithData:initialData];
[self _readNextBodyChunk:chunkData completionBlock:^(BOOL success) { [self _readNextBodyChunk:chunkData
completionBlock:^(BOOL success) {
NSError* localError = nil; NSError* localError = nil;
if ([_request performClose:&localError]) { if ([_request performClose:&localError]) {
[self _startProcessingRequest]; [self _startProcessingRequest];
} else { } else {
GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error); GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error);
[self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError];
} }
}]; }];
} }
- (void)_readRequestHeaders { - (void)_readRequestHeaders {
_requestMessage = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, true); _requestMessage = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, true);
NSMutableData* headersData = [[NSMutableData alloc] initWithCapacity:kHeadersReadCapacity]; NSMutableData* headersData = [[NSMutableData alloc] initWithCapacity:kHeadersReadCapacity];
[self _readHeaders:headersData withCompletionBlock:^(NSData* extraData) { [self _readHeaders:headersData
withCompletionBlock:^(NSData* extraData) {
if (extraData) { if (extraData) {
NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(_requestMessage)); // Method verbs are case-sensitive and uppercase NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(_requestMessage)); // Method verbs are case-sensitive and uppercase
if (_server.shouldAutomaticallyMapHEADToGET && [requestMethod isEqualToString:@"HEAD"]) { if (_server.shouldAutomaticallyMapHEADToGET && [requestMethod isEqualToString:@"HEAD"]) {
requestMethod = @"GET"; requestMethod = @"GET";
_virtualHEAD = YES; _virtualHEAD = YES;
}
NSDictionary* requestHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones
NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(_requestMessage));
if (requestURL) {
requestURL = [self rewriteRequestURL:requestURL withMethod:requestMethod headers:requestHeaders];
GWS_DCHECK(requestURL);
}
NSString* requestPath = requestURL ? GCDWebServerUnescapeURLString(CFBridgingRelease(CFURLCopyPath((CFURLRef)requestURL))) : nil; // Don't use -[NSURL path] which strips the ending slash
NSString* queryString = requestURL ? CFBridgingRelease(CFURLCopyQueryString((CFURLRef)requestURL, NULL)) : nil; // Don't use -[NSURL query] to make sure query is not unescaped;
NSDictionary* requestQuery = queryString ? GCDWebServerParseURLEncodedForm(queryString) : @{};
if (requestMethod && requestURL && requestHeaders && requestPath && requestQuery) {
for (_handler in _server.handlers) {
_request = _handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery);
if (_request) {
break;
} }
} NSDictionary* requestHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones
if (_request) { NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(_requestMessage));
_request.localAddressData = self.localAddressData; if (requestURL) {
_request.remoteAddressData = self.remoteAddressData; requestURL = [self rewriteRequestURL:requestURL withMethod:requestMethod headers:requestHeaders];
if ([_request hasBody]) { GWS_DCHECK(requestURL);
[_request prepareForWriting]; }
if (_request.usesChunkedTransferEncoding || (extraData.length <= _request.contentLength)) { NSString* requestPath = requestURL ? GCDWebServerUnescapeURLString(CFBridgingRelease(CFURLCopyPath((CFURLRef)requestURL))) : nil; // Don't use -[NSURL path] which strips the ending slash
NSString* expectHeader = [requestHeaders objectForKey:@"Expect"]; NSString* queryString = requestURL ? CFBridgingRelease(CFURLCopyQueryString((CFURLRef)requestURL, NULL)) : nil; // Don't use -[NSURL query] to make sure query is not unescaped;
if (expectHeader) { NSDictionary* requestQuery = queryString ? GCDWebServerParseURLEncodedForm(queryString) : @{};
if ([expectHeader caseInsensitiveCompare:@"100-continue"] == NSOrderedSame) { // TODO: Actually validate request before continuing if (requestMethod && requestURL && requestHeaders && requestPath && requestQuery) {
[self _writeData:_continueData withCompletionBlock:^(BOOL success) { for (_handler in _server.handlers) {
_request = _handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery);
if (_request) {
break;
}
}
if (_request) {
_request.localAddressData = self.localAddressData;
_request.remoteAddressData = self.remoteAddressData;
if ([_request hasBody]) {
[_request prepareForWriting];
if (_request.usesChunkedTransferEncoding || (extraData.length <= _request.contentLength)) {
NSString* expectHeader = [requestHeaders objectForKey:@"Expect"];
if (expectHeader) {
if ([expectHeader caseInsensitiveCompare:@"100-continue"] == NSOrderedSame) { // TODO: Actually validate request before continuing
[self _writeData:_continueData
withCompletionBlock:^(BOOL success) {
if (success) { if (success) {
if (_request.usesChunkedTransferEncoding) { if (_request.usesChunkedTransferEncoding) {
[self _readChunkedBodyWithInitialData:extraData]; [self _readChunkedBodyWithInitialData:extraData];
} else { } else {
[self _readBodyWithLength:_request.contentLength initialData:extraData]; [self _readBodyWithLength:_request.contentLength initialData:extraData];
} }
}
}];
} else {
GWS_LOG_ERROR(@"Unsupported 'Expect' / 'Content-Length' header combination on socket %i", _socket);
[self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_ExpectationFailed];
} }
} else {
}]; if (_request.usesChunkedTransferEncoding) {
[self _readChunkedBodyWithInitialData:extraData];
} else {
[self _readBodyWithLength:_request.contentLength initialData:extraData];
}
}
} else { } else {
GWS_LOG_ERROR(@"Unsupported 'Expect' / 'Content-Length' header combination on socket %i", _socket); GWS_LOG_ERROR(@"Unexpected 'Content-Length' header value on socket %i", _socket);
[self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_ExpectationFailed]; [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_BadRequest];
} }
} else { } else {
if (_request.usesChunkedTransferEncoding) { [self _startProcessingRequest];
[self _readChunkedBodyWithInitialData:extraData];
} else {
[self _readBodyWithLength:_request.contentLength initialData:extraData];
}
} }
} else { } else {
GWS_LOG_ERROR(@"Unexpected 'Content-Length' header value on socket %i", _socket); _request = [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:requestPath query:requestQuery];
[self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_BadRequest]; GWS_DCHECK(_request);
[self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_MethodNotAllowed];
} }
} else { } else {
[self _startProcessingRequest]; [self abortRequest:nil withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError];
GWS_DNOT_REACHED();
} }
} else { } else {
_request = [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:requestPath query:requestQuery]; [self abortRequest:nil withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError];
GWS_DCHECK(_request);
[self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_MethodNotAllowed];
} }
} else {
[self abortRequest:nil withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError];
GWS_DNOT_REACHED();
}
} else {
[self abortRequest:nil withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError];
}
}]; }];
} }
- (id)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket { - (id)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket {
+5 -5
View File
@@ -163,8 +163,8 @@ NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension) {
static NSDictionary* _overrides = nil; static NSDictionary* _overrides = nil;
if (_overrides == nil) { if (_overrides == nil) {
_overrides = [[NSDictionary alloc] initWithObjectsAndKeys: _overrides = [[NSDictionary alloc] initWithObjectsAndKeys:
@"text/css", @"css", @"text/css", @"css",
nil]; nil];
} }
NSString* mimeType = nil; NSString* mimeType = nil;
extension = [extension lowercaseString]; extension = [extension lowercaseString];
@@ -267,9 +267,9 @@ NSString* GCDWebServerGetPrimaryIPAddress(BOOL useIPv6) {
struct ifaddrs* list; struct ifaddrs* list;
if (getifaddrs(&list) >= 0) { if (getifaddrs(&list) >= 0) {
for (struct ifaddrs* ifap = list; ifap; ifap = ifap->ifa_next) { for (struct ifaddrs* ifap = list; ifap; ifap = ifap->ifa_next) {
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_TV #if TARGET_IPHONE_SIMULATOR || TARGET_OS_TV
// Assume en0 is Ethernet and en1 is WiFi since there is no way to use SystemConfiguration framework in iOS Simulator // Assume en0 is Ethernet and en1 is WiFi since there is no way to use SystemConfiguration framework in iOS Simulator
// Assumption holds for Apple TV running tvOS // Assumption holds for Apple TV running tvOS
if (strcmp(ifap->ifa_name, "en0") && strcmp(ifap->ifa_name, "en1")) if (strcmp(ifap->ifa_name, "en0") && strcmp(ifap->ifa_name, "en1"))
#else #else
if (strcmp(ifap->ifa_name, primaryInterface)) if (strcmp(ifap->ifa_name, primaryInterface))
+26 -11
View File
@@ -123,14 +123,29 @@ extern GCDWebServerLoggingLevel GCDWebServerLogLevel;
extern void GCDWebServerLogMessage(GCDWebServerLoggingLevel level, NSString* format, ...) NS_FORMAT_FUNCTION(2, 3); extern void GCDWebServerLogMessage(GCDWebServerLoggingLevel level, NSString* format, ...) NS_FORMAT_FUNCTION(2, 3);
#if DEBUG #if DEBUG
#define GWS_LOG_DEBUG(...) do { if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Debug) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Debug, __VA_ARGS__); } while (0) #define GWS_LOG_DEBUG(...) \
do { \
if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Debug) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Debug, __VA_ARGS__); \
} while (0)
#else #else
#define GWS_LOG_DEBUG(...) #define GWS_LOG_DEBUG(...)
#endif #endif
#define GWS_LOG_VERBOSE(...) do { if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Verbose) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Verbose, __VA_ARGS__); } while (0) #define GWS_LOG_VERBOSE(...) \
#define GWS_LOG_INFO(...) do { if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Info) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Info, __VA_ARGS__); } while (0) do { \
#define GWS_LOG_WARNING(...) do { if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Warning) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Warning, __VA_ARGS__); } while (0) if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Verbose) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Verbose, __VA_ARGS__); \
#define GWS_LOG_ERROR(...) do { if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Error) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Error, __VA_ARGS__); } while (0) } while (0)
#define GWS_LOG_INFO(...) \
do { \
if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Info) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Info, __VA_ARGS__); \
} while (0)
#define GWS_LOG_WARNING(...) \
do { \
if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Warning) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Warning, __VA_ARGS__); \
} while (0)
#define GWS_LOG_ERROR(...) \
do { \
if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Error) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Error, __VA_ARGS__); \
} while (0)
#endif #endif
@@ -143,10 +158,10 @@ extern void GCDWebServerLogMessage(GCDWebServerLoggingLevel level, NSString* for
#if DEBUG #if DEBUG
#define GWS_DCHECK(__CONDITION__) \ #define GWS_DCHECK(__CONDITION__) \
do { \ do { \
if (!(__CONDITION__)) { \ if (!(__CONDITION__)) { \
abort(); \ abort(); \
} \ } \
} while (0) } while (0)
#define GWS_DNOT_REACHED() abort() #define GWS_DNOT_REACHED() abort()
@@ -171,7 +186,7 @@ static inline BOOL GCDWebServerIsValidByteRange(NSRange range) {
} }
static inline NSError* GCDWebServerMakePosixError(int code) { static inline NSError* GCDWebServerMakePosixError(int code) {
return [NSError errorWithDomain:NSPOSIXErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithUTF8String:strerror(code)]}]; return [NSError errorWithDomain:NSPOSIXErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithUTF8String:strerror(code)]}];
} }
extern void GCDWebServerInitializeFunctions(); extern void GCDWebServerInitializeFunctions();
@@ -181,7 +196,7 @@ extern NSString* GCDWebServerExtractHeaderValueParameter(NSString* header, NSStr
extern NSStringEncoding GCDWebServerStringEncodingFromCharset(NSString* charset); extern NSStringEncoding GCDWebServerStringEncodingFromCharset(NSString* charset);
extern BOOL GCDWebServerIsTextContentType(NSString* type); extern BOOL GCDWebServerIsTextContentType(NSString* type);
extern NSString* GCDWebServerDescribeData(NSData* data, NSString* contentType); extern NSString* GCDWebServerDescribeData(NSData* data, NSString* contentType);
extern NSString* GCDWebServerComputeMD5Digest(NSString* format, ...) NS_FORMAT_FUNCTION(1,2); extern NSString* GCDWebServerComputeMD5Digest(NSString* format, ...) NS_FORMAT_FUNCTION(1, 2);
extern NSString* GCDWebServerStringFromSockAddr(const struct sockaddr* addr, BOOL includeService); extern NSString* GCDWebServerStringFromSockAddr(const struct sockaddr* addr, BOOL includeService);
@interface GCDWebServerConnection () @interface GCDWebServerConnection ()
+2 -2
View File
@@ -169,8 +169,8 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
@implementation GCDWebServerRequest : NSObject @implementation GCDWebServerRequest : NSObject
@synthesize method=_method, URL=_url, headers=_headers, path=_path, query=_query, contentType=_type, contentLength=_length, ifModifiedSince=_modifiedSince, ifNoneMatch=_noneMatch, @synthesize method = _method, URL = _url, headers = _headers, path = _path, query = _query, contentType = _type, contentLength = _length, ifModifiedSince = _modifiedSince, ifNoneMatch = _noneMatch,
byteRange=_range, acceptsGzipContentEncoding=_gzipAccepted, usesChunkedTransferEncoding=_chunked, localAddressData=_localAddress, remoteAddressData=_remoteAddress; byteRange = _range, acceptsGzipContentEncoding = _gzipAccepted, usesChunkedTransferEncoding = _chunked, localAddressData = _localAddress, remoteAddressData = _remoteAddress;
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query { - (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
if ((self = [super init])) { if ((self = [super init])) {
+2 -2
View File
@@ -177,8 +177,8 @@
@implementation GCDWebServerResponse @implementation GCDWebServerResponse
@synthesize contentType=_type, contentLength=_length, statusCode=_status, cacheControlMaxAge=_maxAge, lastModifiedDate=_lastModified, eTag=_eTag, @synthesize contentType = _type, contentLength = _length, statusCode = _status, cacheControlMaxAge = _maxAge, lastModifiedDate = _lastModified, eTag = _eTag,
gzipContentEncodingEnabled=_gzipped, additionalHeaders=_headers; gzipContentEncodingEnabled = _gzipped, additionalHeaders = _headers;
+ (instancetype)response { + (instancetype)response {
return [[[self class] alloc] init]; return [[[self class] alloc] init];
@@ -42,7 +42,7 @@
@implementation GCDWebServerDataRequest @implementation GCDWebServerDataRequest
@synthesize data=_data; @synthesize data = _data;
- (BOOL)open:(NSError**)error { - (BOOL)open:(NSError**)error {
if (self.contentLength != NSUIntegerMax) { if (self.contentLength != NSUIntegerMax) {
@@ -52,7 +52,7 @@
} }
if (_data == nil) { if (_data == nil) {
if (error) { if (error) {
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed allocating memory"}]; *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed allocating memory" }];
} }
return NO; return NO;
} }
@@ -40,7 +40,7 @@
@implementation GCDWebServerFileRequest @implementation GCDWebServerFileRequest
@synthesize temporaryPath=_temporaryPath; @synthesize temporaryPath = _temporaryPath;
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query { - (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) { if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) {
@@ -85,14 +85,14 @@
NSString* creationDateHeader = [self.headers objectForKey:@"X-GCDWebServer-CreationDate"]; NSString* creationDateHeader = [self.headers objectForKey:@"X-GCDWebServer-CreationDate"];
if (creationDateHeader) { if (creationDateHeader) {
NSDate* date = GCDWebServerParseISO8601(creationDateHeader); NSDate* date = GCDWebServerParseISO8601(creationDateHeader);
if (!date || ![[NSFileManager defaultManager] setAttributes:@{NSFileCreationDate: date} ofItemAtPath:_temporaryPath error:error]) { if (!date || ![[NSFileManager defaultManager] setAttributes:@{ NSFileCreationDate : date } ofItemAtPath:_temporaryPath error:error]) {
return NO; return NO;
} }
} }
NSString* modifiedDateHeader = [self.headers objectForKey:@"X-GCDWebServer-ModifiedDate"]; NSString* modifiedDateHeader = [self.headers objectForKey:@"X-GCDWebServer-ModifiedDate"];
if (modifiedDateHeader) { if (modifiedDateHeader) {
NSDate* date = GCDWebServerParseRFC822(modifiedDateHeader); NSDate* date = GCDWebServerParseRFC822(modifiedDateHeader);
if (!date || ![[NSFileManager defaultManager] setAttributes:@{NSFileModificationDate: date} ofItemAtPath:_temporaryPath error:error]) { if (!date || ![[NSFileManager defaultManager] setAttributes:@{ NSFileModificationDate : date } ofItemAtPath:_temporaryPath error:error]) {
return NO; return NO;
} }
} }
@@ -61,7 +61,7 @@ static NSData* _dashNewlineData = nil;
@implementation GCDWebServerMultiPart @implementation GCDWebServerMultiPart
@synthesize controlName=_controlName, contentType=_contentType, mimeType=_mimeType; @synthesize controlName = _controlName, contentType = _contentType, mimeType = _mimeType;
- (id)initWithControlName:(NSString*)name contentType:(NSString*)type { - (id)initWithControlName:(NSString*)name contentType:(NSString*)type {
if ((self = [super init])) { if ((self = [super init])) {
@@ -83,7 +83,7 @@ static NSData* _dashNewlineData = nil;
@implementation GCDWebServerMultiPartArgument @implementation GCDWebServerMultiPartArgument
@synthesize data=_data, string=_string; @synthesize data = _data, string = _string;
- (id)initWithControlName:(NSString*)name contentType:(NSString*)type data:(NSData*)data { - (id)initWithControlName:(NSString*)name contentType:(NSString*)type data:(NSData*)data {
if ((self = [super initWithControlName:name contentType:type])) { if ((self = [super initWithControlName:name contentType:type])) {
@@ -112,7 +112,7 @@ static NSData* _dashNewlineData = nil;
@implementation GCDWebServerMultiPartFile @implementation GCDWebServerMultiPartFile
@synthesize fileName=_fileName, temporaryPath=_temporaryPath; @synthesize fileName = _fileName, temporaryPath = _temporaryPath;
- (id)initWithControlName:(NSString*)name contentType:(NSString*)type fileName:(NSString*)fileName temporaryPath:(NSString*)temporaryPath { - (id)initWithControlName:(NSString*)name contentType:(NSString*)type fileName:(NSString*)fileName temporaryPath:(NSString*)temporaryPath {
if ((self = [super initWithControlName:name contentType:type])) { if ((self = [super initWithControlName:name contentType:type])) {
@@ -198,7 +198,6 @@ static NSData* _dashNewlineData = nil;
if (_state == kParserState_Headers) { if (_state == kParserState_Headers) {
NSRange range = [_data rangeOfData:_newlinesData options:0 range:NSMakeRange(0, _data.length)]; NSRange range = [_data rangeOfData:_newlinesData options:0 range:NSMakeRange(0, _data.length)];
if (range.location != NSNotFound) { if (range.location != NSNotFound) {
_controlName = nil; _controlName = nil;
_fileName = nil; _fileName = nil;
_contentType = nil; _contentType = nil;
@@ -269,7 +268,6 @@ static NSData* _dashNewlineData = nil;
NSRange subRange1 = [_data rangeOfData:_newlineData options:NSDataSearchAnchored range:subRange]; NSRange subRange1 = [_data rangeOfData:_newlineData options:NSDataSearchAnchored range:subRange];
NSRange subRange2 = [_data rangeOfData:_dashNewlineData options:NSDataSearchAnchored range:subRange]; NSRange subRange2 = [_data rangeOfData:_dashNewlineData options:NSDataSearchAnchored range:subRange];
if ((subRange1.location != NSNotFound) || (subRange2.location != NSNotFound)) { if ((subRange1.location != NSNotFound) || (subRange2.location != NSNotFound)) {
if (_state == kParserState_Content) { if (_state == kParserState_Content) {
const void* dataBytes = _data.bytes; const void* dataBytes = _data.bytes;
NSUInteger dataLength = range.location - 2; NSUInteger dataLength = range.location - 2;
@@ -358,7 +356,7 @@ static NSData* _dashNewlineData = nil;
@implementation GCDWebServerMultiPartFormRequest @implementation GCDWebServerMultiPartFormRequest
@synthesize arguments=_arguments, files=_files; @synthesize arguments = _arguments, files = _files;
+ (NSString*)mimeType { + (NSString*)mimeType {
return @"multipart/form-data"; return @"multipart/form-data";
@@ -377,7 +375,7 @@ static NSData* _dashNewlineData = nil;
_parser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:nil arguments:_arguments files:_files]; _parser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:nil arguments:_arguments files:_files];
if (_parser == nil) { if (_parser == nil) {
if (error) { if (error) {
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed starting to parse multipart form data"}]; *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed starting to parse multipart form data" }];
} }
return NO; return NO;
} }
@@ -387,7 +385,7 @@ static NSData* _dashNewlineData = nil;
- (BOOL)writeData:(NSData*)data error:(NSError**)error { - (BOOL)writeData:(NSData*)data error:(NSError**)error {
if (![_parser appendBytes:data.bytes length:data.length]) { if (![_parser appendBytes:data.bytes length:data.length]) {
if (error) { if (error) {
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed continuing to parse multipart form data"}]; *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed continuing to parse multipart form data" }];
} }
return NO; return NO;
} }
@@ -399,7 +397,7 @@ static NSData* _dashNewlineData = nil;
_parser = nil; _parser = nil;
if (!atEnd) { if (!atEnd) {
if (error) { if (error) {
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed finishing to parse multipart form data"}]; *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed finishing to parse multipart form data" }];
} }
return NO; return NO;
} }
@@ -39,7 +39,7 @@
@implementation GCDWebServerURLEncodedFormRequest @implementation GCDWebServerURLEncodedFormRequest
@synthesize arguments=_arguments; @synthesize arguments = _arguments;
+ (NSString*)mimeType { + (NSString*)mimeType {
return @"application/x-www-form-urlencoded"; return @"application/x-www-form-urlencoded";
@@ -37,45 +37,45 @@
/** /**
* Creates a client error response with the corresponding HTTP status code. * Creates a client error response with the corresponding HTTP status code.
*/ */
+ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2,3); + (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2, 3);
/** /**
* Creates a server error response with the corresponding HTTP status code. * Creates a server error response with the corresponding HTTP status code.
*/ */
+ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2,3); + (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2, 3);
/** /**
* Creates a client error response with the corresponding HTTP status code * Creates a client error response with the corresponding HTTP status code
* and an underlying NSError. * and an underlying NSError.
*/ */
+ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3,4); + (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3, 4);
/** /**
* Creates a server error response with the corresponding HTTP status code * Creates a server error response with the corresponding HTTP status code
* and an underlying NSError. * and an underlying NSError.
*/ */
+ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3,4); + (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3, 4);
/** /**
* Initializes a client error response with the corresponding HTTP status code. * Initializes a client error response with the corresponding HTTP status code.
*/ */
- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2,3); - (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2, 3);
/** /**
* Initializes a server error response with the corresponding HTTP status code. * Initializes a server error response with the corresponding HTTP status code.
*/ */
- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2,3); - (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2, 3);
/** /**
* Initializes a client error response with the corresponding HTTP status code * Initializes a client error response with the corresponding HTTP status code
* and an underlying NSError. * and an underlying NSError.
*/ */
- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3,4); - (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3, 4);
/** /**
* Initializes a server error response with the corresponding HTTP status code * Initializes a server error response with the corresponding HTTP status code
* and an underlying NSError. * and an underlying NSError.
*/ */
- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3,4); - (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3, 4);
@end @end
@@ -48,13 +48,14 @@
} }
- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block { - (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
return [self initWithContentType:type asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) { return [self initWithContentType:type
asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) {
NSError* error = nil; NSError* error = nil;
NSData* data = block(&error); NSData* data = block(&error);
completionBlock(data, error); completionBlock(data, error);
}]; }];
} }
- (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block { - (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block {
+95 -75
View File
@@ -73,7 +73,7 @@
return YES; return YES;
} }
- (NSString*) _uniquePathForPath:(NSString*)path { - (NSString*)_uniquePathForPath:(NSString*)path {
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSString* directory = [path stringByDeletingLastPathComponent]; NSString* directory = [path stringByDeletingLastPathComponent];
NSString* file = [path lastPathComponent]; NSString* file = [path lastPathComponent];
@@ -120,15 +120,15 @@
NSString* type = [attributes objectForKey:NSFileType]; NSString* type = [attributes objectForKey:NSFileType];
if ([type isEqualToString:NSFileTypeRegular] && [self _checkFileExtension:item]) { if ([type isEqualToString:NSFileTypeRegular] && [self _checkFileExtension:item]) {
[array addObject:@{ [array addObject:@{
@"path": [relativePath stringByAppendingPathComponent:item], @"path" : [relativePath stringByAppendingPathComponent:item],
@"name": item, @"name" : item,
@"size": [attributes objectForKey:NSFileSize] @"size" : [attributes objectForKey:NSFileSize]
}]; }];
} else if ([type isEqualToString:NSFileTypeDirectory]) { } else if ([type isEqualToString:NSFileTypeDirectory]) {
[array addObject:@{ [array addObject:@{
@"path": [[relativePath stringByAppendingPathComponent:item] stringByAppendingString:@"/"], @"path" : [[relativePath stringByAppendingPathComponent:item] stringByAppendingString:@"/"],
@"name": item @"name" : item
}]; }];
} }
} }
} }
@@ -151,7 +151,7 @@
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Downlading file name \"%@\" is not allowed", fileName]; return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Downlading file name \"%@\" is not allowed", fileName];
} }
if ([self.delegate respondsToSelector:@selector(webUploader:didDownloadFileAtPath: )]) { if ([self.delegate respondsToSelector:@selector(webUploader:didDownloadFileAtPath:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate webUploader:self didDownloadFileAtPath:absolutePath]; [self.delegate webUploader:self didDownloadFileAtPath:absolutePath];
}); });
@@ -289,8 +289,8 @@
@implementation GCDWebUploader @implementation GCDWebUploader
@synthesize uploadDirectory=_uploadDirectory, allowedFileExtensions=_allowedExtensions, allowHiddenItems=_allowHidden, @synthesize uploadDirectory = _uploadDirectory, allowedFileExtensions = _allowedExtensions, allowHiddenItems = _allowHidden,
title=_title, header=_header, prologue=_prologue, epilogue=_epilogue, footer=_footer; title = _title, header = _header, prologue = _prologue, epilogue = _epilogue, footer = _footer;
@dynamic delegate; @dynamic delegate;
@@ -307,91 +307,111 @@
[self addGETHandlerForBasePath:@"/" directoryPath:[siteBundle resourcePath] indexFilename:nil cacheAge:3600 allowRangeRequests:NO]; [self addGETHandlerForBasePath:@"/" directoryPath:[siteBundle resourcePath] indexFilename:nil cacheAge:3600 allowRangeRequests:NO];
// Web page // Web page
[self addHandlerForMethod:@"GET" path:@"/" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"GET"
path:@"/"
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
NSString* device = [[UIDevice currentDevice] name]; NSString* device = [[UIDevice currentDevice] name];
#else #else
NSString* device = CFBridgingRelease(SCDynamicStoreCopyComputerName(NULL, NULL)); NSString* device = CFBridgingRelease(SCDynamicStoreCopyComputerName(NULL, NULL));
#endif #endif
NSString* title = server.title; NSString* title = server.title;
if (title == nil) { if (title == nil) {
title = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; title = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
if (title == nil) { if (title == nil) {
title = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; title = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
} }
#if !TARGET_OS_IPHONE #if !TARGET_OS_IPHONE
if (title == nil) { if (title == nil) {
title = [[NSProcessInfo processInfo] processName]; title = [[NSProcessInfo processInfo] processName];
} }
#endif #endif
} }
NSString* header = server.header; NSString* header = server.header;
if (header == nil) { if (header == nil) {
header = title; header = title;
} }
NSString* prologue = server.prologue; NSString* prologue = server.prologue;
if (prologue == nil) { if (prologue == nil) {
prologue = [siteBundle localizedStringForKey:@"PROLOGUE" value:@"" table:nil]; prologue = [siteBundle localizedStringForKey:@"PROLOGUE" value:@"" table:nil];
} }
NSString* epilogue = server.epilogue; NSString* epilogue = server.epilogue;
if (epilogue == nil) { if (epilogue == nil) {
epilogue = [siteBundle localizedStringForKey:@"EPILOGUE" value:@"" table:nil]; epilogue = [siteBundle localizedStringForKey:@"EPILOGUE" value:@"" table:nil];
} }
NSString* footer = server.footer; NSString* footer = server.footer;
if (footer == nil) { if (footer == nil) {
NSString* name = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; NSString* name = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
NSString* version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; NSString* version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
#if !TARGET_OS_IPHONE #if !TARGET_OS_IPHONE
if (!name && !version) { if (!name && !version) {
name = @"OS X"; name = @"OS X";
version = [[NSProcessInfo processInfo] operatingSystemVersionString]; version = [[NSProcessInfo processInfo] operatingSystemVersionString];
} }
#endif #endif
footer = [NSString stringWithFormat:[siteBundle localizedStringForKey:@"FOOTER_FORMAT" value:@"" table:nil], name, version]; footer = [NSString stringWithFormat:[siteBundle localizedStringForKey:@"FOOTER_FORMAT" value:@"" table:nil], name, version];
} }
return [GCDWebServerDataResponse responseWithHTMLTemplate:[siteBundle pathForResource:@"index" ofType:@"html"] return [GCDWebServerDataResponse responseWithHTMLTemplate:[siteBundle pathForResource:@"index" ofType:@"html"]
variables:@{ variables:@{
@"device": device, @"device" : device,
@"title": title, @"title" : title,
@"header": header, @"header" : header,
@"prologue": prologue, @"prologue" : prologue,
@"epilogue": epilogue, @"epilogue" : epilogue,
@"footer": footer @"footer" : footer
}]; }];
}]; }];
// File listing // File listing
[self addHandlerForMethod:@"GET" path:@"/list" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"GET"
return [server listDirectory:request]; path:@"/list"
}]; requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server listDirectory:request];
}];
// File download // File download
[self addHandlerForMethod:@"GET" path:@"/download" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"GET"
return [server downloadFile:request]; path:@"/download"
}]; requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server downloadFile:request];
}];
// File upload // File upload
[self addHandlerForMethod:@"POST" path:@"/upload" requestClass:[GCDWebServerMultiPartFormRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"POST"
return [server uploadFile:(GCDWebServerMultiPartFormRequest*)request]; path:@"/upload"
}]; requestClass:[GCDWebServerMultiPartFormRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server uploadFile:(GCDWebServerMultiPartFormRequest*)request];
}];
// File and folder moving // File and folder moving
[self addHandlerForMethod:@"POST" path:@"/move" requestClass:[GCDWebServerURLEncodedFormRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"POST"
return [server moveItem:(GCDWebServerURLEncodedFormRequest*)request]; path:@"/move"
}]; requestClass:[GCDWebServerURLEncodedFormRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server moveItem:(GCDWebServerURLEncodedFormRequest*)request];
}];
// File and folder deletion // File and folder deletion
[self addHandlerForMethod:@"POST" path:@"/delete" requestClass:[GCDWebServerURLEncodedFormRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"POST"
return [server deleteItem:(GCDWebServerURLEncodedFormRequest*)request]; path:@"/delete"
}]; requestClass:[GCDWebServerURLEncodedFormRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server deleteItem:(GCDWebServerURLEncodedFormRequest*)request];
}];
// Directory creation // Directory creation
[self addHandlerForMethod:@"POST" path:@"/create" requestClass:[GCDWebServerURLEncodedFormRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addHandlerForMethod:@"POST"
return [server createDirectory:(GCDWebServerURLEncodedFormRequest*)request]; path:@"/create"
}]; requestClass:[GCDWebServerURLEncodedFormRequest class]
processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [server createDirectory:(GCDWebServerURLEncodedFormRequest*)request];
}];
} }
return self; return self;
} }
+71 -70
View File
@@ -204,7 +204,6 @@ int main(int argc, const char* argv[]) {
GCDWebServer* webServer = nil; GCDWebServer* webServer = nil;
switch (mode) { switch (mode) {
// Simply serve contents of home directory // Simply serve contents of home directory
case kMode_WebServer: { case kMode_WebServer: {
fprintf(stdout, "Running in Web Server mode from \"%s\"", [rootDirectory UTF8String]); fprintf(stdout, "Running in Web Server mode from \"%s\"", [rootDirectory UTF8String]);
@@ -219,11 +218,11 @@ int main(int argc, const char* argv[]) {
webServer = [[GCDWebServer alloc] init]; webServer = [[GCDWebServer alloc] init];
[webServer addDefaultHandlerForMethod:@"GET" [webServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class] requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
return [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"]; return [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"];
}]; }];
break; break;
} }
@@ -234,9 +233,9 @@ int main(int argc, const char* argv[]) {
[webServer addHandlerForMethod:@"GET" [webServer addHandlerForMethod:@"GET"
path:@"/" path:@"/"
requestClass:[GCDWebServerRequest class] requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
NSString* html = @" \ NSString* html = @" \
<html><body> \ <html><body> \
<form name=\"input\" action=\"/\" method=\"post\" enctype=\"application/x-www-form-urlencoded\"> \ <form name=\"input\" action=\"/\" method=\"post\" enctype=\"application/x-www-form-urlencoded\"> \
Value: <input type=\"text\" name=\"value\"> \ Value: <input type=\"text\" name=\"value\"> \
@@ -244,19 +243,19 @@ int main(int argc, const char* argv[]) {
</form> \ </form> \
</body></html> \ </body></html> \
"; ";
return [GCDWebServerDataResponse responseWithHTML:html]; return [GCDWebServerDataResponse responseWithHTML:html];
}]; }];
[webServer addHandlerForMethod:@"POST" [webServer addHandlerForMethod:@"POST"
path:@"/" path:@"/"
requestClass:[GCDWebServerURLEncodedFormRequest class] requestClass:[GCDWebServerURLEncodedFormRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
NSString* value = [[(GCDWebServerURLEncodedFormRequest*)request arguments] objectForKey:@"value"]; NSString* value = [[(GCDWebServerURLEncodedFormRequest*)request arguments] objectForKey:@"value"];
NSString* html = [NSString stringWithFormat:@"<html><body><p>%@</p></body></html>", value]; NSString* html = [NSString stringWithFormat:@"<html><body><p>%@</p></body></html>", value];
return [GCDWebServerDataResponse responseWithHTML:html]; return [GCDWebServerDataResponse responseWithHTML:html];
}]; }];
break; break;
} }
@@ -274,31 +273,31 @@ int main(int argc, const char* argv[]) {
[webServer addHandlerForMethod:@"GET" [webServer addHandlerForMethod:@"GET"
path:@"/" path:@"/"
requestClass:[GCDWebServerRequest class] requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
NSString* html = [NSString stringWithFormat:@"<html><body>%@</body></html>", formHTML]; NSString* html = [NSString stringWithFormat:@"<html><body>%@</body></html>", formHTML];
return [GCDWebServerDataResponse responseWithHTML:html]; return [GCDWebServerDataResponse responseWithHTML:html];
}]; }];
[webServer addHandlerForMethod:@"POST" [webServer addHandlerForMethod:@"POST"
path:@"/" path:@"/"
requestClass:[GCDWebServerMultiPartFormRequest class] requestClass:[GCDWebServerMultiPartFormRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
NSMutableString* string = [NSMutableString string]; NSMutableString* string = [NSMutableString string];
for (GCDWebServerMultiPartArgument* argument in [(GCDWebServerMultiPartFormRequest*)request arguments]) { for (GCDWebServerMultiPartArgument* argument in [(GCDWebServerMultiPartFormRequest*)request arguments]) {
[string appendFormat:@"%@ = %@<br>", argument.controlName, argument.string]; [string appendFormat:@"%@ = %@<br>", argument.controlName, argument.string];
} }
for (GCDWebServerMultiPartFile* file in [(GCDWebServerMultiPartFormRequest*)request files]) { for (GCDWebServerMultiPartFile* file in [(GCDWebServerMultiPartFormRequest*)request files]) {
NSDictionary* attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:file.temporaryPath error:NULL]; NSDictionary* attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:file.temporaryPath error:NULL];
[string appendFormat:@"%@ = &quot;%@&quot; (%@ | %llu %@)<br>", file.controlName, file.fileName, file.mimeType, [string appendFormat:@"%@ = &quot;%@&quot; (%@ | %llu %@)<br>", file.controlName, file.fileName, file.mimeType,
attributes.fileSize >= 1000 ? attributes.fileSize / 1000 : attributes.fileSize, attributes.fileSize >= 1000 ? attributes.fileSize / 1000 : attributes.fileSize,
attributes.fileSize >= 1000 ? @"KB" : @"Bytes"]; attributes.fileSize >= 1000 ? @"KB" : @"Bytes"];
}; };
NSString* html = [NSString stringWithFormat:@"<html><body><p>%@</p><hr>%@</body></html>", string, formHTML]; NSString* html = [NSString stringWithFormat:@"<html><body><p>%@</p><hr>%@</body></html>", string, formHTML];
return [GCDWebServerDataResponse responseWithHTML:html]; return [GCDWebServerDataResponse responseWithHTML:html];
}]; }];
break; break;
} }
@@ -323,39 +322,41 @@ int main(int argc, const char* argv[]) {
[webServer addHandlerForMethod:@"GET" [webServer addHandlerForMethod:@"GET"
path:@"/sync" path:@"/sync"
requestClass:[GCDWebServerRequest class] requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
__block int countDown = 10; __block int countDown = 10;
return [GCDWebServerStreamedResponse responseWithContentType:@"text/plain" streamBlock:^NSData *(NSError** error) { return [GCDWebServerStreamedResponse responseWithContentType:@"text/plain"
streamBlock:^NSData*(NSError** error) {
usleep(100 * 1000); usleep(100 * 1000);
if (countDown) { if (countDown) {
return [[NSString stringWithFormat:@"%i\n", countDown--] dataUsingEncoding:NSUTF8StringEncoding]; return [[NSString stringWithFormat:@"%i\n", countDown--] dataUsingEncoding:NSUTF8StringEncoding];
} else { } else {
return [NSData data]; return [NSData data];
} }
}]; }];
}]; }];
[webServer addHandlerForMethod:@"GET" [webServer addHandlerForMethod:@"GET"
path:@"/async" path:@"/async"
requestClass:[GCDWebServerRequest class] requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) {
__block int countDown = 10; __block int countDown = 10;
return [GCDWebServerStreamedResponse responseWithContentType:@"text/plain" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) { return [GCDWebServerStreamedResponse responseWithContentType:@"text/plain"
asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSData* data = countDown ? [[NSString stringWithFormat:@"%i\n", countDown--] dataUsingEncoding:NSUTF8StringEncoding] : [NSData data]; NSData* data = countDown ? [[NSString stringWithFormat:@"%i\n", countDown--] dataUsingEncoding:NSUTF8StringEncoding] : [NSData data];
completionBlock(data, nil); completionBlock(data, nil);
}); });
}]; }];
}]; }];
break; break;
} }
@@ -368,38 +369,38 @@ int main(int argc, const char* argv[]) {
requestClass:[GCDWebServerRequest class] requestClass:[GCDWebServerRequest class]
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithData:[@"Hello World!" dataUsingEncoding:NSUTF8StringEncoding] contentType:@"text/plain"]; GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithData:[@"Hello World!" dataUsingEncoding:NSUTF8StringEncoding] contentType:@"text/plain"];
completionBlock(response); completionBlock(response);
}); });
}]; }];
[webServer addHandlerForMethod:@"GET" [webServer addHandlerForMethod:@"GET"
path:@"/async2" path:@"/async2"
requestClass:[GCDWebServerRequest class] requestClass:[GCDWebServerRequest class]
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock handlerCompletionBlock) { asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock handlerCompletionBlock) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__block int countDown = 10; __block int countDown = 10;
GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:@"text/plain" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock readerCompletionBlock) { GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:@"text/plain"
asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock readerCompletionBlock) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSData* data = countDown ? [[NSString stringWithFormat:@"%i\n", countDown--] dataUsingEncoding:NSUTF8StringEncoding] : [NSData data]; NSData* data = countDown ? [[NSString stringWithFormat:@"%i\n", countDown--] dataUsingEncoding:NSUTF8StringEncoding] : [NSData data];
readerCompletionBlock(data, nil); readerCompletionBlock(data, nil);
}); });
}]; }];
handlerCompletionBlock(response); handlerCompletionBlock(response);
}); });
}]; }];
break; break;
} }
} }
if (webServer) { if (webServer) {
@@ -409,7 +410,7 @@ int main(int argc, const char* argv[]) {
webServer.delegate = delegate; webServer.delegate = delegate;
#endif #endif
fprintf(stdout, "<RUNNING TESTS FROM \"%s\">\n\n", [testDirectory UTF8String]); fprintf(stdout, "<RUNNING TESTS FROM \"%s\">\n\n", [testDirectory UTF8String]);
result = (int)[webServer runTestsWithOptions:@{GCDWebServerOption_Port: @8080} inDirectory:testDirectory]; result = (int)[webServer runTestsWithOptions:@{ GCDWebServerOption_Port : @8080 } inDirectory:testDirectory];
} else { } else {
webServer.delegate = delegate; webServer.delegate = delegate;
if (recording) { if (recording) {
@@ -424,7 +425,7 @@ int main(int argc, const char* argv[]) {
[options setObject:@"" forKey:GCDWebServerOption_BonjourName]; [options setObject:@"" forKey:GCDWebServerOption_BonjourName];
if (authenticationUser && authenticationPassword) { if (authenticationUser && authenticationPassword) {
[options setValue:authenticationRealm forKey:GCDWebServerOption_AuthenticationRealm]; [options setValue:authenticationRealm forKey:GCDWebServerOption_AuthenticationRealm];
[options setObject:@{authenticationUser: authenticationPassword} forKey:GCDWebServerOption_AuthenticationAccounts]; [options setObject:@{ authenticationUser : authenticationPassword } forKey:GCDWebServerOption_AuthenticationAccounts];
if ([authenticationMethod isEqualToString:@"Basic"]) { if ([authenticationMethod isEqualToString:@"Basic"]) {
[options setObject:GCDWebServerAuthenticationMethod_Basic forKey:GCDWebServerOption_AuthenticationMethod]; [options setObject:GCDWebServerAuthenticationMethod_Basic forKey:GCDWebServerOption_AuthenticationMethod];
} else if ([authenticationMethod isEqualToString:@"Digest"]) { } else if ([authenticationMethod isEqualToString:@"Digest"]) {
+40
View File
@@ -0,0 +1,40 @@
#!/bin/sh -ex
# brew install clang-format
CLANG_FORMAT_VERSION=`clang-format -version | awk '{ print $3 }'`
if [[ "$CLANG_FORMAT_VERSION" != "4.0.0" ]]; then
echo "Unsupported clang-format version"
exit 1
fi
pushd "GCDWebServer/Core"
clang-format -style=file -i *.h *.m
popd
pushd "GCDWebServer/Requests"
clang-format -style=file -i *.h *.m
popd
pushd "GCDWebServer/Responses"
clang-format -style=file -i *.h *.m
popd
pushd "GCDWebUploader"
clang-format -style=file -i *.h *.m
popd
pushd "GCDWebDAVServer"
clang-format -style=file -i *.h *.m
popd
pushd "Frameworks"
clang-format -style=file -i *.h *.m
popd
pushd "Mac"
clang-format -style=file -i *.m
popd
pushd "iOS"
clang-format -style=file -i *.h *.m
popd
pushd "tvOS"
clang-format -style=file -i *.h *.m
popd
echo "OK"