在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):swisspol/GCDWebServer开源软件地址(OpenSource Url):https://github.com/swisspol/GCDWebServer开源编程语言(OpenSource Language):Objective-C 83.3%开源软件介绍(OpenSource Introduction):OverviewGCDWebServer is a modern and lightweight GCD based HTTP 1.1 server designed to be embedded in iOS, macOS & tvOS apps. It was written from scratch with the following goals in mind:
Extra built-in features:
Included extensions:
What's not supported (but not really required from an embedded HTTP server):
Requirements:
Getting StartedDownload or check out the latest release of GCDWebServer then add the entire "GCDWebServer" subfolder to your Xcode project. If you intend to use one of the extensions like GCDWebDAVServer or GCDWebUploader, add these subfolders as well. Finally link to Alternatively, you can install GCDWebServer using CocoaPods by simply adding this line to your Podfile:
If you want to use GCDWebUploader, use this line instead:
Or this line for GCDWebDAVServer:
And finally run You can also use Carthage by adding this line to your Cartfile (3.2.5 is the first release with Carthage support):
Then run Help & SupportFor help with using GCDWebServer, it's best to ask your question on Stack Overflow with the Be sure to read this entire README first though! Hello WorldThese code snippets show how to implement a custom HTTP server that runs on port 8080 and returns a "Hello World" HTML page to any request. Since GCDWebServer uses GCD blocks to handle requests, no subclassing or delegates are needed, which results in very clean code. IMPORTANT: If not using CocoaPods, be sure to add the macOS version (command line tool): #import "GCDWebServer.h"
#import "GCDWebServerDataResponse.h"
int main(int argc, const char* argv[]) {
@autoreleasepool {
// Create server
GCDWebServer* webServer = [[GCDWebServer alloc] init];
// Add a handler to respond to GET requests on any URL
[webServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
return [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"];
}];
// Use convenience method that runs server on port 8080
// until SIGINT (Ctrl-C in Terminal) or SIGTERM is received
[webServer runWithPort:8080 bonjourName:nil];
NSLog(@"Visit %@ in your web browser", webServer.serverURL);
}
return 0;
} iOS version: #import "GCDWebServer.h"
#import "GCDWebServerDataResponse.h"
@interface AppDelegate : NSObject <UIApplicationDelegate> {
GCDWebServer* _webServer;
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
// Create server
_webServer = [[GCDWebServer alloc] init];
// Add a handler to respond to GET requests on any URL
[_webServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
return [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"];
}];
// Start server on port 8080
[_webServer startWithPort:8080 bonjourName:nil];
NSLog(@"Visit %@ in your web browser", _webServer.serverURL);
return YES;
}
@end macOS Swift version (command line tool): webServer.swift import Foundation
import GCDWebServer
func initWebServer() {
let webServer = GCDWebServer()
webServer.addDefaultHandler(forMethod: "GET", request: GCDWebServerRequest.self, processBlock: {request in
return GCDWebServerDataResponse(html:"<html><body><p>Hello World</p></body></html>")
})
webServer.start(withPort: 8080, bonjourName: "GCD Web Server")
print("Visit \(webServer.serverURL) in your web browser")
} WebServer-Bridging-Header.h #import <GCDWebServer/GCDWebServer.h>
#import <GCDWebServer/GCDWebServerDataResponse.h> Web Based Uploads in iOS AppsGCDWebUploader is a subclass of Simply instantiate and run a #import "GCDWebUploader.h"
@interface AppDelegate : NSObject <UIApplicationDelegate> {
GCDWebUploader* _webUploader;
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
_webUploader = [[GCDWebUploader alloc] initWithUploadDirectory:documentsPath];
[_webUploader start];
NSLog(@"Visit %@ in your web browser", _webUploader.serverURL);
return YES;
}
@end WebDAV Server in iOS AppsGCDWebDAVServer is a subclass of GCDWebDAVServer should also work with the macOS Finder as it is partially class 2 compliant (but only when the client is the macOS WebDAV implementation). Simply instantiate and run a #import "GCDWebDAVServer.h"
@interface AppDelegate : NSObject <UIApplicationDelegate> {
GCDWebDAVServer* _davServer;
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
_davServer = [[GCDWebDAVServer alloc] initWithUploadDirectory:documentsPath];
[_davServer start];
NSLog(@"Visit %@ in your WebDAV client", _davServer.serverURL);
return YES;
}
@end Serving a Static WebsiteGCDWebServer includes a built-in handler that can recursively serve a directory (it also lets you control how the "Cache-Control" header should be set): macOS version (command line tool): #import "GCDWebServer.h"
int main(int argc, const char* argv[]) {
@autoreleasepool {
GCDWebServer* webServer = [[GCDWebServer alloc] init];
[webServer addGETHandlerForBasePath:@"/" directoryPath:NSHomeDirectory() indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
[webServer runWithPort:8080];
}
return 0;
} Using GCDWebServerYou start by creating an instance of the Then you add one or more "handlers" to the server: each handler gets a chance to handle an incoming web request and provide a response. Handlers are called in a LIFO queue, so the latest added handler overrides any previously added ones. Finally you start the server on a given port. Understanding GCDWebServer's ArchitectureGCDWebServer's architecture consists of only 4 core classes:
Implementing HandlersGCDWebServer relies on "handlers" to process incoming web requests and generating responses. Handlers are implemented with GCD blocks which makes it very easy to provide your own. However, they are executed on arbitrary threads within GCD so special attention must be paid to thread-safety and re-entrancy. Handlers require 2 GCD blocks:
Note that most methods on Asynchronous HTTP ResponsesNew in GCDWebServer 3.0 is the ability to process HTTP requests asynchronously i.e. add handlers to the server which generate their (Synchronous version) The handler blocks while generating the HTTP response: [webServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"];
return response;
}]; (Asynchronous version) The handler returns immediately and calls back GCDWebServer later with the generated HTTP response: [webServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
// Do some async operation like network access or file I/O (simulated here using dispatch_after())
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"];
completionBlock(response);
});
}]; (Advanced asynchronous version) The handler returns immediately a streamed HTTP response which itself generates its contents asynchronously: [webServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
NSMutableArray* contents = [NSMutableArray arrayWithObjects:@"<html><body><p>\n", @"Hello World!\n", @"</p></body></html>\n", nil]; // Fake data source we are reading from
GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:@"text/html" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) {
// Simulate a delay reading from the fake data source
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString* string = contents.firstObject;
if (string) {
[contents removeObjectAtIndex:0];
completionBlock([string dataUsingEncoding:NSUTF8StringEncoding], nil); // Generate the 2nd part of the stream data
} else {
completionBlock([NSData data], nil); // Must pass an empty NSData to signal the end of the stream
}
});
}];
return response;
}]; Note that you can even combine both the asynchronous and advanced asynchronous versions to return asynchronously an asynchronous HTTP response! GCDWebServer & Background Mode for iOS AppsWhen doing networking operations in iOS apps, you must handle carefully what happens when iOS puts the app in the background. Typically you must stop any network servers while the app is in the background and restart them when the app comes back to the foreground. This can become quite complex considering servers might have ongoing connections when they need to be stopped. Fortunately, GCDWebServer does all of this automatically for you:
HTTP connections are often initiated in batches (or bursts), for instance when loading a web page with multiple resources. This makes it difficult to accurately detect when the very last HTTP connection has been closed: it's possible 2 consecutive HTTP connections part of the same batch would be separated by a small delay instead of overlapping. It would be bad for the client if GCDWebServer suspended itself right in between. The Logging in GCDWebServerBoth for debugging and informational purpose, GCDWebServer logs messages extensively whenever something happens. Furthermore, when building GCDWebServer in "Debug" mode versus "Release" mode, it logs even more information but also performs a number of internal consistency checks. To enable this behavior, define the preprocessor constant By default, all messages logged by GCDWebServer are sent to its built-in logging facility, which simply outputs to GCDWebServer has automatic support for XLFacility (by the same author as GCDWebServer and also open-source): if it is in the same Xcode project, GCDWebServer should use it automatically instead of the built-in logging facility (see GCDWebServerPrivate.h for the implementation details). It's also possible to use a custom logging facility - see GCDWebServer.h for more information. Advanced Example 1: Implementing HTTP RedirectsHere's an example handler that redirects "/" to "/index.html" using the convenience method on [self addHandlerForMethod:@"GET"
path:@"/"
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
return [GCDWebServerResponse responseWithRedirect:[NSURL URLWithString:@"index.html" relativeToURL:request.URL]
permanent:NO];
}]; Advanced Example 2: Implementing FormsTo implement an HTTP form, you need a pair of handlers:
[webServer addHandlerForMethod:@"GET"
path:@"/"
requestClass:[GCDWebServerRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
NSString* html = @" \
<html><body> \
<form name=\"input\" action=\"/\" method=\"post\" enctype=\"application/x-www-form-urlencoded\"> \
Value: <input type=\"text\" name=\"value\"> \
<input type=\"submit\" value=\"Submit\"> \
</form> \
</body></html> \
";
return [GCDWebServerDataResponse responseWithHTML:html];
}];
[webServer addHandlerForMethod:@"POST"
path:@"/"
requestClass:[GCDWebServerURLEncodedFormRequest class]
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
NSString* value = [[(GCDWebServerURLEncodedFormRequest*)request arguments] objectForKey:@"value"];
NSString* html = [NSString stringWithFormat:@"<html><body><p>%@</p></body></html>", value];
return [GCDWebServerDataResponse responseWithHTML:html];
}]; Advanced Example 3: Serving a Dynamic WebsiteGCDWebServer provides an extension to the Assuming you have a website directory in your app containing HTML template files along with the corresponding CSS, scripts and images, it's pretty easy to turn it into a dynamic website: // Get the path to the website directory
NSString* websitePath = [[NSBundle mainBundle] pathForResource:@"Website" ofType:nil];
// Add a default handler to serve static files (i.e. anything other than HTML files)
[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
全部评论
专题导读
上一篇:usnistgov/macos_security: macOS Security Compliance Project发布时间:2022-08-18下一篇:novastone-media/MQTT-Client-Framework: iOS, macOS, tvOS native ObjectiveC MQTT C ...发布时间:2022-08-18热门推荐
热门话题
阅读排行榜
|
请发表评论