|
@@ -361,12 +361,71 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
|
|
} processBlock:block];
|
|
|
}
|
|
|
|
|
|
-- (GCDWebServerResponse*)_responseWithContentsOfFile:(NSString*)path {
|
|
|
- return [GCDWebServerFileResponse responseWithFile:path];
|
|
|
+- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
|
|
|
+ if ([path hasPrefix:@"/"] && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) {
|
|
|
+ [self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
|
|
+
|
|
|
+ if (![requestMethod isEqualToString:method]) {
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+ if ([urlPath caseInsensitiveCompare:path] != NSOrderedSame) {
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+ return ARC_AUTORELEASE([[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
|
|
+
|
|
|
+ } processBlock:block];
|
|
|
+ } else {
|
|
|
+ DNOT_REACHED();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
|
|
|
+ NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:regex options:NSRegularExpressionCaseInsensitive error:NULL];
|
|
|
+ if (expression && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) {
|
|
|
+ [self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
|
|
+
|
|
|
+ if (![requestMethod isEqualToString:method]) {
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+ if ([expression firstMatchInString:urlPath options:0 range:NSMakeRange(0, urlPath.length)] == nil) {
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+ return ARC_AUTORELEASE([[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
|
|
+
|
|
|
+ } processBlock:block];
|
|
|
+ } else {
|
|
|
+ DNOT_REACHED();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@implementation GCDWebServer (GETHandlers)
|
|
|
+
|
|
|
+- (void)addGETHandlerForPath:(NSString*)path staticData:(NSData*)staticData contentType:(NSString*)contentType cacheAge:(NSUInteger)cacheAge {
|
|
|
+ GCDWebServerResponse* response = [GCDWebServerDataResponse responseWithData:staticData contentType:contentType];
|
|
|
+ response.cacheControlMaxAge = cacheAge;
|
|
|
+ [self addHandlerForMethod:@"GET" path:path requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
|
|
+
|
|
|
+ return response;
|
|
|
+
|
|
|
+ }];
|
|
|
}
|
|
|
|
|
|
-- (GCDWebServerResponse*)_responseWithPartialContentsOfFile:(NSString*)path byteRange:(NSRange)range {
|
|
|
- return [GCDWebServerFileResponse responseWithFile:path byteRange:range];
|
|
|
+- (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) {
|
|
|
+
|
|
|
+ GCDWebServerResponse* response = nil;
|
|
|
+ if (allowRangeRequests) {
|
|
|
+ response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange isAttachment:isAttachment];
|
|
|
+ [response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
|
|
|
+ } else {
|
|
|
+ response = [GCDWebServerFileResponse responseWithFile:filePath isAttachment:isAttachment];
|
|
|
+ }
|
|
|
+ response.cacheControlMaxAge = cacheAge;
|
|
|
+ return response;
|
|
|
+
|
|
|
+ }];
|
|
|
}
|
|
|
|
|
|
- (GCDWebServerResponse*)_responseWithContentsOfDirectory:(NSString*)path {
|
|
@@ -375,7 +434,8 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
|
|
return nil;
|
|
|
}
|
|
|
NSMutableString* html = [NSMutableString string];
|
|
|
- [html appendString:@"<html><body>\n"];
|
|
|
+ [html appendString:@"<!DOCTYPE html>\n"];
|
|
|
+ [html appendString:@"<html><head><meta charset=\"utf-8\"></head><body>\n"];
|
|
|
[html appendString:@"<ul>\n"];
|
|
|
for (NSString* file in enumerator) {
|
|
|
if (![file hasPrefix:@"."]) {
|
|
@@ -395,7 +455,7 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
|
|
return [GCDWebServerDataResponse responseWithHTML:html];
|
|
|
}
|
|
|
|
|
|
-- (void)addHandlerForBasePath:(NSString*)basePath localPath:(NSString*)localPath 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 __has_feature(objc_arc)
|
|
|
__unsafe_unretained GCDWebServer* server = self;
|
|
@@ -415,27 +475,24 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
|
|
} processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
|
|
|
|
|
GCDWebServerResponse* response = nil;
|
|
|
- NSString* filePath = [localPath stringByAppendingPathComponent:[request.path substringFromIndex:basePath.length]];
|
|
|
+ NSString* filePath = [directoryPath stringByAppendingPathComponent:[request.path substringFromIndex:basePath.length]];
|
|
|
BOOL isDirectory;
|
|
|
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]) {
|
|
|
if (isDirectory) {
|
|
|
if (indexFilename) {
|
|
|
NSString* indexPath = [filePath stringByAppendingPathComponent:indexFilename];
|
|
|
if ([[NSFileManager defaultManager] fileExistsAtPath:indexPath isDirectory:&isDirectory] && !isDirectory) {
|
|
|
- return [server _responseWithContentsOfFile:indexPath];
|
|
|
+ return [GCDWebServerFileResponse responseWithFile:indexPath];
|
|
|
}
|
|
|
}
|
|
|
response = [server _responseWithContentsOfDirectory:filePath];
|
|
|
- } else if (allowRangeRequests) {
|
|
|
- NSRange range = request.byteRange;
|
|
|
- if ((range.location != NSNotFound) || (range.length > 0)) {
|
|
|
- response = [server _responseWithPartialContentsOfFile:filePath byteRange:range];
|
|
|
+ } else {
|
|
|
+ if (allowRangeRequests) {
|
|
|
+ response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange];
|
|
|
+ [response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
|
|
|
} else {
|
|
|
- response = [server _responseWithContentsOfFile:filePath];
|
|
|
+ response = [GCDWebServerFileResponse responseWithFile:filePath];
|
|
|
}
|
|
|
- [response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
|
|
|
- } else {
|
|
|
- response = [server _responseWithContentsOfFile:filePath];
|
|
|
}
|
|
|
}
|
|
|
if (response) {
|
|
@@ -451,41 +508,4 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
|
|
|
- if ([path hasPrefix:@"/"] && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) {
|
|
|
- [self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
|
|
-
|
|
|
- if (![requestMethod isEqualToString:method]) {
|
|
|
- return nil;
|
|
|
- }
|
|
|
- if ([urlPath caseInsensitiveCompare:path] != NSOrderedSame) {
|
|
|
- return nil;
|
|
|
- }
|
|
|
- return ARC_AUTORELEASE([[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
|
|
-
|
|
|
- } processBlock:block];
|
|
|
- } else {
|
|
|
- DNOT_REACHED();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block {
|
|
|
- NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:regex options:NSRegularExpressionCaseInsensitive error:NULL];
|
|
|
- if (expression && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) {
|
|
|
- [self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
|
|
-
|
|
|
- if (![requestMethod isEqualToString:method]) {
|
|
|
- return nil;
|
|
|
- }
|
|
|
- if ([expression firstMatchInString:urlPath options:0 range:NSMakeRange(0, urlPath.length)] == nil) {
|
|
|
- return nil;
|
|
|
- }
|
|
|
- return ARC_AUTORELEASE([[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
|
|
-
|
|
|
- } processBlock:block];
|
|
|
- } else {
|
|
|
- DNOT_REACHED();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
@end
|