晚上一点多是什么时辰| 7月去青海带什么衣服| 20度穿什么| 元神是什么意思| 送镜子代表什么意思| 嘌呤高会引起什么症状| 打强心针意味着什么| 什么的沙滩| 大什么大| 口扫是什么| 吃什么推迟月经| 采是什么意思| 蛊惑什么意思| 鸡蛋加什么吃壮阳持久| 口角炎缺乏什么维生素| 月和什么有关| 2005年什么年| 吃什么去湿气最快最有效| 肾气不固吃什么中成药| 长红疹是什么原因| 专长是什么意思| 什么病会晕倒| 锐字五行属什么| 为什么一同房就出血| 伏藏是什么意思| 单纯疱疹吃什么药| 和女生聊天聊什么| 李克勤属什么生肖| 马齿苋有什么作用| 清福是什么意思| 高血压看什么科室| 煎牛排用什么锅| 吃完饭胃疼是什么原因| 馐什么意思| 乳头有点痛什么原因| 血脂看什么指标| 凌霄什么意思| 三观不正是什么意思| 榴莲壳有什么作用| 540是什么意思| 让平是什么意思| 孕吐吃什么药| 吃甲钴胺有什么副作用| 为什么会得白癜风| 慈禧和光绪是什么关系| 静谧什么意思| 来大姨妈适合吃什么水果| 拉屎拉出血是什么原因| 证监会是干什么的| 头自动摇摆是什么原因| 离职什么意思| 蛇盘疮长什么样| 4月29日是什么星座| 男人地盘是什么生肖| 颈椎钙化是什么意思| 阴茎长水泡是什么原因| 为什么庙里不让孕妇去| 以逸待劳是什么意思| 梦到女朋友出轨是什么意思| 我们都没错只是不适合是什么歌| 子宫内膜9mm意味着什么| 丝瓜水敷脸有什么作用| 肺结节吃什么食物散结节最快| 万能血型是什么血型| 吃紫菜有什么好处和坏处| 椎管狭窄是什么意思| 卵巢钙化灶是什么意思| 7月4日是什么星座| 就请你给我多一点点时间是什么歌| 什么是射线| 为什么遗精| 什么是膜性肾病| 考试前吃什么能让大脑发挥最佳| 脸上白了一小块是什么原因| 18号来月经什么时候是排卵期| 双鱼座的幸运色是什么| 什么是辅酶q10| 小蛇吃什么| 7月18号是什么日子| 肚脐下三寸是什么位置| 爱情和面包是什么意思| 粑粑黑色是什么原因| 嗓子有异物感堵得慌吃什么药| 嘴唇起皮是什么原因| 炜字五行属什么| 一九三七年属什么生肖| 凌晨五点是什么时辰| 梦见被蛇咬了是什么意思| 胃泌素释放肽前体高是什么原因| 甲状腺肿是什么意思| 湿热体质适合喝什么茶| 什么都不放的冬瓜清汤| 经血是什么血| pda是什么意思| 处女女和什么星座最配| 生理曲度变直什么意思| 性有什么好处和坏处| 是什么时候| 燃气泄露是什么味道| 节操什么意思| 什么是白内障| mixblu是什么牌子| pv是什么材质| 蚊子讨厌什么气味| 什么叫有氧运动| 木是什么生肖| 静脉曲张吃什么药好| 为什么会一直放屁| 稳是什么意思| 宫颈出血是什么症状| 料酒是什么| 产前诊断是检查什么| c肽高说明什么| 西葫芦是什么| 两手发麻是什么原因| 什么是靶向疗法| 九一年属什么生肖| 什么头什么发| 子宫内膜增厚是什么意思| 大便排不出来是什么原因| 做恐怖的梦预示着什么| 770是什么意思| 古驰属于什么档次| 信手拈来是什么意思| 关晓彤属什么生肖| 甲醛中毒什么症状| 风对什么| 男性湿热吃什么药最好| 4.11是什么星座| 隔离霜和粉底液有什么区别| 幼儿急疹吃什么药| 看见乌鸦有什么预兆| act是什么意思| 西红柿吃多了有什么坏处| 术前八项检查是什么| 脑供血不足什么原因引起的| 咽炎雾化用什么药最好| 农历9月11日是什么星座| hd什么意思| 什么情况下会怀孕| 钾低吃什么药| 6月20是什么星座| 裙摆是什么| 婴儿口臭是什么原因引起的| 牵强是什么意思| herb是什么意思| 今年温度为什么这么高| 玉簟秋是什么意思| 古代内衣叫什么| 颈椎骨质增生吃什么药效果好| fe是什么元素| 耐药是什么意思| 舌头烂了是什么原因| 湘字五行属什么的| 私事是什么意思| 老是放屁什么原因| 印度人是什么人种| 为什么做完爱下面会疼| cooc香水是什么牌子的| 胡牌是什么意思| 白蛋白低是什么意思| 丁丁是什么意思| 肌膜炎是什么原因造成的| 躺枪是什么意思| 男人早泄吃什么药最好| 同学生日送什么礼物| ddg是什么意思| 拉不出大便吃什么药| flour是什么意思| 长期吃二甲双胍有什么副作用| 牛吃什么| 什么是多动症| 夏的五行属什么| 什么年马月| 吃什么可以解决便秘| 绀是什么意思| 随礼钱有什么讲究| 杏鲍菇不能和什么一起吃| 来月经喝什么茶好| 退烧吃什么药好| 水中毒是什么| 脚底疼是什么原因引起的| 厘米为什么叫公分| 啤酒鸭可以放什么配菜| 提是什么生肖| 心脏不舒服看什么科室| 赤子之心什么意思| 百香果什么季节成熟| 吃瓜是什么意思| 吸毒什么感觉| 6.29什么星座| 太平天国为什么会失败| 红枣和枸杞一起泡水喝有什么作用| 梦见杀牛是什么预兆| 月经每个月都推迟是什么原因| 捡帽子有什么说法吗| 肺慢性炎症是什么意思| 意大利买什么包便宜| 三伏天从什么时候开始| 雪花飘飘北风萧萧是什么歌| 柯字五行属什么| 什么是纯净水| 肾疼挂什么科| jordan是什么意思| 彩金是什么| 三本是什么| 喜用神是什么意思| 湿热重吃什么药| 什么人不能吃鸡蛋| 花开花落不见你回头是什么歌| rhubarb是什么意思| 吃什么降血脂| 优甲乐是治什么病的| 失联是什么意思| 朗姆酒兑什么好喝| 吃什么能养肝护肝| 脸上长藓用什么药| 好好的什么意思| 正方体体积公式是什么| 登基是什么意思| 气血不足什么引起的| 什么是交感神经| 忖量是什么意思| 灰色是什么颜色调出来的| 入珠是什么| 满清十大酷刑是什么| 做b超需要挂什么科| 内痔用什么药治最好效果最快| 中耳炎是什么| 梦见洪水是什么意思| 王字旁的字跟什么有关| 小卡是什么| 孕吐反应强烈说明什么| 肝脏排毒吃什么最好| 可见原始心管搏动是什么意思| 摇呼啦圈有什么好处| 扁桃体发炎是什么症状| 什么河没有水| 吃枸杞有什么功效| 验光是什么意思| 为什么穿堂风最伤人| 间质性改变是什么意思| 酸是什么意思| 前门大街有什么好玩的| 活性炭是什么| 文笔是什么意思| 令公子车祸隐藏了什么| 梦见和别人结婚是什么意思| 伏天吃羊肉有什么好处| 为什么感冒会流鼻涕| 肺结节什么症状| 装模作样是什么生肖| 男人嘴小代表什么意思| 心律不齐是什么意思| 屈膝是什么意思| 进门见什么好| 发冷发热是什么原因| 胆囊粗糙是什么意思| 1975属什么生肖| 什么地问填词语| 嘴唇发乌是什么原因| 驻唱是什么意思| 可见一什么| 脉压是什么意思| 百度
Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.
/ GCDWebServer Public archive

