Go to file
Pierre-Olivier Latour eb8b27d8b3 Update README.md
2012-12-29 23:12:22 -08:00
CGDWebServer Initial import 2012-12-29 22:23:49 -08:00
GCDWebServer.xcodeproj Initial import 2012-12-29 22:23:49 -08:00
.gitignore Initial commit 2012-12-29 10:22:35 -08:00
LICENSE Create LICENSE 2012-12-29 10:53:27 -08:00
main.m Added more test cases 2012-12-29 22:44:36 -08:00
README.md Update README.md 2012-12-29 23:12:22 -08:00

GCDWebServer

A lightweight GCD based HTTP 1.1 server for Mac & iOS apps written from scratch with the following goals in mind:

  • Entirely built on Grand Central Dispatch for best performance and no-hassle multithreading
  • Well designed API for easy integration and customization
  • Minimal number of source files and no dependencies on third-party source code
  • Support for streaming large HTTP bodies for requests and responses to minimize memory usage
  • Built-in parser for web forms submitted using "application/x-www-form-urlencoded" or "multipart/form-data"
  • Available under a friendly New BSD License

What's not supported (yet?):

  • Keep-alive connections
  • Authentication
  • HTTPS
  • Web forms submitted using "multipart/mixed"

Requirements:

  • OS X 10.7 or later
  • iOS 5.0 or later

Hello World

A simple HTTP server that runs on port 8080 and returns a "Hello World" HTML page to any request:

#import "GCDWebServer.h"

int main(int argc, const char* argv[]) {
  @autoreleasepool {
    
    // Create server and add default handler
    GCDWebServer* webServer = [[GCDWebServer alloc] init];
    [webServer addDefaultHandlerForMethod:@"GET"
                             requestClass:[GCDWebServerRequest class]
                             processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
      
      return [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"];
      
    }];
    
    // Run server on port 8080 until SIGINT received
    [webServer runWithPort:8080];
    
    // Destroy server
    [webServer release];
    
  }
  return 0;
}

Serving a Static Website

GCDWebServer includes a built-in handler that can recursively serve a directory (it also lets you control how the "Cache-Control" header should be set):

#import "GCDWebServer.h"

int main(int argc, const char* argv[]) {
  @autoreleasepool {
    
    GCDWebServer* webServer = [[GCDWebServer alloc] init];
    [webServer addHandlerForBasePath:@"/" localPath:NSHomeDirectory() indexFilename:nil cacheAge:3600];
    [webServer runWithPort:8080];
    [webServer release];
    
  }
  return 0;
}

How it Works

TBD

Advanced Example 1: Implementing HTTP Redirects

Here's an example handler that redirects "/" to "/index.html" using the convenience method on 'GCDWebServerResponse' (it sets the HTTP status code and 'Location' header automatically):

[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 Forms

To implement an HTTP form, you need a pair of handlers:

  • The GET handler does not expect any body in the HTTP request and therefore uses the 'GCDWebServerRequest' class. The handler generates a response containing a simple HTML form.
  • The POST handler expects the form values to be in the body of the HTTP request and percent-encoded. Fortunately, GCDWebServer provides the request class 'GCDWebServerURLEncodedFormRequest' which can automatically parse such bodies. The handler simply echoes back the value from the user submitted form.
[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];
  
}];