mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-04-24 00:00:04 +08:00
Update README.md
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
GCDWebServer
|
||||
============
|
||||
Overview
|
||||
========
|
||||
|
||||
GCDWebServer is a lightweight GCD based HTTP 1.1 server for Mac & iOS apps written from scratch with the following goals in mind:
|
||||
* Entirely built with an event-driven design using [Grand Central Dispatch](http://en.wikipedia.org/wiki/Grand_Central_Dispatch) for maximum performance and concurrency
|
||||
* Well designed API for easy integration
|
||||
* Handle URL requests with simple GCD blocks instead of subclasses or delegates
|
||||
* Well designed API for easy integration and customization
|
||||
* 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"
|
||||
* Minimal number of source files and no dependencies on third-party source code
|
||||
@@ -25,7 +24,7 @@ Requirements:
|
||||
Hello World
|
||||
===========
|
||||
|
||||
A simple HTTP server that runs on port 8080 and returns a "Hello World" HTML page to any request:
|
||||
This code snippet shows how to implement a custom HTTP server that runs on port 8080 and returns a "Hello World" HTML page to any request — Because GCDWebServer uses GCD blocks to handle requests, no subclassing or delegates are needed:
|
||||
|
||||
```objectivec
|
||||
#import "GCDWebServer.h"
|
||||
@@ -33,8 +32,10 @@ A simple HTTP server that runs on port 8080 and returns a "Hello World" HTML pag
|
||||
int main(int argc, const char* argv[]) {
|
||||
@autoreleasepool {
|
||||
|
||||
// Create server and add default handler
|
||||
// Create server
|
||||
GCDWebServer* webServer = [[GCDWebServer alloc] init];
|
||||
|
||||
// Add a handler to respond to requests on any URL
|
||||
[webServer addDefaultHandlerForMethod:@"GET"
|
||||
requestClass:[GCDWebServerRequest class]
|
||||
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||
@@ -43,7 +44,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
}];
|
||||
|
||||
// Run server on port 8080 until SIGINT received
|
||||
// Use convenience method that runs server on port 8080 until SIGINT received
|
||||
[webServer runWithPort:8080];
|
||||
|
||||
// Destroy server
|
||||
@@ -84,16 +85,25 @@ Then you add one or more "handlers" to the server: each handler gets a chance to
|
||||
|
||||
Finally you start the server on a given port. Note that even if built on GCD, GCDWebServer still requires a runloop to be around (by default the main thread runloop is used). This is because there is no CGD API at this point to handle listening sockets, so it must be done using CFSocket which requires a runloop. However, the runloop is only used to accept the connection: immediately afterwards, the connection handling is dispatched to GCD queues.
|
||||
|
||||
Understanding GCDWebServer Architecture
|
||||
=======================================
|
||||
|
||||
GCDWebServer is made of only 4 core classes:
|
||||
* 'GCDWebServer' manages the socket that listens for new HTTP connections and the list of handlers used by the server.
|
||||
* 'GCDWebServerConnection' is instantiated by 'GCDWebServer' to handle each new HTTP connection. Each instance stays alive until the connection is closed. You cannot use this class directly, but it is exposed so you can subclass it to override some hooks.
|
||||
* 'GCDWebServerRequest' is created by the 'GCDWebServerConnection' instance after HTTP headers have been received. It wraps the request and handles the HTTP body if any. GCDWebServer comes with several subclasses of 'GCDWebServerRequest' to handle common cases like storing the body in memory or stream it to a file on disk. See [GCDWebServerRequest.h](GCDWebServer/blob/master/CGDWebServer/GCDWebServerRequest.h) for the full list.
|
||||
* 'GCDWebServerResponse' is created by the request handler and wraps the response HTTP headers and optional body. GCDWebServer provides several subclasses of 'GCDWebServerResponse' to handle common cases like HTML text in memory or streaming a file from disk. See [GCDWebServerResponse.h](GCDWebServer/blob/master/CGDWebServer/GCDWebServerResponse.h) for the full list.
|
||||
|
||||
Implementing Handlers
|
||||
=====================
|
||||
|
||||
GCDWebServer 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 owns. However, they are executed on arbitrary threads within GCD so special attention must be paid to thread-safety.
|
||||
GCDWebServer 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 owns. 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:
|
||||
* The 'GCDWebServerMatchBlock' is called on every handler added to the 'GCDWebServer' instance whenever a web request has started (i.e. HTTP headers have been received). It is passed the basic info for the web request (HTTP method, URL, headers...) and must decide if it wants to handle it or not. If yes, it must return a 'GCDWebServerRequest' instance which will be used to read (and optionally parse) the web request HTTP body. Otherwise, it simply returns nil. GCDWebServer provides several subclasses of 'GCDWebServerRequest' to handle common cases like storing the body in memory or to a file on disk. See [GCDWebServerRequest.h](GCDWebServer/blob/master/CGDWebServer/GCDWebServerRequest.h) for the full list.
|
||||
* The 'GCDWebServerProcessBlock' is called after the web request has been fully received and is passed the 'GCDWebServerRequest' instance created at the previous step. It must return a 'GCDWebServerResponse' instance which will be used to send the reponse HTTP headers and body. GCDWebServer provides several subclasses of 'GCDWebServerResponse' to handle common cases like HTML text in memory or streaming a file from disk. See [GCDWebServerResponse.h](GCDWebServer/blob/master/CGDWebServer/GCDWebServerResponse.h) for the full list.
|
||||
* The 'GCDWebServerMatchBlock' is called on every handler added to the 'GCDWebServer' instance whenever a web request has started (i.e. HTTP headers have been received). It is passed the basic info for the web request (HTTP method, URL, headers...) and must decide if it wants to handle it or not. If yes, it must return a 'GCDWebServerRequest' instance (see above). Otherwise, it simply returns nil.
|
||||
* The 'GCDWebServerProcessBlock' is called after the web request has been fully received and is passed the 'GCDWebServerRequest' instance created at the previous step. It must return a 'GCDWebServerResponse' instance (see above) or nil on error.
|
||||
|
||||
Note that most methods on 'GCDWebServer' to add handlers only take a 'GCDWebServerProcessBlock' as they already provide a built-in 'GCDWebServerMatchBlock' e.g. to match a URL path with a Regex.
|
||||
Note that most methods on 'GCDWebServer' to add handlers only require the 'GCDWebServerProcessBlock' as they already provide a built-in 'GCDWebServerMatchBlock' e.g. to match a URL path with a Regex.
|
||||
|
||||
Advanced Example 1: Implementing HTTP Redirects
|
||||
===============================================
|
||||
|
||||
Reference in New Issue
Block a user