The #1 HTTP server for iOS, macOS & tvOS (also includes web based uploader & WebDAV server)

License

Notifications You must be signed in to change notification settings

swisspol/GCDWebServer

Repository files navigation

Overview

Build Status Version Platform License

GCDWebServer 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:

  • Elegant and easy to use architecture with only 4 core classes: server, connection, request and response (see "Understanding GCDWebServer's Architecture" below)
  • Well designed API with fully documented headers for easy integration and customization
  • Entirely built with an event-driven design using Grand Central Dispatch for best performance and concurrency
  • No dependencies on third-party source code
  • Available under a friendly New BSD License

Extra built-in features:

  • Allow implementation of fully asynchronous handlers of incoming HTTP requests
  • Minimize memory usage with disk streaming of large HTTP request or response bodies
  • Parser for web forms submitted using "application/x-www-form-urlencoded" or "multipart/form-data" encodings (including file uploads)
  • JSON parsing and serialization for request and response HTTP bodies
  • Chunked transfer encoding for request and response HTTP bodies
  • HTTP compression with gzip for request and response HTTP bodies
  • HTTP range support for requests of local files
  • Basic and Digest Access authentications for password protection
  • Automatically handle transitions between foreground, background and suspended modes in iOS apps
  • Full support for both IPv4 and IPv6
  • NAT port mapping (IPv4 only)

