Kaynağa Gözat

Updated handlers convenience API

Pierre-Olivier Latour 11 yıl önce
ebeveyn
işleme
cedec20673
4 değiştirilmiş dosya ile 85 ekleme ve 57 silme
  1. 6 1
      CGDWebServer/GCDWebServer.h
  2. 73 53
      CGDWebServer/GCDWebServer.m
  3. 4 1
      Mac/main.m
  4. 2 2
      README.md

+ 6 - 1
CGDWebServer/GCDWebServer.h

@@ -54,7 +54,12 @@ typedef GCDWebServerResponse* (^GCDWebServerProcessBlock)(GCDWebServerRequest* r
 
 @interface GCDWebServer (Handlers)
 - (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block;
-- (void)addHandlerForBasePath:(NSString*)basePath localPath:(NSString*)localPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests;  // Base path is recursive and case-sensitive
 - (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block;  // Path is case-insensitive
 - (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block;  // Regular expression is case-insensitive
 @end
+
+@interface GCDWebServer (GETHandlers)
+- (void)addGETHandlerForPath:(NSString*)path staticData:(NSData*)staticData contentType:(NSString*)contentType cacheAge:(NSUInteger)cacheAge;  // Path is case-insensitive
+- (void)addGETHandlerForPath:(NSString*)path filePath:(NSString*)filePath isAttachment:(BOOL)isAttachment cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests;  // Path is case-insensitive
+- (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)directoryPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests;  // Base path is recursive and case-sensitive
+@end

+ 73 - 53
CGDWebServer/GCDWebServer.m

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

+ 4 - 1
Mac/main.m

@@ -34,11 +34,13 @@ int main(int argc, const char* argv[]) {
     GCDWebServer* webServer = [[GCDWebServer alloc] init];
     switch (mode) {
       
+      // Simply serve contents of home directory
       case 0: {
-        [webServer addHandlerForBasePath:@"/" localPath:NSHomeDirectory() indexFilename:nil cacheAge:0 allowRangeRequests:YES];
+        [webServer addGETHandlerForBasePath:@"/" directoryPath:NSHomeDirectory() indexFilename:nil cacheAge:0 allowRangeRequests:YES];
         break;
       }
       
+      // Renders a HTML page
       case 1: {
         [webServer addDefaultHandlerForMethod:@"GET"
                                  requestClass:[GCDWebServerRequest class]
@@ -50,6 +52,7 @@ int main(int argc, const char* argv[]) {
         break;
       }
       
+      // Implements an HTML form
       case 2: {
         [webServer addHandlerForMethod:@"GET"
                                   path:@"/"

+ 2 - 2
README.md

@@ -67,7 +67,7 @@ int main(int argc, const char* argv[]) {
   @autoreleasepool {
     
     GCDWebServer* webServer = [[GCDWebServer alloc] init];
-    [webServer addHandlerForBasePath:@"/" localPath:NSHomeDirectory() indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
+    [webServer addGETHandlerForBasePath:@"/" directoryPath:NSHomeDirectory() indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
     [webServer runWithPort:8080];
     [webServer release];
     
@@ -171,7 +171,7 @@ Assuming you have a website directory in your app containing HTML template files
 NSString* websitePath = [[NSBundle mainBundle] pathForResource:@"Website" ofType:nil];
 
 // Add a default handler to serve static files (i.e. anything other than HTML files)
-[self addHandlerForBasePath:@"/" localPath:websitePath indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
+[self addGETHandlerForBasePath:@"/" directoryPath:websitePath indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
 
 // Add an override handler for all requests to "*.html" URLs to do the special HTML templatization
 [self addHandlerForMethod:@"GET"