Included extensions:

  • GCDWebUploader: subclass of GCDWebServer that implements an interface for uploading and downloading files using a web browser
  • GCDWebDAVServer: subclass of GCDWebServer that implements a class 1 WebDAV server (with partial class 2 support for macOS Finder)

What's not supported (but not really required from an embedded HTTP server):

  • Keep-alive connections
  • HTTPS

Requirements:

  • macOS 10.7 or later (x86_64)
  • iOS 8.0 or later (armv7, armv7s or arm64)
  • tvOS 9.0 or later (arm64)
  • ARC memory management only (if you need MRC support use GCDWebServer 3.1 or earlier)

Getting Started

Download 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 libz (via Target > Build Phases > Link Binary With Libraries) and add $(SDKROOT)/usr/include/libxml2 to your header search paths (via Target > Build Settings > HEADER_SEARCH_PATHS).

Alternatively, you can install GCDWebServer using CocoaPods by simply adding this line to your Podfile:

pod "GCDWebServer", "~> 3.0"

If you want to use GCDWebUploader, use this line instead:

pod "GCDWebServer/WebUploader", "~> 3.0"

Or this line for GCDWebDAVServer:

pod "GCDWebServer/WebDAV", "~> 3.0"

And finally run $ pod install.

You can also use Carthage by adding this line to your Cartfile (3.2.5 is the first release with Carthage support):

github "swisspol/GCDWebServer" ~> 3.2.5

Then run $ carthage update and add the generated frameworks to your Xcode projects (see Carthage instructions).

Help & Support

For help with using GCDWebServer, it's best to ask your question on Stack Overflow with the gcdwebserver tag. For bug reports and enhancement requests you can use issues in this project.

Be sure to read this entire README first though!

Hello World

These 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 libz shared system library to the Xcode target for your app.

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 Apps

GCDWebUploader is a subclass of GCDWebServer that provides a ready-to-use HTML 5 file uploader & downloader. This lets users upload, download, delete files and create directories from a directory inside your iOS app's sandbox using a clean user interface in their web browser.

Simply instantiate and run a GCDWebUploader instance then visit http://{YOUR-IOS-DEVICE-IP-ADDRESS}/ from your web browser:

#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 Apps

GCDWebDAVServer is a subclass of GCDWebServer that provides a class 1 compliant WebDAV server. This lets users upload, download, delete files and create directories from a directory inside your iOS app's sandbox using any WebDAV client like Transmit (Mac), ForkLift (Mac) or CyberDuck (Mac / Windows).

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 GCDWebDAVServer instance then connect to http://{YOUR-IOS-DEVICE-IP-ADDRESS}/ using a WebDAV client:

#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 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):

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 GCDWebServer

You start by creating an instance of the GCDWebServer class. Note that you can have multiple web servers running in the same app as long as they listen on different ports.

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 Architecture

GCDWebServer's architecture consists 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.
  • GCDWebServerResponse is created by the request handler and wraps the response HTTP headers and optional body. GCDWebServer comes with several subclasses of GCDWebServerResponse to handle common cases like HTML text in memory or streaming a file from disk.

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

  • 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 new GCDWebServerRequest instance (see above) created with this info. Otherwise, it simply returns nil.
  • The GCDWebServerProcessBlock or GCDWebServerAsyncProcessBlock is called after the web request has been fully received and is passed the GCDWebServerRequest instance created at the previous step. It must return synchronously (if using GCDWebServerProcessBlock) or asynchronously (if using GCDWebServerAsyncProcessBlock) a GCDWebServerResponse instance (see above) or nil on error, which will result in a 500 HTTP status code returned to the client. It's however recommended to return an instance of GCDWebServerErrorResponse on error so more useful information can be returned to the client.

Note that most methods on GCDWebServer to add handlers only require the GCDWebServerProcessBlock or GCDWebServerAsyncProcessBlock as they already provide a built-in GCDWebServerMatchBlock e.g. to match a URL path with a Regex.

Asynchronous HTTP Responses

New in GCDWebServer 3.0 is the ability to process HTTP requests asynchronously i.e. add handlers to the server which generate their GCDWebServerResponse asynchronously. This is achieved by adding handlers that use a GCDWebServerAsyncProcessBlock instead of a GCDWebServerProcessBlock. Here's an example:

(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 Apps

When 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:

  • GCDWebServer begins a background task whenever the first HTTP connection is opened and ends it only when the last one is closed. This prevents iOS from suspending the app after it goes in the background, which would immediately kill HTTP connections to the client.
  • While the app is in the background, as long as new HTTP connections keep being initiated, the background task will continue to exist and iOS will not suspend the app for up to 10 minutes (unless under sudden and unexpected memory pressure).
  • If the app is still in the background when the last HTTP connection is closed, GCDWebServer will suspend itself and stop accepting new connections as if you had called -stop (this behavior can be disabled with the GCDWebServerOption_AutomaticallySuspendInBackground option).
  • If the app goes in the background while no HTTP connections are opened, GCDWebServer will immediately suspend itself and stop accepting new connections as if you had called -stop (this behavior can be disabled with the GCDWebServerOption_AutomaticallySuspendInBackground option).
  • If the app comes back to the foreground and GCDWebServer had been suspended, it will automatically resume itself and start accepting again new HTTP connections as if you had called -start.

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 GCDWebServerOption_ConnectedStateCoalescingInterval option solves this problem elegantly by forcing GCDWebServer to wait some extra delay before performing any action after the last HTTP connection has been closed, just in case a new HTTP connection is initiated within this delay.

Logging in GCDWebServer

Both 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 DEBUG=1 when compiling GCDWebServer. In Xcode target settings, this can be done by adding DEBUG=1 to the build setting GCC_PREPROCESSOR_DEFINITIONS when building in "Debug" configuration. Finally, you can also control the logging verbosity at run time by calling +[GCDWebServer setLogLevel:].

By default, all messages logged by GCDWebServer are sent to its built-in logging facility, which simply outputs to stderr (assuming a terminal type device is connected). In order to better integrate with the rest of your app or because of the amount of information logged, you might want to use another logging facility.

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 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];
  
}];

Advanced Example 3: Serving a Dynamic Website

GCDWebServer provides an extension to the GCDWebServerDataResponse class that can return HTML content generated from a template and a set of variables (using the format %variable%). It is a very basic template system and is really intended as a starting point to building more advanced template systems by subclassing GCDWebServerResponse.

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"
                pathRegex:@"/.*\.html"
             requestClass:[GCDWebServerRequest class]
             processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
    
    NSDictionary* variables = [NSDictionary dictionaryWithObjectsAndKeys:@"value", @"variable", nil];
    return [GCDWebServerDataResponse responseWithHTMLTemplate:[websitePath stringByAppendingPathComponent:request.path]
                                                    variables:variables];
    
}];

// Add an override handler to redirect "/" URL to "/index.html"
[self addHandlerForMethod:@"GET"
                     path:@"/"
             requestClass:[GCDWebServerRequest class]
             processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
    
    return [GCDWebServerResponse responseWithRedirect:[NSURL URLWithString:@"index.html" relativeToURL:request.URL]
                                            permanent:NO];
    
];

Final Example: File Downloads and Uploads From iOS App

GCDWebServer was originally written for the ComicFlow comic reader app for iPad. It allow users to connect to their iPad with their web browser over WiFi and then upload, download and organize comic files inside the app.

ComicFlow is entirely open-source and you can see how it uses GCDWebServer in the WebServer.h and WebServer.m files.

About

The #1 HTTP server for iOS, macOS & tvOS (also includes web based uploader & WebDAV server)

Resources

License

Stars

Watchers

Forks

Packages

No packages published
川崎病是什么原因引起的 九月24日是什么星座 忌作灶是什么意思 做梦梦到蛆是什么意思 护肝养肝吃什么药最好
王母娘娘叫什么名字 腿弯后面疼是什么原因 三个句号代表什么意思 为什么老被蚊子咬 药物流产最佳时间什么时候
干涉是什么意思 入睡困难吃什么药效果最好 双下肢静脉彩超主要检查什么 婊子代表什么生肖 深圳少年宫有什么好玩的
滴虫性阴炎有什么症状表现 雷达是什么 不怀孕是什么原因引起的 男人蛋疼是什么原因 血糖什么时候最高
三八是什么意思hcv8jop7ns7r.cn no医学上是什么意思hcv9jop6ns8r.cn 谷草谷丙高是什么原因hcv9jop0ns5r.cn 朝花夕拾什么意思shenchushe.com 魂牵梦萦的意思是什么hcv8jop3ns6r.cn
泡汤是什么意思hcv9jop2ns6r.cn 做梦梦见下大雨是什么意思hcv8jop2ns7r.cn 类风湿吃什么食物好clwhiglsz.com 腿水肿是什么原因引起的hcv7jop6ns8r.cn 月经期喝什么好hcv9jop2ns5r.cn
种植牙是什么意思jasonfriends.com 土字旁的字与什么有关hcv7jop4ns8r.cn 94年属什么hcv8jop5ns8r.cn 高压偏低有什么危害hcv9jop0ns1r.cn 3月5号是什么星座hcv9jop3ns8r.cn
梦见男朋友是什么意思inbungee.com 看淋巴挂什么科室hcv8jop5ns4r.cn 转氨酶高是什么原因引起的hkuteam.com 肾结石喝酒有什么影响hcv9jop4ns8r.cn 维酶素片搭配什么药治萎缩性胃炎hcv9jop5ns6r.cn
百度