mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-02-11 00:00:07 +08:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdfe6728ae | ||
|
|
b1ab7479b3 | ||
|
|
03a0ac32ee | ||
|
|
bd2c292cb6 | ||
|
|
e8b67264ab | ||
|
|
3d5fd0b828 | ||
|
|
9524d31b1b | ||
|
|
a3606d6027 | ||
|
|
00b2c38109 | ||
|
|
0a9d3105fc | ||
|
|
0f0a9840e4 | ||
|
|
047fdddb0e | ||
|
|
79d6075a84 | ||
|
|
594497d234 | ||
|
|
1f7c0366f0 | ||
|
|
fe472cdd54 | ||
|
|
9c33c83351 | ||
|
|
9719406303 | ||
|
|
0b8f7ff6ad | ||
|
|
71c08cff73 | ||
|
|
1a6786488a | ||
|
|
472c7855a7 | ||
|
|
2fdeb9581c | ||
|
|
c4310fcdf4 | ||
|
|
33645d3c6b | ||
|
|
3618dcac7e | ||
|
|
432e3826c9 | ||
|
|
4e31508195 | ||
|
|
628f6673b0 | ||
|
|
1944cd8a6e | ||
|
|
d2001e38ca | ||
|
|
18889793b7 | ||
|
|
14d538b0fb | ||
|
|
3b7198b4cc | ||
|
|
abb891334a | ||
|
|
059f5c8d01 | ||
|
|
9d9546bb6d | ||
|
|
2ff05b1aa0 | ||
|
|
bf2c9a170d | ||
|
|
15caa9cd20 | ||
|
|
32ba49ae34 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ xcuserdata
|
||||
project.xcworkspace
|
||||
|
||||
Tests/Payload
|
||||
Carthage/Build
|
||||
|
||||
48
Frameworks/GCDWebServers.h
Normal file
48
Frameworks/GCDWebServers.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (c) 2012-2014, Pierre-Olivier Latour
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* The name of Pierre-Olivier Latour may not be used to endorse
|
||||
or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// GCDWebServer
|
||||
#import <GCDWebServers/GCDWebServer.h>
|
||||
#import <GCDWebServers/GCDWebServerHTTPStatusCodes.h>
|
||||
#import <GCDWebServers/GCDWebServerRequest.h>
|
||||
#import <GCDWebServers/GCDWebServerErrorResponse.h>
|
||||
#import <GCDWebServers/GCDWebServerURLEncodedFormRequest.h>
|
||||
#import <GCDWebServers/GCDWebServerResponse.h>
|
||||
#import <GCDWebServers/GCDWebServerFileResponse.h>
|
||||
#import <GCDWebServers/GCDWebServerMultiPartFormRequest.h>
|
||||
#import <GCDWebServers/GCDWebServerStreamedResponse.h>
|
||||
#import <GCDWebServers/GCDWebServerConnection.h>
|
||||
#import <GCDWebServers/GCDWebServerDataRequest.h>
|
||||
#import <GCDWebServers/GCDWebServerDataResponse.h>
|
||||
#import <GCDWebServers/GCDWebServerFunctions.h>
|
||||
#import <GCDWebServers/GCDWebServerFileRequest.h>
|
||||
|
||||
// GCDWebUploader
|
||||
#import <GCDWebServers/GCDWebUploader.h>
|
||||
|
||||
// GCDWebDAVServer
|
||||
#import <GCDWebServers/GCDWebDAVServer.h>
|
||||
18
Frameworks/Info.plist
Normal file
18
Frameworks/Info.plist
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>net.pol-online.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebDAVServer requires ARC
|
||||
#endif
|
||||
|
||||
// WebDAV specifications: http://webdav.org/specs/rfc4918.html
|
||||
|
||||
// Requires "HEADER_SEARCH_PATHS = $(SDKROOT)/usr/include/libxml2" in Xcode build settings
|
||||
@@ -418,9 +422,6 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
|
||||
}
|
||||
if (!success) {
|
||||
NSString* string = [[NSString alloc] initWithData:request.data encoding:NSUTF8StringEncoding];
|
||||
#if !__has_feature(objc_arc)
|
||||
[string autorelease];
|
||||
#endif
|
||||
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Invalid DAV properties:\n%@", string];
|
||||
}
|
||||
} else {
|
||||
@@ -519,9 +520,6 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
|
||||
}
|
||||
if (!success) {
|
||||
NSString* string = [[NSString alloc] initWithData:request.data encoding:NSUTF8StringEncoding];
|
||||
#if !__has_feature(objc_arc)
|
||||
[string autorelease];
|
||||
#endif
|
||||
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Invalid DAV properties:\n%@", string];
|
||||
}
|
||||
|
||||
@@ -604,14 +602,12 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
|
||||
|
||||
@synthesize uploadDirectory=_uploadDirectory, allowedFileExtensions=_allowedExtensions, allowHiddenItems=_allowHidden;
|
||||
|
||||
@dynamic delegate;
|
||||
|
||||
- (instancetype)initWithUploadDirectory:(NSString*)path {
|
||||
if ((self = [super init])) {
|
||||
_uploadDirectory = [[path stringByStandardizingPath] copy];
|
||||
#if __has_feature(objc_arc)
|
||||
GCDWebDAVServer* __unsafe_unretained server = self;
|
||||
#else
|
||||
__block GCDWebDAVServer* server = self;
|
||||
#endif
|
||||
|
||||
// 9.1 PROPFIND method
|
||||
[self addDefaultHandlerForMethod:@"PROPFIND" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||
@@ -667,17 +663,6 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
|
||||
return self;
|
||||
}
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
|
||||
- (void)dealloc {
|
||||
[_uploadDirectory release];
|
||||
[_allowedExtensions release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@implementation GCDWebDAVServer (Subclassing)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'GCDWebServer'
|
||||
s.version = '3.1'
|
||||
s.version = '3.2.5'
|
||||
s.author = { 'Pierre-Olivier Latour' => 'info@pol-online.net' }
|
||||
s.license = { :type => 'BSD', :file => 'LICENSE' }
|
||||
s.homepage = 'https://github.com/swisspol/GCDWebServer'
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
CE54F3961AE84FCA003C110E /* PBXTargetDependency */,
|
||||
CE54F3941AE84FCA003C110E /* PBXTargetDependency */,
|
||||
E274F87D187E77E5009E0582 /* PBXTargetDependency */,
|
||||
E274F87B187E77E3009E0582 /* PBXTargetDependency */,
|
||||
);
|
||||
@@ -22,6 +24,84 @@
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
CEE28CF41AE0051F00F4023C /* GCDWebServers.h in Headers */ = {isa = PBXBuildFile; fileRef = CEE28CF31AE0051F00F4023C /* GCDWebServers.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D091AE006C200F4023C /* GCDWebServer.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1618F99C810095C089 /* GCDWebServer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D0A1AE006C300F4023C /* GCDWebServer.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1618F99C810095C089 /* GCDWebServer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D0B1AE006CC00F4023C /* GCDWebServer.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE1718F99C810095C089 /* GCDWebServer.m */; };
|
||||
CEE28D0C1AE006CD00F4023C /* GCDWebServer.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE1718F99C810095C089 /* GCDWebServer.m */; };
|
||||
CEE28D0D1AE006D700F4023C /* GCDWebServerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1818F99C810095C089 /* GCDWebServerConnection.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D0E1AE006D800F4023C /* GCDWebServerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1818F99C810095C089 /* GCDWebServerConnection.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D0F1AE006DE00F4023C /* GCDWebServerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE1918F99C810095C089 /* GCDWebServerConnection.m */; };
|
||||
CEE28D101AE006DF00F4023C /* GCDWebServerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE1918F99C810095C089 /* GCDWebServerConnection.m */; };
|
||||
CEE28D111AE006E200F4023C /* GCDWebServerFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1A18F99C810095C089 /* GCDWebServerFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D121AE006E300F4023C /* GCDWebServerFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1A18F99C810095C089 /* GCDWebServerFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D131AE006E900F4023C /* GCDWebServerFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE1B18F99C810095C089 /* GCDWebServerFunctions.m */; };
|
||||
CEE28D141AE006EA00F4023C /* GCDWebServerFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE1B18F99C810095C089 /* GCDWebServerFunctions.m */; };
|
||||
CEE28D151AE006ED00F4023C /* GCDWebServerHTTPStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1C18F99C810095C089 /* GCDWebServerHTTPStatusCodes.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D161AE006EE00F4023C /* GCDWebServerHTTPStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1C18F99C810095C089 /* GCDWebServerHTTPStatusCodes.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D191AE006FD00F4023C /* GCDWebServerRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1E18F99C810095C089 /* GCDWebServerRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D1A1AE006FD00F4023C /* GCDWebServerRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE1E18F99C810095C089 /* GCDWebServerRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D1B1AE0070300F4023C /* GCDWebServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE1F18F99C810095C089 /* GCDWebServerRequest.m */; };
|
||||
CEE28D1C1AE0070400F4023C /* GCDWebServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE1F18F99C810095C089 /* GCDWebServerRequest.m */; };
|
||||
CEE28D1D1AE0070600F4023C /* GCDWebServerResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2018F99C810095C089 /* GCDWebServerResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D1E1AE0070700F4023C /* GCDWebServerResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2018F99C810095C089 /* GCDWebServerResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D1F1AE0070D00F4023C /* GCDWebServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2118F99C810095C089 /* GCDWebServerResponse.m */; };
|
||||
CEE28D201AE0070E00F4023C /* GCDWebServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2118F99C810095C089 /* GCDWebServerResponse.m */; };
|
||||
CEE28D211AE0071200F4023C /* GCDWebServerDataRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2318F99C810095C089 /* GCDWebServerDataRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D221AE0071300F4023C /* GCDWebServerDataRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2318F99C810095C089 /* GCDWebServerDataRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D231AE0071A00F4023C /* GCDWebServerDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2418F99C810095C089 /* GCDWebServerDataRequest.m */; };
|
||||
CEE28D241AE0071B00F4023C /* GCDWebServerDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2418F99C810095C089 /* GCDWebServerDataRequest.m */; };
|
||||
CEE28D251AE0071E00F4023C /* GCDWebServerFileRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2518F99C810095C089 /* GCDWebServerFileRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D261AE0071E00F4023C /* GCDWebServerFileRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2518F99C810095C089 /* GCDWebServerFileRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D271AE0072400F4023C /* GCDWebServerFileRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2618F99C810095C089 /* GCDWebServerFileRequest.m */; };
|
||||
CEE28D281AE0072400F4023C /* GCDWebServerFileRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2618F99C810095C089 /* GCDWebServerFileRequest.m */; };
|
||||
CEE28D291AE0072800F4023C /* GCDWebServerMultiPartFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2718F99C810095C089 /* GCDWebServerMultiPartFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D2A1AE0072800F4023C /* GCDWebServerMultiPartFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2718F99C810095C089 /* GCDWebServerMultiPartFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D2B1AE0073000F4023C /* GCDWebServerMultiPartFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2818F99C810095C089 /* GCDWebServerMultiPartFormRequest.m */; };
|
||||
CEE28D2C1AE0073000F4023C /* GCDWebServerMultiPartFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2818F99C810095C089 /* GCDWebServerMultiPartFormRequest.m */; };
|
||||
CEE28D2D1AE0073300F4023C /* GCDWebServerURLEncodedFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2918F99C810095C089 /* GCDWebServerURLEncodedFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D2E1AE0073400F4023C /* GCDWebServerURLEncodedFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2918F99C810095C089 /* GCDWebServerURLEncodedFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D2F1AE0073C00F4023C /* GCDWebServerURLEncodedFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2A18F99C810095C089 /* GCDWebServerURLEncodedFormRequest.m */; };
|
||||
CEE28D301AE0073C00F4023C /* GCDWebServerURLEncodedFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2A18F99C810095C089 /* GCDWebServerURLEncodedFormRequest.m */; };
|
||||
CEE28D311AE0074200F4023C /* GCDWebServerDataResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2C18F99C810095C089 /* GCDWebServerDataResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D321AE0074200F4023C /* GCDWebServerDataResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2C18F99C810095C089 /* GCDWebServerDataResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D331AE0074900F4023C /* GCDWebServerDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2D18F99C810095C089 /* GCDWebServerDataResponse.m */; };
|
||||
CEE28D341AE0074A00F4023C /* GCDWebServerDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2D18F99C810095C089 /* GCDWebServerDataResponse.m */; };
|
||||
CEE28D351AE0074D00F4023C /* GCDWebServerErrorResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2E18F99C810095C089 /* GCDWebServerErrorResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D361AE0074E00F4023C /* GCDWebServerErrorResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE2E18F99C810095C089 /* GCDWebServerErrorResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D371AE0075900F4023C /* GCDWebServerErrorResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2F18F99C810095C089 /* GCDWebServerErrorResponse.m */; };
|
||||
CEE28D381AE0075900F4023C /* GCDWebServerErrorResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE2F18F99C810095C089 /* GCDWebServerErrorResponse.m */; };
|
||||
CEE28D391AE0075C00F4023C /* GCDWebServerFileResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE3018F99C810095C089 /* GCDWebServerFileResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D3A1AE0075D00F4023C /* GCDWebServerFileResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE3018F99C810095C089 /* GCDWebServerFileResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D3B1AE0076400F4023C /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE3118F99C810095C089 /* GCDWebServerFileResponse.m */; };
|
||||
CEE28D3C1AE0076400F4023C /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE3118F99C810095C089 /* GCDWebServerFileResponse.m */; };
|
||||
CEE28D3D1AE0076700F4023C /* GCDWebServerStreamedResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE3218F99C810095C089 /* GCDWebServerStreamedResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D3E1AE0076800F4023C /* GCDWebServerStreamedResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = E28BAE3218F99C810095C089 /* GCDWebServerStreamedResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D3F1AE0076E00F4023C /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE3318F99C810095C089 /* GCDWebServerStreamedResponse.m */; };
|
||||
CEE28D401AE0076F00F4023C /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = E28BAE3318F99C810095C089 /* GCDWebServerStreamedResponse.m */; };
|
||||
CEE28D411AE0077800F4023C /* GCDWebDAVServer.h in Headers */ = {isa = PBXBuildFile; fileRef = E2A0E80818F3432600C580B1 /* GCDWebDAVServer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D421AE0077800F4023C /* GCDWebDAVServer.h in Headers */ = {isa = PBXBuildFile; fileRef = E2A0E80818F3432600C580B1 /* GCDWebDAVServer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D431AE0077F00F4023C /* GCDWebDAVServer.m in Sources */ = {isa = PBXBuildFile; fileRef = E2A0E80918F3432600C580B1 /* GCDWebDAVServer.m */; };
|
||||
CEE28D441AE0078000F4023C /* GCDWebDAVServer.m in Sources */ = {isa = PBXBuildFile; fileRef = E2A0E80918F3432600C580B1 /* GCDWebDAVServer.m */; };
|
||||
CEE28D451AE0078600F4023C /* GCDWebUploader.bundle in Resources */ = {isa = PBXBuildFile; fileRef = E2BE850718E77ECA0061360B /* GCDWebUploader.bundle */; };
|
||||
CEE28D461AE0078600F4023C /* GCDWebUploader.bundle in Resources */ = {isa = PBXBuildFile; fileRef = E2BE850718E77ECA0061360B /* GCDWebUploader.bundle */; };
|
||||
CEE28D471AE0078A00F4023C /* GCDWebUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = E2BE850818E77ECA0061360B /* GCDWebUploader.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D481AE0078B00F4023C /* GCDWebUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = E2BE850818E77ECA0061360B /* GCDWebUploader.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D491AE0079100F4023C /* GCDWebUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = E2BE850918E77ECA0061360B /* GCDWebUploader.m */; };
|
||||
CEE28D4A1AE0079200F4023C /* GCDWebUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = E2BE850918E77ECA0061360B /* GCDWebUploader.m */; };
|
||||
CEE28D4C1AE0095600F4023C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE28D4B1AE0095600F4023C /* Foundation.framework */; };
|
||||
CEE28D4D1AE0096A00F4023C /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E2A0E80E18F35CA300C580B1 /* libxml2.dylib */; };
|
||||
CEE28D4E1AE0097400F4023C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E2B0D4A618F13495009A7927 /* libz.dylib */; };
|
||||
CEE28D4F1AE0097E00F4023C /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E208D148167B76B700500836 /* CFNetwork.framework */; };
|
||||
CEE28D501AE0098600F4023C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2BE851018E79DAF0061360B /* SystemConfiguration.framework */; };
|
||||
CEE28D511AE0098C00F4023C /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E208D1B2167BB17E00500836 /* CoreServices.framework */; };
|
||||
CEE28D521AE00A7A00F4023C /* GCDWebServers.h in Headers */ = {isa = PBXBuildFile; fileRef = CEE28CF31AE0051F00F4023C /* GCDWebServers.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CEE28D541AE00ADC00F4023C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE28D531AE00ADC00F4023C /* Foundation.framework */; };
|
||||
CEE28D571AE00AFE00F4023C /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E221129C1690B7BA0048D2B2 /* MobileCoreServices.framework */; };
|
||||
CEE28D591AE00AFE00F4023C /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E22112981690B7AA0048D2B2 /* CFNetwork.framework */; };
|
||||
CEE28D5A1AE00AFE00F4023C /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E2A0E80C18F35C9A00C580B1 /* libxml2.dylib */; };
|
||||
CEE28D5B1AE00AFE00F4023C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E2B0D4A818F134A8009A7927 /* libz.dylib */; };
|
||||
CEE28D6A1AE1ABAA00F4023C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEE28D691AE1ABAA00F4023C /* UIKit.framework */; };
|
||||
E208D149167B76B700500836 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E208D148167B76B700500836 /* CFNetwork.framework */; };
|
||||
E208D1B3167BB17E00500836 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E208D1B2167BB17E00500836 /* CoreServices.framework */; };
|
||||
E221128F1690B6470048D2B2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E221128E1690B6470048D2B2 /* main.m */; };
|
||||
@@ -70,6 +150,20 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
CE54F3931AE84FCA003C110E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = CEE28CD01AE004D800F4023C;
|
||||
remoteInfo = "GCDWebServers (Mac)";
|
||||
};
|
||||
CE54F3951AE84FCA003C110E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = CEE28CEE1AE0051F00F4023C;
|
||||
remoteInfo = "GCDWebServers (iOS)";
|
||||
};
|
||||
E274F87A187E77E3009E0582 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
@@ -101,6 +195,13 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
8DD76FB20486AB0100D96B5E /* GCDWebServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = GCDWebServer; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CEE28CD11AE004D800F4023C /* GCDWebServers.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GCDWebServers.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CEE28CEF1AE0051F00F4023C /* GCDWebServers.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GCDWebServers.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CEE28CF21AE0051F00F4023C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CEE28CF31AE0051F00F4023C /* GCDWebServers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GCDWebServers.h; sourceTree = "<group>"; };
|
||||
CEE28D4B1AE0095600F4023C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
CEE28D531AE00ADC00F4023C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
CEE28D691AE1ABAA00F4023C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
E208D148167B76B700500836 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
|
||||
E208D1B2167BB17E00500836 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
|
||||
E221125A1690B4DE0048D2B2 /* GCDWebServer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GCDWebServer.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -167,6 +268,32 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CEE28CCD1AE004D800F4023C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEE28D4C1AE0095600F4023C /* Foundation.framework in Frameworks */,
|
||||
CEE28D511AE0098C00F4023C /* CoreServices.framework in Frameworks */,
|
||||
CEE28D501AE0098600F4023C /* SystemConfiguration.framework in Frameworks */,
|
||||
CEE28D4F1AE0097E00F4023C /* CFNetwork.framework in Frameworks */,
|
||||
CEE28D4E1AE0097400F4023C /* libz.dylib in Frameworks */,
|
||||
CEE28D4D1AE0096A00F4023C /* libxml2.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CEE28CEB1AE0051F00F4023C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEE28D6A1AE1ABAA00F4023C /* UIKit.framework in Frameworks */,
|
||||
CEE28D541AE00ADC00F4023C /* Foundation.framework in Frameworks */,
|
||||
CEE28D571AE00AFE00F4023C /* MobileCoreServices.framework in Frameworks */,
|
||||
CEE28D591AE00AFE00F4023C /* CFNetwork.framework in Frameworks */,
|
||||
CEE28D5A1AE00AFE00F4023C /* libxml2.dylib in Frameworks */,
|
||||
CEE28D5B1AE00AFE00F4023C /* libz.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E22112571690B4DE0048D2B2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -190,6 +317,7 @@
|
||||
E28BAE1418F99C810095C089 /* GCDWebServer */,
|
||||
E2A0E80718F3432600C580B1 /* GCDWebDAVServer */,
|
||||
E2BE850618E77ECA0061360B /* GCDWebUploader */,
|
||||
CEE28D081AE0053E00F4023C /* Frameworks */,
|
||||
E221128D1690B6470048D2B2 /* Mac */,
|
||||
E22112901690B64F0048D2B2 /* iOS */,
|
||||
E282F1A7150FF0630004D7C0 /* Mac Frameworks and Libraries */,
|
||||
@@ -204,10 +332,21 @@
|
||||
children = (
|
||||
8DD76FB20486AB0100D96B5E /* GCDWebServer */,
|
||||
E221125A1690B4DE0048D2B2 /* GCDWebServer.app */,
|
||||
CEE28CD11AE004D800F4023C /* GCDWebServers.framework */,
|
||||
CEE28CEF1AE0051F00F4023C /* GCDWebServers.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CEE28D081AE0053E00F4023C /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CEE28CF31AE0051F00F4023C /* GCDWebServers.h */,
|
||||
CEE28CF21AE0051F00F4023C /* Info.plist */,
|
||||
);
|
||||
path = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E221128D1690B6470048D2B2 /* Mac */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -230,6 +369,8 @@
|
||||
E221129E1690B7CB0048D2B2 /* iOS Frameworks and Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CEE28D691AE1ABAA00F4023C /* UIKit.framework */,
|
||||
CEE28D531AE00ADC00F4023C /* Foundation.framework */,
|
||||
E221129C1690B7BA0048D2B2 /* MobileCoreServices.framework */,
|
||||
E221129A1690B7B10048D2B2 /* UIKit.framework */,
|
||||
E22112981690B7AA0048D2B2 /* CFNetwork.framework */,
|
||||
@@ -242,6 +383,7 @@
|
||||
E282F1A7150FF0630004D7C0 /* Mac Frameworks and Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CEE28D4B1AE0095600F4023C /* Foundation.framework */,
|
||||
E2BE851018E79DAF0061360B /* SystemConfiguration.framework */,
|
||||
E208D1B2167BB17E00500836 /* CoreServices.framework */,
|
||||
E208D148167B76B700500836 /* CFNetwork.framework */,
|
||||
@@ -331,6 +473,57 @@
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
CEE28CCE1AE004D800F4023C /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEE28D471AE0078A00F4023C /* GCDWebUploader.h in Headers */,
|
||||
CEE28D151AE006ED00F4023C /* GCDWebServerHTTPStatusCodes.h in Headers */,
|
||||
CEE28D191AE006FD00F4023C /* GCDWebServerRequest.h in Headers */,
|
||||
CEE28D091AE006C200F4023C /* GCDWebServer.h in Headers */,
|
||||
CEE28D351AE0074D00F4023C /* GCDWebServerErrorResponse.h in Headers */,
|
||||
CEE28D2D1AE0073300F4023C /* GCDWebServerURLEncodedFormRequest.h in Headers */,
|
||||
CEE28D411AE0077800F4023C /* GCDWebDAVServer.h in Headers */,
|
||||
CEE28D1D1AE0070600F4023C /* GCDWebServerResponse.h in Headers */,
|
||||
CEE28D391AE0075C00F4023C /* GCDWebServerFileResponse.h in Headers */,
|
||||
CEE28D291AE0072800F4023C /* GCDWebServerMultiPartFormRequest.h in Headers */,
|
||||
CEE28D3D1AE0076700F4023C /* GCDWebServerStreamedResponse.h in Headers */,
|
||||
CEE28D0D1AE006D700F4023C /* GCDWebServerConnection.h in Headers */,
|
||||
CEE28D211AE0071200F4023C /* GCDWebServerDataRequest.h in Headers */,
|
||||
CEE28D521AE00A7A00F4023C /* GCDWebServers.h in Headers */,
|
||||
CEE28D311AE0074200F4023C /* GCDWebServerDataResponse.h in Headers */,
|
||||
CEE28D111AE006E200F4023C /* GCDWebServerFunctions.h in Headers */,
|
||||
CEE28D251AE0071E00F4023C /* GCDWebServerFileRequest.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CEE28CEC1AE0051F00F4023C /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEE28CF41AE0051F00F4023C /* GCDWebServers.h in Headers */,
|
||||
CEE28D261AE0071E00F4023C /* GCDWebServerFileRequest.h in Headers */,
|
||||
CEE28D321AE0074200F4023C /* GCDWebServerDataResponse.h in Headers */,
|
||||
CEE28D121AE006E300F4023C /* GCDWebServerFunctions.h in Headers */,
|
||||
CEE28D481AE0078B00F4023C /* GCDWebUploader.h in Headers */,
|
||||
CEE28D221AE0071300F4023C /* GCDWebServerDataRequest.h in Headers */,
|
||||
CEE28D1A1AE006FD00F4023C /* GCDWebServerRequest.h in Headers */,
|
||||
CEE28D0E1AE006D800F4023C /* GCDWebServerConnection.h in Headers */,
|
||||
CEE28D421AE0077800F4023C /* GCDWebDAVServer.h in Headers */,
|
||||
CEE28D161AE006EE00F4023C /* GCDWebServerHTTPStatusCodes.h in Headers */,
|
||||
CEE28D3A1AE0075D00F4023C /* GCDWebServerFileResponse.h in Headers */,
|
||||
CEE28D2A1AE0072800F4023C /* GCDWebServerMultiPartFormRequest.h in Headers */,
|
||||
CEE28D3E1AE0076800F4023C /* GCDWebServerStreamedResponse.h in Headers */,
|
||||
CEE28D1E1AE0070700F4023C /* GCDWebServerResponse.h in Headers */,
|
||||
CEE28D2E1AE0073400F4023C /* GCDWebServerURLEncodedFormRequest.h in Headers */,
|
||||
CEE28D0A1AE006C300F4023C /* GCDWebServer.h in Headers */,
|
||||
CEE28D361AE0074E00F4023C /* GCDWebServerErrorResponse.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8DD76FA90486AB0100D96B5E /* GCDWebServer (Mac) */ = {
|
||||
isa = PBXNativeTarget;
|
||||
@@ -351,6 +544,42 @@
|
||||
productReference = 8DD76FB20486AB0100D96B5E /* GCDWebServer */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
CEE28CD01AE004D800F4023C /* GCDWebServers (Mac) */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = CEE28CE81AE004D800F4023C /* Build configuration list for PBXNativeTarget "GCDWebServers (Mac)" */;
|
||||
buildPhases = (
|
||||
CEE28CCC1AE004D800F4023C /* Sources */,
|
||||
CEE28CCD1AE004D800F4023C /* Frameworks */,
|
||||
CEE28CCE1AE004D800F4023C /* Headers */,
|
||||
CEE28CCF1AE004D800F4023C /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "GCDWebServers (Mac)";
|
||||
productName = GCDWebServers;
|
||||
productReference = CEE28CD11AE004D800F4023C /* GCDWebServers.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
CEE28CEE1AE0051F00F4023C /* GCDWebServers (iOS) */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = CEE28D021AE0052000F4023C /* Build configuration list for PBXNativeTarget "GCDWebServers (iOS)" */;
|
||||
buildPhases = (
|
||||
CEE28CEA1AE0051F00F4023C /* Sources */,
|
||||
CEE28CEB1AE0051F00F4023C /* Frameworks */,
|
||||
CEE28CEC1AE0051F00F4023C /* Headers */,
|
||||
CEE28CED1AE0051F00F4023C /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "GCDWebServers (iOS)";
|
||||
productName = GCDWebServers;
|
||||
productReference = CEE28CEF1AE0051F00F4023C /* GCDWebServers.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
E22112591690B4DE0048D2B2 /* GCDWebServer (iOS) */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E22112751690B4DF0048D2B2 /* Build configuration list for PBXNativeTarget "GCDWebServer (iOS)" */;
|
||||
@@ -374,7 +603,15 @@
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
LastUpgradeCheck = 0630;
|
||||
TargetAttributes = {
|
||||
CEE28CD01AE004D800F4023C = {
|
||||
CreatedOnToolsVersion = 6.3;
|
||||
};
|
||||
CEE28CEE1AE0051F00F4023C = {
|
||||
CreatedOnToolsVersion = 6.3;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "GCDWebServer" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
@@ -394,11 +631,29 @@
|
||||
E274F876187E77D8009E0582 /* Build All */,
|
||||
8DD76FA90486AB0100D96B5E /* GCDWebServer (Mac) */,
|
||||
E22112591690B4DE0048D2B2 /* GCDWebServer (iOS) */,
|
||||
CEE28CD01AE004D800F4023C /* GCDWebServers (Mac) */,
|
||||
CEE28CEE1AE0051F00F4023C /* GCDWebServers (iOS) */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
CEE28CCF1AE004D800F4023C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEE28D451AE0078600F4023C /* GCDWebUploader.bundle in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CEE28CED1AE0051F00F4023C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEE28D461AE0078600F4023C /* GCDWebUploader.bundle in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E2BE850418E77B730061360B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -422,8 +677,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "cd \"$BUILT_PRODUCTS_DIR\"\nrm -rf \"GCDWebUploader.bundle\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
shellScript = "if [ \"$CONFIGURATION\" == \"Debug\" ]; then\n cd \"$BUILT_PRODUCTS_DIR\"\n rm -rf \"GCDWebUploader.bundle\"\nfi\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
@@ -451,6 +705,50 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CEE28CCC1AE004D800F4023C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEE28D1B1AE0070300F4023C /* GCDWebServerRequest.m in Sources */,
|
||||
CEE28D2F1AE0073C00F4023C /* GCDWebServerURLEncodedFormRequest.m in Sources */,
|
||||
CEE28D0F1AE006DE00F4023C /* GCDWebServerConnection.m in Sources */,
|
||||
CEE28D231AE0071A00F4023C /* GCDWebServerDataRequest.m in Sources */,
|
||||
CEE28D2B1AE0073000F4023C /* GCDWebServerMultiPartFormRequest.m in Sources */,
|
||||
CEE28D271AE0072400F4023C /* GCDWebServerFileRequest.m in Sources */,
|
||||
CEE28D1F1AE0070D00F4023C /* GCDWebServerResponse.m in Sources */,
|
||||
CEE28D3B1AE0076400F4023C /* GCDWebServerFileResponse.m in Sources */,
|
||||
CEE28D3F1AE0076E00F4023C /* GCDWebServerStreamedResponse.m in Sources */,
|
||||
CEE28D331AE0074900F4023C /* GCDWebServerDataResponse.m in Sources */,
|
||||
CEE28D431AE0077F00F4023C /* GCDWebDAVServer.m in Sources */,
|
||||
CEE28D0B1AE006CC00F4023C /* GCDWebServer.m in Sources */,
|
||||
CEE28D131AE006E900F4023C /* GCDWebServerFunctions.m in Sources */,
|
||||
CEE28D371AE0075900F4023C /* GCDWebServerErrorResponse.m in Sources */,
|
||||
CEE28D491AE0079100F4023C /* GCDWebUploader.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CEE28CEA1AE0051F00F4023C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CEE28D1C1AE0070400F4023C /* GCDWebServerRequest.m in Sources */,
|
||||
CEE28D301AE0073C00F4023C /* GCDWebServerURLEncodedFormRequest.m in Sources */,
|
||||
CEE28D101AE006DF00F4023C /* GCDWebServerConnection.m in Sources */,
|
||||
CEE28D241AE0071B00F4023C /* GCDWebServerDataRequest.m in Sources */,
|
||||
CEE28D2C1AE0073000F4023C /* GCDWebServerMultiPartFormRequest.m in Sources */,
|
||||
CEE28D281AE0072400F4023C /* GCDWebServerFileRequest.m in Sources */,
|
||||
CEE28D201AE0070E00F4023C /* GCDWebServerResponse.m in Sources */,
|
||||
CEE28D3C1AE0076400F4023C /* GCDWebServerFileResponse.m in Sources */,
|
||||
CEE28D401AE0076F00F4023C /* GCDWebServerStreamedResponse.m in Sources */,
|
||||
CEE28D341AE0074A00F4023C /* GCDWebServerDataResponse.m in Sources */,
|
||||
CEE28D441AE0078000F4023C /* GCDWebDAVServer.m in Sources */,
|
||||
CEE28D0C1AE006CD00F4023C /* GCDWebServer.m in Sources */,
|
||||
CEE28D141AE006EA00F4023C /* GCDWebServerFunctions.m in Sources */,
|
||||
CEE28D381AE0075900F4023C /* GCDWebServerErrorResponse.m in Sources */,
|
||||
CEE28D4A1AE0079200F4023C /* GCDWebUploader.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E22112561690B4DE0048D2B2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -478,6 +776,16 @@
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
CE54F3941AE84FCA003C110E /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = CEE28CD01AE004D800F4023C /* GCDWebServers (Mac) */;
|
||||
targetProxy = CE54F3931AE84FCA003C110E /* PBXContainerItemProxy */;
|
||||
};
|
||||
CE54F3961AE84FCA003C110E /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = CEE28CEE1AE0051F00F4023C /* GCDWebServers (iOS) */;
|
||||
targetProxy = CE54F3951AE84FCA003C110E /* PBXContainerItemProxy */;
|
||||
};
|
||||
E274F87B187E77E3009E0582 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 8DD76FA90486AB0100D96B5E /* GCDWebServer (Mac) */;
|
||||
@@ -536,6 +844,7 @@
|
||||
"-Wno-documentation",
|
||||
"-Wno-documentation-unknown-command",
|
||||
"-Wno-objc-missing-property-synthesis",
|
||||
"-Wno-cstring-format-directive",
|
||||
);
|
||||
};
|
||||
name = Debug;
|
||||
@@ -552,6 +861,70 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
CEE28CE41AE004D800F4023C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Frameworks/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
PRODUCT_NAME = GCDWebServers;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
CEE28CE51AE004D800F4023C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Frameworks/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
PRODUCT_NAME = GCDWebServers;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
CEE28D031AE0052000F4023C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Frameworks/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = GCDWebServers;
|
||||
PROVISIONING_PROFILE = "";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
CEE28D041AE0052000F4023C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Frameworks/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = GCDWebServers;
|
||||
PROVISIONING_PROFILE = "";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E22112761690B4DF0048D2B2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -613,6 +986,24 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
CEE28CE81AE004D800F4023C /* Build configuration list for PBXNativeTarget "GCDWebServers (Mac)" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
CEE28CE41AE004D800F4023C /* Debug */,
|
||||
CEE28CE51AE004D800F4023C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
CEE28D021AE0052000F4023C /* Build configuration list for PBXNativeTarget "GCDWebServers (iOS)" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
CEE28D031AE0052000F4023C /* Debug */,
|
||||
CEE28D041AE0052000F4023C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E22112751690B4DF0048D2B2 /* Build configuration list for PBXNativeTarget "GCDWebServer (iOS)" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CEE28CD01AE004D800F4023C"
|
||||
BuildableName = "GCDWebServers.framework"
|
||||
BlueprintName = "GCDWebServers (Mac)"
|
||||
ReferencedContainer = "container:GCDWebServer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CEE28CD01AE004D800F4023C"
|
||||
BuildableName = "GCDWebServers.framework"
|
||||
BlueprintName = "GCDWebServers (Mac)"
|
||||
ReferencedContainer = "container:GCDWebServer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CEE28CD01AE004D800F4023C"
|
||||
BuildableName = "GCDWebServers.framework"
|
||||
BlueprintName = "GCDWebServers (Mac)"
|
||||
ReferencedContainer = "container:GCDWebServer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CEE28CEE1AE0051F00F4023C"
|
||||
BuildableName = "GCDWebServers.framework"
|
||||
BlueprintName = "GCDWebServers (iOS)"
|
||||
ReferencedContainer = "container:GCDWebServer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CEE28CEE1AE0051F00F4023C"
|
||||
BuildableName = "GCDWebServers.framework"
|
||||
BlueprintName = "GCDWebServers (iOS)"
|
||||
ReferencedContainer = "container:GCDWebServer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CEE28CEE1AE0051F00F4023C"
|
||||
BuildableName = "GCDWebServers.framework"
|
||||
BlueprintName = "GCDWebServers (iOS)"
|
||||
ReferencedContainer = "container:GCDWebServer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -79,7 +79,7 @@ extern NSString* const GCDWebServerOption_Port;
|
||||
* the name will automatically take the value of the GCDWebServerOption_ServerName
|
||||
* option. If this option is set to nil, Bonjour will be disabled.
|
||||
*
|
||||
* The default value is an empty string.
|
||||
* The default value is nil.
|
||||
*/
|
||||
extern NSString* const GCDWebServerOption_BonjourName;
|
||||
|
||||
@@ -90,6 +90,17 @@ extern NSString* const GCDWebServerOption_BonjourName;
|
||||
*/
|
||||
extern NSString* const GCDWebServerOption_BonjourType;
|
||||
|
||||
/**
|
||||
* Only accept HTTP requests coming from localhost i.e. not from the outside
|
||||
* network (NSNumber / BOOL).
|
||||
*
|
||||
* The default value is NO.
|
||||
*
|
||||
* @warning Bonjour should be disabled if using this option since the server
|
||||
* will not be reachable from the outside network anyway.
|
||||
*/
|
||||
extern NSString* const GCDWebServerOption_BindToLocalhost;
|
||||
|
||||
/**
|
||||
* The maximum number of incoming HTTP requests that can be queued waiting to
|
||||
* be handled before new ones are dropped (NSNumber / NSUInteger).
|
||||
@@ -512,6 +523,14 @@ extern NSString* const GCDWebServerAuthenticationMethod_DigestAccess;
|
||||
*
|
||||
* @warning The interpretation of the "level" argument depends on the logging
|
||||
* facility used at compile time.
|
||||
*
|
||||
* If using the built-in logging facility, the log levels are as follow:
|
||||
* DEBUG = 0
|
||||
* VERBOSE = 1
|
||||
* INFO = 2
|
||||
* WARNING = 3
|
||||
* ERROR = 4
|
||||
* EXCEPTION = 5
|
||||
*/
|
||||
+ (void)setLogLevel:(int)level;
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <UIKit/UIKit.h>
|
||||
@@ -46,6 +50,7 @@
|
||||
NSString* const GCDWebServerOption_Port = @"Port";
|
||||
NSString* const GCDWebServerOption_BonjourName = @"BonjourName";
|
||||
NSString* const GCDWebServerOption_BonjourType = @"BonjourType";
|
||||
NSString* const GCDWebServerOption_BindToLocalhost = @"BindToLocalhost";
|
||||
NSString* const GCDWebServerOption_MaxPendingConnections = @"MaxPendingConnections";
|
||||
NSString* const GCDWebServerOption_ServerName = @"ServerName";
|
||||
NSString* const GCDWebServerOption_AuthenticationMethod = @"AuthenticationMethod";
|
||||
@@ -69,9 +74,9 @@ GCDWebServerLoggingLevel GCDWebServerLogLevel = kGCDWebServerLoggingLevel_Info;
|
||||
#endif
|
||||
#elif defined(__GCDWEBSERVER_LOGGING_FACILITY_COCOALUMBERJACK__)
|
||||
#if DEBUG
|
||||
int GCDWebServerLogLevel = LOG_LEVEL_DEBUG;
|
||||
DDLogLevel GCDWebServerLogLevel = DDLogLevelDebug;
|
||||
#else
|
||||
int GCDWebServerLogLevel = LOG_LEVEL_INFO;
|
||||
DDLogLevel GCDWebServerLogLevel = DDLogLevelInfo;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -93,7 +98,6 @@ void GCDWebServerLogMessage(GCDWebServerLoggingLevel level, NSString* format, ..
|
||||
NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
|
||||
va_end(arguments);
|
||||
fprintf(stderr, "[%s] %s\n", levelNames[level], [message UTF8String]);
|
||||
ARC_RELEASE(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,13 +146,6 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_matchBlock);
|
||||
ARC_RELEASE(_asyncProcessBlock);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface GCDWebServer () {
|
||||
@@ -174,6 +171,7 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
dispatch_source_t _source6;
|
||||
CFNetServiceRef _registrationService;
|
||||
CFNetServiceRef _resolutionService;
|
||||
BOOL _bindToLocalhost;
|
||||
#if TARGET_OS_IPHONE
|
||||
BOOL _suspendInBackground;
|
||||
UIBackgroundTaskIdentifier _backgroundTask;
|
||||
@@ -212,11 +210,10 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
GWS_DCHECK(_options == nil); // The server can never be dealloc'ed while running because of the retain-cycle with the dispatch source
|
||||
GWS_DCHECK(_disconnectTimer == NULL); // The server can never be dealloc'ed while the disconnect timer is pending because of the retain-cycle
|
||||
|
||||
ARC_RELEASE(_handlers);
|
||||
ARC_DISPATCH_RELEASE(_sourceGroup);
|
||||
ARC_DISPATCH_RELEASE(_syncQueue);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
dispatch_release(_sourceGroup);
|
||||
dispatch_release(_syncQueue);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
@@ -247,7 +244,9 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
GWS_LOG_DEBUG(@"Did connect");
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
[self _startBackgroundTask];
|
||||
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground) {
|
||||
[self _startBackgroundTask];
|
||||
}
|
||||
#endif
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(webServerDidConnect:)]) {
|
||||
@@ -288,8 +287,6 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
[[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
|
||||
_backgroundTask = UIBackgroundTaskInvalid;
|
||||
GWS_LOG_DEBUG(@"Did end background task");
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,12 +336,12 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
|
||||
- (NSString*)bonjourName {
|
||||
CFStringRef name = _resolutionService ? CFNetServiceGetName(_resolutionService) : NULL;
|
||||
return name && CFStringGetLength(name) ? ARC_BRIDGE_RELEASE(CFStringCreateCopy(kCFAllocatorDefault, name)) : nil;
|
||||
return name && CFStringGetLength(name) ? CFBridgingRelease(CFStringCreateCopy(kCFAllocatorDefault, name)) : nil;
|
||||
}
|
||||
|
||||
- (NSString*)bonjourType {
|
||||
CFStringRef type = _resolutionService ? CFNetServiceGetType(_resolutionService) : NULL;
|
||||
return type && CFStringGetLength(type) ? ARC_BRIDGE_RELEASE(CFStringCreateCopy(kCFAllocatorDefault, type)) : nil;
|
||||
return type && CFStringGetLength(type) ? CFBridgingRelease(CFStringCreateCopy(kCFAllocatorDefault, type)) : nil;
|
||||
}
|
||||
|
||||
- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock {
|
||||
@@ -357,7 +354,6 @@ static void _ExecuteMainThreadRunLoopSources() {
|
||||
GWS_DCHECK(_options == nil);
|
||||
GCDWebServerHandler* handler = [[GCDWebServerHandler alloc] initWithMatchBlock:matchBlock asyncProcessBlock:processBlock];
|
||||
[_handlers insertObject:handler atIndex:0];
|
||||
ARC_RELEASE(handler);
|
||||
}
|
||||
|
||||
- (void)removeAllHandlers {
|
||||
@@ -371,7 +367,7 @@ static void _NetServiceRegisterCallBack(CFNetServiceRef service, CFStreamError*
|
||||
if (error->error) {
|
||||
GWS_LOG_ERROR(@"Bonjour registration error %i (domain %i)", (int)error->error, (int)error->domain);
|
||||
} else {
|
||||
GCDWebServer* server = (ARC_BRIDGE GCDWebServer*)info;
|
||||
GCDWebServer* server = (__bridge GCDWebServer*)info;
|
||||
GWS_LOG_VERBOSE(@"Bonjour registration complete for %@", [server class]);
|
||||
CFNetServiceResolveWithTimeout(server->_resolutionService, 1.0, NULL);
|
||||
}
|
||||
@@ -386,7 +382,7 @@ static void _NetServiceResolveCallBack(CFNetServiceRef service, CFStreamError* e
|
||||
GWS_LOG_ERROR(@"Bonjour resolution error %i (domain %i)", (int)error->error, (int)error->domain);
|
||||
}
|
||||
} else {
|
||||
GCDWebServer* server = (ARC_BRIDGE GCDWebServer*)info;
|
||||
GCDWebServer* server = (__bridge GCDWebServer*)info;
|
||||
GWS_LOG_INFO(@"%@ now reachable at %@", [server class], server.bonjourServerURL);
|
||||
if ([server.delegate respondsToSelector:@selector(webServerDidCompleteBonjourRegistration:)]) {
|
||||
[server.delegate webServerDidCompleteBonjourRegistration:server];
|
||||
@@ -407,7 +403,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
return [data base64Encoding];
|
||||
}
|
||||
#endif
|
||||
return ARC_AUTORELEASE([[NSString alloc] initWithData:[data base64EncodedDataWithOptions:0] encoding:NSASCIIStringEncoding]);
|
||||
return [[NSString alloc] initWithData:[data base64EncodedDataWithOptions:0] encoding:NSASCIIStringEncoding];
|
||||
}
|
||||
|
||||
- (int)_createListeningSocket:(BOOL)useIPv6
|
||||
@@ -487,11 +483,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &noSigPipe, sizeof(noSigPipe)); // Make sure this socket cannot generate SIG_PIPE
|
||||
|
||||
GCDWebServerConnection* connection = [[_connectionClass alloc] initWithServer:self localAddress:localAddress remoteAddress:remoteAddress socket:socket]; // Connection will automatically retain itself while opened
|
||||
#if __has_feature(objc_arc)
|
||||
[connection self]; // Prevent compiler from complaining about unused variable / useless statement
|
||||
#else
|
||||
[connection release];
|
||||
#endif
|
||||
} else {
|
||||
GWS_LOG_ERROR(@"Failed accepting %s socket: %s (%i)", isIPv6 ? "IPv6" : "IPv4", strerror(errno), errno);
|
||||
}
|
||||
@@ -505,6 +497,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
GWS_DCHECK(_source4 == NULL);
|
||||
|
||||
NSUInteger port = [_GetOption(_options, GCDWebServerOption_Port, @0) unsignedIntegerValue];
|
||||
BOOL bindToLocalhost = [_GetOption(_options, GCDWebServerOption_BindToLocalhost, @NO) boolValue];
|
||||
NSUInteger maxPendingConnections = [_GetOption(_options, GCDWebServerOption_MaxPendingConnections, @16) unsignedIntegerValue];
|
||||
|
||||
struct sockaddr_in addr4;
|
||||
@@ -512,7 +505,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
addr4.sin_len = sizeof(addr4);
|
||||
addr4.sin_family = AF_INET;
|
||||
addr4.sin_port = htons(port);
|
||||
addr4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addr4.sin_addr.s_addr = bindToLocalhost ? htonl(INADDR_LOOPBACK) : htonl(INADDR_ANY);
|
||||
int listeningSocket4 = [self _createListeningSocket:NO localAddress:&addr4 length:sizeof(addr4) maxPendingConnections:maxPendingConnections error:error];
|
||||
if (listeningSocket4 <= 0) {
|
||||
return NO;
|
||||
@@ -533,7 +526,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
addr6.sin6_len = sizeof(addr6);
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = htons(port);
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
addr6.sin6_addr = bindToLocalhost ? in6addr_loopback : in6addr_any;
|
||||
int listeningSocket6 = [self _createListeningSocket:YES localAddress:&addr6 length:sizeof(addr6) maxPendingConnections:maxPendingConnections error:error];
|
||||
if (listeningSocket6 <= 0) {
|
||||
close(listeningSocket4);
|
||||
@@ -564,13 +557,14 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
_source4 = [self _createDispatchSourceWithListeningSocket:listeningSocket4 isIPv6:NO];
|
||||
_source6 = [self _createDispatchSourceWithListeningSocket:listeningSocket6 isIPv6:YES];
|
||||
_port = port;
|
||||
_bindToLocalhost = bindToLocalhost;
|
||||
|
||||
NSString* bonjourName = _GetOption(_options, GCDWebServerOption_BonjourName, @"");
|
||||
NSString* bonjourName = _GetOption(_options, GCDWebServerOption_BonjourName, nil);
|
||||
NSString* bonjourType = _GetOption(_options, GCDWebServerOption_BonjourType, @"_http._tcp");
|
||||
if (bonjourName) {
|
||||
_registrationService = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), (ARC_BRIDGE CFStringRef)bonjourType, (ARC_BRIDGE CFStringRef)(bonjourName.length ? bonjourName : _serverName), (SInt32)_port);
|
||||
_registrationService = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), (__bridge CFStringRef)bonjourType, (__bridge CFStringRef)(bonjourName.length ? bonjourName : _serverName), (SInt32)_port);
|
||||
if (_registrationService) {
|
||||
CFNetServiceClientContext context = {0, (ARC_BRIDGE void*)self, NULL, NULL, NULL};
|
||||
CFNetServiceClientContext context = {0, (__bridge void*)self, NULL, NULL, NULL};
|
||||
|
||||
CFNetServiceSetClient(_registrationService, _NetServiceRegisterCallBack, &context);
|
||||
CFNetServiceScheduleWithRunLoop(_registrationService, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
@@ -620,19 +614,20 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
dispatch_source_cancel(_source6);
|
||||
dispatch_source_cancel(_source4);
|
||||
dispatch_group_wait(_sourceGroup, DISPATCH_TIME_FOREVER); // Wait until the cancellation handlers have been called which guarantees the listening sockets are closed
|
||||
ARC_DISPATCH_RELEASE(_source6);
|
||||
#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
dispatch_release(_source6);
|
||||
#endif
|
||||
_source6 = NULL;
|
||||
ARC_DISPATCH_RELEASE(_source4);
|
||||
#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
dispatch_release(_source4);
|
||||
#endif
|
||||
_source4 = NULL;
|
||||
_port = 0;
|
||||
_bindToLocalhost = NO;
|
||||
|
||||
ARC_RELEASE(_serverName);
|
||||
_serverName = nil;
|
||||
ARC_RELEASE(_authenticationRealm);
|
||||
_authenticationRealm = nil;
|
||||
ARC_RELEASE(_authenticationBasicAccounts);
|
||||
_authenticationBasicAccounts = nil;
|
||||
ARC_RELEASE(_authenticationDigestAccounts);
|
||||
_authenticationDigestAccounts = nil;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@@ -674,7 +669,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
|
||||
- (BOOL)startWithOptions:(NSDictionary*)options error:(NSError**)error {
|
||||
if (_options == nil) {
|
||||
_options = [options copy];
|
||||
_options = options ? [options copy] : @{};
|
||||
#if TARGET_OS_IPHONE
|
||||
_suspendInBackground = [_GetOption(_options, GCDWebServerOption_AutomaticallySuspendInBackground, @YES) boolValue];
|
||||
if (((_suspendInBackground == NO) || ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground)) && ![self _start:error])
|
||||
@@ -682,7 +677,6 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
if (![self _start:error])
|
||||
#endif
|
||||
{
|
||||
ARC_RELEASE(_options);
|
||||
_options = nil;
|
||||
return NO;
|
||||
}
|
||||
@@ -714,7 +708,6 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
if (_source4) {
|
||||
[self _stop];
|
||||
}
|
||||
ARC_RELEASE(_options);
|
||||
_options = nil;
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
@@ -727,7 +720,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
|
||||
- (NSURL*)serverURL {
|
||||
if (_source4) {
|
||||
NSString* ipAddress = GCDWebServerGetPrimaryIPAddress(NO); // We can't really use IPv6 anyway as it doesn't work great with HTTP URLs in practice
|
||||
NSString* ipAddress = _bindToLocalhost ? @"localhost" : GCDWebServerGetPrimaryIPAddress(NO); // We can't really use IPv6 anyway as it doesn't work great with HTTP URLs in practice
|
||||
if (ipAddress) {
|
||||
if (_port != 80) {
|
||||
return [NSURL URLWithString:[NSString stringWithFormat:@"http://%@:%i/", ipAddress, (int)_port]];
|
||||
@@ -741,7 +734,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
|
||||
- (NSURL*)bonjourServerURL {
|
||||
if (_source4 && _resolutionService) {
|
||||
NSString* name = (ARC_BRIDGE NSString*)CFNetServiceGetTargetHost(_resolutionService);
|
||||
NSString* name = (__bridge NSString*)CFNetServiceGetTargetHost(_resolutionService);
|
||||
if (name.length) {
|
||||
name = [name substringToIndex:(name.length - 1)]; // Strip trailing period at end of domain
|
||||
if (_port != 80) {
|
||||
@@ -813,7 +806,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
if (![requestMethod isEqualToString:method]) {
|
||||
return nil;
|
||||
}
|
||||
return ARC_AUTORELEASE([[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
||||
return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
|
||||
|
||||
} asyncProcessBlock:block];
|
||||
}
|
||||
@@ -834,7 +827,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
if ([urlPath caseInsensitiveCompare:path] != NSOrderedSame) {
|
||||
return nil;
|
||||
}
|
||||
return ARC_AUTORELEASE([[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
||||
return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
|
||||
|
||||
} asyncProcessBlock:block];
|
||||
} else {
|
||||
@@ -872,7 +865,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
|
||||
GCDWebServerRequest* request = [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
|
||||
[request setAttribute:captures forKey:GCDWebServerRequestAttribute_RegexCaptures];
|
||||
return ARC_AUTORELEASE(request);
|
||||
return request;
|
||||
|
||||
} asyncProcessBlock:block];
|
||||
} else {
|
||||
@@ -939,11 +932,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
|
||||
- (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)
|
||||
GCDWebServer* __unsafe_unretained server = self;
|
||||
#else
|
||||
__block GCDWebServer* server = self;
|
||||
#endif
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
if (![requestMethod isEqualToString:@"GET"]) {
|
||||
@@ -952,7 +941,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
if (![urlPath hasPrefix:basePath]) {
|
||||
return nil;
|
||||
}
|
||||
return ARC_AUTORELEASE([[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
||||
return [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
|
||||
|
||||
} processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||
|
||||
@@ -1000,7 +989,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
[XLSharedFacility setMinLogLevel:level];
|
||||
#elif defined(__GCDWEBSERVER_LOGGING_FACILITY_COCOALUMBERJACK__)
|
||||
GCDWebServerLogLevel = level;
|
||||
#else
|
||||
#elif defined(__GCDWEBSERVER_LOGGING_FACILITY_BUILTIN__)
|
||||
GCDWebServerLogLevel = level;
|
||||
#endif
|
||||
}
|
||||
@@ -1008,28 +997,28 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
||||
- (void)logVerbose:(NSString*)format, ... {
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
GWS_LOG_VERBOSE(@"%@", ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments]));
|
||||
GWS_LOG_VERBOSE(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]);
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
- (void)logInfo:(NSString*)format, ... {
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
GWS_LOG_INFO(@"%@", ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments]));
|
||||
GWS_LOG_INFO(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]);
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
- (void)logWarning:(NSString*)format, ... {
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
GWS_LOG_WARNING(@"%@", ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments]));
|
||||
GWS_LOG_WARNING(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]);
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
- (void)logError:(NSString*)format, ... {
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
GWS_LOG_ERROR(@"%@", ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments]));
|
||||
GWS_LOG_ERROR(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]);
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
@@ -1093,7 +1082,6 @@ static CFHTTPMessageRef _CreateHTTPMessageFromPerformingRequest(NSData* inData,
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
}
|
||||
ARC_RELEASE(outData);
|
||||
}
|
||||
}
|
||||
close(httpSocket);
|
||||
@@ -1107,7 +1095,6 @@ static void _LogResult(NSString* format, ...) {
|
||||
NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
|
||||
va_end(arguments);
|
||||
fprintf(stdout, "%s\n", [message UTF8String]);
|
||||
ARC_RELEASE(message);
|
||||
}
|
||||
|
||||
- (NSInteger)runTestsWithOptions:(NSDictionary*)options inDirectory:(NSString*)path {
|
||||
@@ -1130,8 +1117,8 @@ static void _LogResult(NSString* format, ...) {
|
||||
if (requestData) {
|
||||
CFHTTPMessageRef request = _CreateHTTPMessageFromData(requestData, YES);
|
||||
if (request) {
|
||||
NSString* requestMethod = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestMethod(request));
|
||||
NSURL* requestURL = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestURL(request));
|
||||
NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(request));
|
||||
NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(request));
|
||||
_LogResult(@"[%i] %@ %@", (int)[index integerValue], requestMethod, requestURL.path);
|
||||
NSString* prefix = [index stringByAppendingString:@"-"];
|
||||
for (NSString* responseFile in files) {
|
||||
@@ -1151,8 +1138,8 @@ static void _LogResult(NSString* format, ...) {
|
||||
success = NO;
|
||||
}
|
||||
|
||||
NSDictionary* expectedHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(expectedResponse));
|
||||
NSDictionary* actualHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(actualResponse));
|
||||
NSDictionary* expectedHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(expectedResponse));
|
||||
NSDictionary* actualHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(actualResponse));
|
||||
for (NSString* expectedHeader in expectedHeaders) {
|
||||
if ([ignoredHeaders containsObject:expectedHeader]) {
|
||||
continue;
|
||||
@@ -1171,10 +1158,10 @@ static void _LogResult(NSString* format, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
NSString* expectedContentLength = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyHeaderFieldValue(expectedResponse, CFSTR("Content-Length")));
|
||||
NSData* expectedBody = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyBody(expectedResponse));
|
||||
NSString* actualContentLength = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyHeaderFieldValue(actualResponse, CFSTR("Content-Length")));
|
||||
NSData* actualBody = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyBody(actualResponse));
|
||||
NSString* expectedContentLength = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(expectedResponse, CFSTR("Content-Length")));
|
||||
NSData* expectedBody = CFBridgingRelease(CFHTTPMessageCopyBody(expectedResponse));
|
||||
NSString* actualContentLength = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(actualResponse, CFSTR("Content-Length")));
|
||||
NSData* actualBody = CFBridgingRelease(CFHTTPMessageCopyBody(actualResponse));
|
||||
if ([actualContentLength isEqualToString:expectedContentLength] && (actualBody.length > expectedBody.length)) { // Handle web browser closing connection before retrieving entire body (e.g. when playing a video file)
|
||||
actualBody = [actualBody subdataWithRange:NSMakeRange(0, expectedBody.length)];
|
||||
}
|
||||
@@ -1191,7 +1178,6 @@ static void _LogResult(NSString* format, ...) {
|
||||
[task setLaunchPath:@"/usr/bin/opendiff"];
|
||||
[task setArguments:@[expectedPath, actualPath]];
|
||||
[task launch];
|
||||
ARC_RELEASE(task);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
#import <netdb.h>
|
||||
#ifdef __GCDWEBSERVER_ENABLE_TESTING__
|
||||
@@ -172,7 +176,6 @@ static int32_t _connectionCounter = 0;
|
||||
}
|
||||
|
||||
}];
|
||||
ARC_RELEASE(bodyData);
|
||||
}
|
||||
|
||||
static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
@@ -244,15 +247,8 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
@implementation GCDWebServerConnection (Write)
|
||||
|
||||
- (void)_writeData:(NSData*)data withCompletionBlock:(WriteDataCompletionBlock)block {
|
||||
#if !__has_feature(objc_arc)
|
||||
[data retain];
|
||||
#endif
|
||||
dispatch_data_t buffer = dispatch_data_create(data.bytes, data.length, kGCDWebServerGCDQueue, ^{
|
||||
#if __has_feature(objc_arc)
|
||||
[data self]; // Keeps ARC from releasing data too early
|
||||
#else
|
||||
[data release];
|
||||
#endif
|
||||
});
|
||||
dispatch_write(_socket, buffer, kGCDWebServerGCDQueue, ^(dispatch_data_t remainingData, int error) {
|
||||
|
||||
@@ -268,13 +264,15 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
}
|
||||
|
||||
});
|
||||
ARC_DISPATCH_RELEASE(buffer);
|
||||
#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
dispatch_release(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)_writeHeadersWithCompletionBlock:(WriteHeadersCompletionBlock)block {
|
||||
GWS_DCHECK(_responseMessage);
|
||||
CFDataRef data = CFHTTPMessageCopySerializedMessage(_responseMessage);
|
||||
[self _writeData:(ARC_BRIDGE NSData*)data withCompletionBlock:block];
|
||||
[self _writeData:(__bridge NSData*)data withCompletionBlock:block];
|
||||
CFRelease(data);
|
||||
}
|
||||
|
||||
@@ -349,11 +347,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
}
|
||||
if (_continueData == nil) {
|
||||
CFHTTPMessageRef message = CFHTTPMessageCreateResponse(kCFAllocatorDefault, 100, NULL, kCFHTTPVersion1_1);
|
||||
#if __has_feature(objc_arc)
|
||||
_continueData = CFBridgingRelease(CFHTTPMessageCopySerializedMessage(message));
|
||||
#else
|
||||
_continueData = (NSData*)CFHTTPMessageCopySerializedMessage(message);
|
||||
#endif
|
||||
CFRelease(message);
|
||||
GWS_DCHECK(_continueData);
|
||||
}
|
||||
@@ -362,7 +356,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
}
|
||||
if (_digestAuthenticationNonce == nil) {
|
||||
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
|
||||
_digestAuthenticationNonce = ARC_RETAIN(GCDWebServerComputeMD5Digest(@"%@", ARC_BRIDGE_RELEASE(CFUUIDCreateString(kCFAllocatorDefault, uuid))));
|
||||
_digestAuthenticationNonce = GCDWebServerComputeMD5Digest(@"%@", CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid)));
|
||||
CFRelease(uuid);
|
||||
}
|
||||
}
|
||||
@@ -376,8 +370,8 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
_statusCode = statusCode;
|
||||
_responseMessage = CFHTTPMessageCreateResponse(kCFAllocatorDefault, statusCode, NULL, kCFHTTPVersion1_1);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Connection"), CFSTR("Close"));
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (ARC_BRIDGE CFStringRef)_server.serverName);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatRFC822([NSDate date]));
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (__bridge CFStringRef)_server.serverName);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (__bridge CFStringRef)GCDWebServerFormatRFC822([NSDate date]));
|
||||
}
|
||||
|
||||
- (void)_startProcessingRequest {
|
||||
@@ -410,36 +404,36 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
if (hasBody && ![response performOpen:&error]) {
|
||||
GWS_LOG_ERROR(@"Failed opening response body for socket %i: %@", _socket, error);
|
||||
} else {
|
||||
_response = ARC_RETAIN(response);
|
||||
_response = response;
|
||||
}
|
||||
}
|
||||
|
||||
if (_response) {
|
||||
[self _initializeResponseHeadersWithStatusCode:_response.statusCode];
|
||||
if (_response.lastModifiedDate) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatRFC822(_response.lastModifiedDate));
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (__bridge CFStringRef)GCDWebServerFormatRFC822(_response.lastModifiedDate));
|
||||
}
|
||||
if (_response.eTag) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("ETag"), (ARC_BRIDGE CFStringRef)_response.eTag);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("ETag"), (__bridge CFStringRef)_response.eTag);
|
||||
}
|
||||
if ((_response.statusCode >= 200) && (_response.statusCode < 300)) {
|
||||
if (_response.cacheControlMaxAge > 0) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)_response.cacheControlMaxAge]);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (__bridge CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)_response.cacheControlMaxAge]);
|
||||
} else {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), CFSTR("no-cache"));
|
||||
}
|
||||
}
|
||||
if (_response.contentType != nil) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Type"), (ARC_BRIDGE CFStringRef)GCDWebServerNormalizeHeaderValue(_response.contentType));
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Type"), (__bridge CFStringRef)GCDWebServerNormalizeHeaderValue(_response.contentType));
|
||||
}
|
||||
if (_response.contentLength != NSUIntegerMax) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Length"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"%lu", (unsigned long)_response.contentLength]);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Length"), (__bridge CFStringRef)[NSString stringWithFormat:@"%lu", (unsigned long)_response.contentLength]);
|
||||
}
|
||||
if (_response.usesChunkedTransferEncoding) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Transfer-Encoding"), CFSTR("chunked"));
|
||||
}
|
||||
[_response.additionalHeaders enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL* stop) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, (ARC_BRIDGE CFStringRef)key, (ARC_BRIDGE CFStringRef)obj);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);
|
||||
}];
|
||||
[self _writeHeadersWithCompletionBlock:^(BOOL success) {
|
||||
|
||||
@@ -524,7 +518,6 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
}
|
||||
|
||||
}];
|
||||
ARC_RELEASE(chunkData);
|
||||
}
|
||||
|
||||
- (void)_readRequestHeaders {
|
||||
@@ -533,28 +526,30 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
[self _readHeaders:headersData withCompletionBlock:^(NSData* extraData) {
|
||||
|
||||
if (extraData) {
|
||||
NSString* requestMethod = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestMethod(_requestMessage)); // Method verbs are case-sensitive and uppercase
|
||||
NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(_requestMessage)); // Method verbs are case-sensitive and uppercase
|
||||
if (_server.shouldAutomaticallyMapHEADToGET && [requestMethod isEqualToString:@"HEAD"]) {
|
||||
requestMethod = @"GET";
|
||||
_virtualHEAD = YES;
|
||||
}
|
||||
NSDictionary* requestHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones
|
||||
NSURL* requestURL = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestURL(_requestMessage));
|
||||
NSDictionary* requestHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones
|
||||
NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(_requestMessage));
|
||||
if (requestURL) {
|
||||
requestURL = [self rewriteRequestURL:requestURL withMethod:requestMethod headers:requestHeaders];
|
||||
GWS_DCHECK(requestURL);
|
||||
}
|
||||
NSString* requestPath = requestURL ? GCDWebServerUnescapeURLString(ARC_BRIDGE_RELEASE(CFURLCopyPath((CFURLRef)requestURL))) : nil; // Don't use -[NSURL path] which strips the ending slash
|
||||
NSString* queryString = requestURL ? ARC_BRIDGE_RELEASE(CFURLCopyQueryString((CFURLRef)requestURL, NULL)) : nil; // Don't use -[NSURL query] to make sure query is not unescaped;
|
||||
NSString* requestPath = requestURL ? GCDWebServerUnescapeURLString(CFBridgingRelease(CFURLCopyPath((CFURLRef)requestURL))) : nil; // Don't use -[NSURL path] which strips the ending slash
|
||||
NSString* queryString = requestURL ? CFBridgingRelease(CFURLCopyQueryString((CFURLRef)requestURL, NULL)) : nil; // Don't use -[NSURL query] to make sure query is not unescaped;
|
||||
NSDictionary* requestQuery = queryString ? GCDWebServerParseURLEncodedForm(queryString) : @{};
|
||||
if (requestMethod && requestURL && requestHeaders && requestPath && requestQuery) {
|
||||
for (_handler in _server.handlers) {
|
||||
_request = ARC_RETAIN(_handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery));
|
||||
_request = _handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery);
|
||||
if (_request) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_request) {
|
||||
_request.localAddressData = self.localAddressData;
|
||||
_request.remoteAddressData = self.remoteAddressData;
|
||||
if ([_request hasBody]) {
|
||||
[_request prepareForWriting];
|
||||
if (_request.usesChunkedTransferEncoding || (extraData.length <= _request.contentLength)) {
|
||||
@@ -604,14 +599,13 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
}
|
||||
|
||||
}];
|
||||
ARC_RELEASE(headersData);
|
||||
}
|
||||
|
||||
- (id)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket {
|
||||
if ((self = [super init])) {
|
||||
_server = ARC_RETAIN(server);
|
||||
_localAddress = ARC_RETAIN(localAddress);
|
||||
_remoteAddress = ARC_RETAIN(remoteAddress);
|
||||
_server = server;
|
||||
_localAddress = localAddress;
|
||||
_remoteAddress = remoteAddress;
|
||||
_socket = socket;
|
||||
GWS_LOG_DEBUG(@"Did open connection on socket %i", _socket);
|
||||
|
||||
@@ -619,7 +613,6 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
|
||||
if (![self open]) {
|
||||
close(_socket);
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
_opened = YES;
|
||||
@@ -650,26 +643,14 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
}
|
||||
|
||||
[_server didEndConnection:self];
|
||||
ARC_RELEASE(_server);
|
||||
ARC_RELEASE(_localAddress);
|
||||
ARC_RELEASE(_remoteAddress);
|
||||
|
||||
if (_requestMessage) {
|
||||
CFRelease(_requestMessage);
|
||||
}
|
||||
ARC_RELEASE(_request);
|
||||
|
||||
if (_responseMessage) {
|
||||
CFRelease(_responseMessage);
|
||||
}
|
||||
ARC_RELEASE(_response);
|
||||
|
||||
#ifdef __GCDWEBSERVER_ENABLE_TESTING__
|
||||
ARC_RELEASE(_requestPath);
|
||||
ARC_RELEASE(_responsePath);
|
||||
#endif
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -681,11 +662,11 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
if (_server.recordingEnabled) {
|
||||
_connectionIndex = OSAtomicIncrement32(&_connectionCounter);
|
||||
|
||||
_requestPath = ARC_RETAIN([NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]);
|
||||
_requestPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
|
||||
_requestFD = open([_requestPath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
GWS_DCHECK(_requestFD > 0);
|
||||
|
||||
_responsePath = ARC_RETAIN([NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]);
|
||||
_responsePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
|
||||
_responseFD = open([_responsePath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
GWS_DCHECK(_responseFD > 0);
|
||||
}
|
||||
@@ -785,15 +766,19 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
|
||||
}
|
||||
}
|
||||
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
|
||||
static inline BOOL _CompareResources(NSString* responseETag, NSString* requestETag, NSDate* responseLastModified, NSDate* requestLastModified) {
|
||||
if ([requestETag isEqualToString:@"*"] && (!responseLastModified || !requestLastModified || ([responseLastModified compare:requestLastModified] != NSOrderedDescending))) {
|
||||
return YES;
|
||||
} else {
|
||||
if ([responseETag isEqualToString:requestETag]) {
|
||||
if (requestLastModified && responseLastModified) {
|
||||
if ([responseLastModified compare:requestLastModified] != NSOrderedDescending) {
|
||||
return YES;
|
||||
}
|
||||
if (responseLastModified && requestLastModified && ([responseLastModified compare:requestLastModified] != NSOrderedDescending)) {
|
||||
}
|
||||
if (requestETag && responseETag) { // Per the specs "If-None-Match" must be checked after "If-Modified-Since"
|
||||
if ([requestETag isEqualToString:@"*"]) {
|
||||
return YES;
|
||||
}
|
||||
if ([responseETag isEqualToString:requestETag]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
@@ -50,14 +54,14 @@ void GCDWebServerInitializeFunctions() {
|
||||
_dateFormatterRFC822 = [[NSDateFormatter alloc] init];
|
||||
_dateFormatterRFC822.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
|
||||
_dateFormatterRFC822.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'";
|
||||
_dateFormatterRFC822.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]);
|
||||
_dateFormatterRFC822.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
|
||||
GWS_DCHECK(_dateFormatterRFC822);
|
||||
}
|
||||
if (_dateFormatterISO8601 == nil) {
|
||||
_dateFormatterISO8601 = [[NSDateFormatter alloc] init];
|
||||
_dateFormatterISO8601.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
|
||||
_dateFormatterISO8601.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'+00:00'";
|
||||
_dateFormatterISO8601.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]);
|
||||
_dateFormatterISO8601.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
|
||||
GWS_DCHECK(_dateFormatterISO8601);
|
||||
}
|
||||
if (_dateFormatterQueue == NULL) {
|
||||
@@ -96,7 +100,6 @@ NSString* GCDWebServerExtractHeaderValueParameter(NSString* value, NSString* nam
|
||||
[scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:¶meter];
|
||||
}
|
||||
}
|
||||
ARC_RELEASE(scanner);
|
||||
return parameter;
|
||||
}
|
||||
|
||||
@@ -150,7 +153,7 @@ NSString* GCDWebServerDescribeData(NSData* data, NSString* type) {
|
||||
NSString* charset = GCDWebServerExtractHeaderValueParameter(type, @"charset");
|
||||
NSString* string = [[NSString alloc] initWithData:data encoding:GCDWebServerStringEncodingFromCharset(charset)];
|
||||
if (string) {
|
||||
return ARC_AUTORELEASE(string);
|
||||
return string;
|
||||
}
|
||||
}
|
||||
return [NSString stringWithFormat:@"<%lu bytes>", (unsigned long)data.length];
|
||||
@@ -168,9 +171,9 @@ NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension) {
|
||||
if (extension.length) {
|
||||
mimeType = [_overrides objectForKey:extension];
|
||||
if (mimeType == nil) {
|
||||
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (ARC_BRIDGE CFStringRef)extension, NULL);
|
||||
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL);
|
||||
if (uti) {
|
||||
mimeType = ARC_BRIDGE_RELEASE(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType));
|
||||
mimeType = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType));
|
||||
CFRelease(uti);
|
||||
}
|
||||
}
|
||||
@@ -179,11 +182,11 @@ NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension) {
|
||||
}
|
||||
|
||||
NSString* GCDWebServerEscapeURLString(NSString* string) {
|
||||
return ARC_BRIDGE_RELEASE(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":@/?&=+"), kCFStringEncodingUTF8));
|
||||
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":@/?&=+"), kCFStringEncodingUTF8));
|
||||
}
|
||||
|
||||
NSString* GCDWebServerUnescapeURLString(NSString* string) {
|
||||
return ARC_BRIDGE_RELEASE(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (CFStringRef)string, CFSTR(""), kCFStringEncodingUTF8));
|
||||
return CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (CFStringRef)string, CFSTR(""), kCFStringEncodingUTF8));
|
||||
}
|
||||
|
||||
NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form) {
|
||||
@@ -219,7 +222,6 @@ NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form) {
|
||||
}
|
||||
[scanner setScanLocation:([scanner scanLocation] + 1)];
|
||||
}
|
||||
ARC_RELEASE(scanner);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@@ -247,7 +249,7 @@ NSString* GCDWebServerGetPrimaryIPAddress(BOOL useIPv6) {
|
||||
if (store) {
|
||||
CFPropertyListRef info = SCDynamicStoreCopyValue(store, CFSTR("State:/Network/Global/IPv4")); // There is no equivalent for IPv6 but the primary interface should be the same
|
||||
if (info) {
|
||||
primaryInterface = [[NSString stringWithString:[(ARC_BRIDGE NSDictionary*)info objectForKey:@"PrimaryInterface"]] UTF8String];
|
||||
primaryInterface = [[NSString stringWithString:[(__bridge NSDictionary*)info objectForKey:@"PrimaryInterface"]] UTF8String];
|
||||
CFRelease(info);
|
||||
}
|
||||
CFRelease(store);
|
||||
@@ -280,7 +282,7 @@ NSString* GCDWebServerGetPrimaryIPAddress(BOOL useIPv6) {
|
||||
NSString* GCDWebServerComputeMD5Digest(NSString* format, ...) {
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
const char* string = [ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments]) UTF8String];
|
||||
const char* string = [[[NSString alloc] initWithFormat:format arguments:arguments] UTF8String];
|
||||
va_end(arguments);
|
||||
unsigned char md5[CC_MD5_DIGEST_LENGTH];
|
||||
CC_MD5(string, (CC_LONG)strlen(string), md5);
|
||||
|
||||
@@ -28,35 +28,6 @@
|
||||
#import <os/object.h>
|
||||
#import <sys/socket.h>
|
||||
|
||||
/**
|
||||
* ARC <-> MRC compatibility macros.
|
||||
*/
|
||||
|
||||
#if __has_feature(objc_arc)
|
||||
#define ARC_BRIDGE __bridge
|
||||
#define ARC_BRIDGE_RELEASE(__OBJECT__) CFBridgingRelease(__OBJECT__)
|
||||
#define ARC_RETAIN(__OBJECT__) __OBJECT__
|
||||
#define ARC_RELEASE(__OBJECT__)
|
||||
#define ARC_AUTORELEASE(__OBJECT__) __OBJECT__
|
||||
#define ARC_DEALLOC(__OBJECT__)
|
||||
#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
#define ARC_DISPATCH_RETAIN(__OBJECT__)
|
||||
#define ARC_DISPATCH_RELEASE(__OBJECT__)
|
||||
#else
|
||||
#define ARC_DISPATCH_RETAIN(__OBJECT__) dispatch_retain(__OBJECT__)
|
||||
#define ARC_DISPATCH_RELEASE(__OBJECT__) dispatch_release(__OBJECT__)
|
||||
#endif
|
||||
#else
|
||||
#define ARC_BRIDGE
|
||||
#define ARC_BRIDGE_RELEASE(__OBJECT__) [(id)__OBJECT__ autorelease]
|
||||
#define ARC_RETAIN(__OBJECT__) [__OBJECT__ retain]
|
||||
#define ARC_RELEASE(__OBJECT__) [__OBJECT__ release]
|
||||
#define ARC_AUTORELEASE(__OBJECT__) [__OBJECT__ autorelease]
|
||||
#define ARC_DEALLOC(__OBJECT__) [__OBJECT__ dealloc]
|
||||
#define ARC_DISPATCH_RETAIN(__OBJECT__) dispatch_retain(__OBJECT__)
|
||||
#define ARC_DISPATCH_RELEASE(__OBJECT__) dispatch_release(__OBJECT__)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* All GCDWebServer headers.
|
||||
*/
|
||||
@@ -77,15 +48,28 @@
|
||||
#import "GCDWebServerFileResponse.h"
|
||||
#import "GCDWebServerStreamedResponse.h"
|
||||
|
||||
/**
|
||||
* Check if a custom logging facility should be used instead.
|
||||
*/
|
||||
|
||||
#if defined(__GCDWEBSERVER_LOGGING_HEADER__)
|
||||
|
||||
#define __GCDWEBSERVER_LOGGING_FACILITY_CUSTOM__
|
||||
|
||||
#import __GCDWEBSERVER_LOGGING_HEADER__
|
||||
|
||||
/**
|
||||
* Automatically detect if XLFacility is available and if so use it as a
|
||||
* logging facility.
|
||||
*/
|
||||
|
||||
#if defined(__has_include) && __has_include("XLFacilityMacros.h")
|
||||
#elif defined(__has_include) && __has_include("XLFacilityMacros.h")
|
||||
|
||||
#define __GCDWEBSERVER_LOGGING_FACILITY_XLFACILITY__
|
||||
|
||||
#undef XLOG_TAG
|
||||
#define XLOG_TAG @"gcdwebserver.internal"
|
||||
|
||||
#import "XLFacilityMacros.h"
|
||||
|
||||
#define GWS_LOG_DEBUG(...) XLOG_DEBUG(__VA_ARGS__)
|
||||
@@ -103,15 +87,15 @@
|
||||
* it as a logging facility.
|
||||
*/
|
||||
|
||||
#elif defined(__has_include) && __has_include("DDLogMacros.h")
|
||||
#elif defined(__has_include) && __has_include("CocoaLumberjack/CocoaLumberjack.h")
|
||||
|
||||
#import "DDLogMacros.h"
|
||||
#import <CocoaLumberjack/CocoaLumberjack.h>
|
||||
|
||||
#define __GCDWEBSERVER_LOGGING_FACILITY_COCOALUMBERJACK__
|
||||
|
||||
#undef LOG_LEVEL_DEF
|
||||
#define LOG_LEVEL_DEF GCDWebServerLogLevel
|
||||
extern int GCDWebServerLogLevel;
|
||||
extern DDLogLevel GCDWebServerLogLevel;
|
||||
|
||||
#define GWS_LOG_DEBUG(...) DDLogDebug(__VA_ARGS__)
|
||||
#define GWS_LOG_VERBOSE(...) DDLogVerbose(__VA_ARGS__)
|
||||
@@ -120,16 +104,6 @@ extern int GCDWebServerLogLevel;
|
||||
#define GWS_LOG_ERROR(...) DDLogError(__VA_ARGS__)
|
||||
#define GWS_LOG_EXCEPTION(__EXCEPTION__) DDLogError(@"%@", __EXCEPTION__)
|
||||
|
||||
/**
|
||||
* Check if a custom logging facility should be used instead.
|
||||
*/
|
||||
|
||||
#elif defined(__GCDWEBSERVER_LOGGING_HEADER__)
|
||||
|
||||
#define __GCDWEBSERVER_LOGGING_FACILITY_CUSTOM__
|
||||
|
||||
#import __GCDWEBSERVER_LOGGING_HEADER__
|
||||
|
||||
/**
|
||||
* If all of the above fail, then use GCDWebServer built-in
|
||||
* logging facility.
|
||||
@@ -145,7 +119,7 @@ typedef NS_ENUM(int, GCDWebServerLoggingLevel) {
|
||||
kGCDWebServerLoggingLevel_Info,
|
||||
kGCDWebServerLoggingLevel_Warning,
|
||||
kGCDWebServerLoggingLevel_Error,
|
||||
kGCDWebServerLoggingLevel_Exception,
|
||||
kGCDWebServerLoggingLevel_Exception
|
||||
};
|
||||
|
||||
extern GCDWebServerLoggingLevel GCDWebServerLogLevel;
|
||||
@@ -237,6 +211,8 @@ extern NSString* GCDWebServerStringFromSockAddr(const struct sockaddr* addr, BOO
|
||||
|
||||
@interface GCDWebServerRequest ()
|
||||
@property(nonatomic, readonly) BOOL usesChunkedTransferEncoding;
|
||||
@property(nonatomic, readwrite) NSData* localAddressData;
|
||||
@property(nonatomic, readwrite) NSData* remoteAddressData;
|
||||
- (void)prepareForWriting;
|
||||
- (BOOL)performOpen:(NSError**)error;
|
||||
- (BOOL)performWriteData:(NSData*)data error:(NSError**)error;
|
||||
|
||||
@@ -157,6 +157,30 @@ extern NSString* const GCDWebServerRequestAttribute_RegexCaptures;
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL acceptsGzipContentEncoding;
|
||||
|
||||
/**
|
||||
* Returns the address of the local peer (i.e. server) for the request
|
||||
* as a raw "struct sockaddr".
|
||||
*/
|
||||
@property(nonatomic, readonly) NSData* localAddressData;
|
||||
|
||||
/**
|
||||
* Returns the address of the local peer (i.e. server) for the request
|
||||
* as a string.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString* localAddressString;
|
||||
|
||||
/**
|
||||
* Returns the address of the remote peer (i.e. client) for the request
|
||||
* as a raw "struct sockaddr".
|
||||
*/
|
||||
@property(nonatomic, readonly) NSData* remoteAddressData;
|
||||
|
||||
/**
|
||||
* Returns the address of the remote peer (i.e. client) for the request
|
||||
* as a string.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString* remoteAddressString;
|
||||
|
||||
/**
|
||||
* This method is the designated initializer for the class.
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import <zlib.h>
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
@@ -84,7 +88,9 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
- (BOOL)open:(NSError**)error {
|
||||
int result = inflateInit2(&_stream, 15 + 16);
|
||||
if (result != Z_OK) {
|
||||
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (![super open:error]) {
|
||||
@@ -110,8 +116,9 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
_stream.avail_out = (uInt)maxLength;
|
||||
int result = inflate(&_stream, Z_NO_FLUSH);
|
||||
if ((result != Z_OK) && (result != Z_STREAM_END)) {
|
||||
ARC_RELEASE(decodedData);
|
||||
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
length += maxLength - _stream.avail_out;
|
||||
@@ -125,7 +132,6 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
}
|
||||
decodedData.length = length;
|
||||
BOOL success = length ? [super writeData:decodedData error:error] : YES; // No need to call writer if we have no data yet
|
||||
ARC_RELEASE(decodedData);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -151,6 +157,8 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
NSString* _noneMatch;
|
||||
NSRange _range;
|
||||
BOOL _gzipAccepted;
|
||||
NSData* _localAddress;
|
||||
NSData* _remoteAddress;
|
||||
|
||||
BOOL _opened;
|
||||
NSMutableArray* _decoders;
|
||||
@@ -162,24 +170,24 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
@implementation GCDWebServerRequest : NSObject
|
||||
|
||||
@synthesize method=_method, URL=_url, headers=_headers, path=_path, query=_query, contentType=_type, contentLength=_length, ifModifiedSince=_modifiedSince, ifNoneMatch=_noneMatch,
|
||||
byteRange=_range, acceptsGzipContentEncoding=_gzipAccepted, usesChunkedTransferEncoding=_chunked;
|
||||
byteRange=_range, acceptsGzipContentEncoding=_gzipAccepted, usesChunkedTransferEncoding=_chunked, localAddressData=_localAddress, remoteAddressData=_remoteAddress;
|
||||
|
||||
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
|
||||
if ((self = [super init])) {
|
||||
_method = [method copy];
|
||||
_url = ARC_RETAIN(url);
|
||||
_headers = ARC_RETAIN(headers);
|
||||
_url = url;
|
||||
_headers = headers;
|
||||
_path = [path copy];
|
||||
_query = ARC_RETAIN(query);
|
||||
_query = query;
|
||||
|
||||
_type = ARC_RETAIN(GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Content-Type"]));
|
||||
_type = GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Content-Type"]);
|
||||
_chunked = [GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Transfer-Encoding"]) isEqualToString:@"chunked"];
|
||||
NSString* lengthHeader = [_headers objectForKey:@"Content-Length"];
|
||||
if (lengthHeader) {
|
||||
NSInteger length = [lengthHeader integerValue];
|
||||
if (_chunked || (length < 0)) {
|
||||
GWS_LOG_WARNING(@"Invalid 'Content-Length' header '%@' for '%@' request on \"%@\"", lengthHeader, _method, _url);
|
||||
GWS_DNOT_REACHED();
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
_length = length;
|
||||
@@ -193,9 +201,8 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
_length = NSUIntegerMax;
|
||||
} else {
|
||||
if (_type) {
|
||||
GWS_DNOT_REACHED();
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
GWS_LOG_WARNING(@"Ignoring 'Content-Type' header for '%@' request on \"%@\"", _method, _url);
|
||||
_type = nil; // Content-Type without Content-Length or chunked-encoding doesn't make sense
|
||||
}
|
||||
_length = NSUIntegerMax;
|
||||
}
|
||||
@@ -204,7 +211,7 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
if (modifiedHeader) {
|
||||
_modifiedSince = [GCDWebServerParseRFC822(modifiedHeader) copy];
|
||||
}
|
||||
_noneMatch = ARC_RETAIN([_headers objectForKey:@"If-None-Match"]);
|
||||
_noneMatch = [_headers objectForKey:@"If-None-Match"];
|
||||
|
||||
_range = NSMakeRange(NSUIntegerMax, 0);
|
||||
NSString* rangeHeader = GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Range"]);
|
||||
@@ -246,21 +253,6 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_method);
|
||||
ARC_RELEASE(_url);
|
||||
ARC_RELEASE(_headers);
|
||||
ARC_RELEASE(_path);
|
||||
ARC_RELEASE(_query);
|
||||
ARC_RELEASE(_type);
|
||||
ARC_RELEASE(_modifiedSince);
|
||||
ARC_RELEASE(_noneMatch);
|
||||
ARC_RELEASE(_decoders);
|
||||
ARC_RELEASE(_attributes);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)hasBody {
|
||||
return _type ? YES : NO;
|
||||
}
|
||||
@@ -290,7 +282,6 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
if ([GCDWebServerNormalizeHeaderValue([self.headers objectForKey:@"Content-Encoding"]) isEqualToString:@"gzip"]) {
|
||||
GCDWebServerGZipDecoder* decoder = [[GCDWebServerGZipDecoder alloc] initWithRequest:self writer:_writer];
|
||||
[_decoders addObject:decoder];
|
||||
ARC_RELEASE(decoder);
|
||||
_writer = decoder;
|
||||
}
|
||||
}
|
||||
@@ -320,6 +311,14 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
|
||||
[_attributes setValue:attribute forKey:key];
|
||||
}
|
||||
|
||||
- (NSString*)localAddressString {
|
||||
return GCDWebServerStringFromSockAddr(_localAddress.bytes, YES);
|
||||
}
|
||||
|
||||
- (NSString*)remoteAddressString {
|
||||
return GCDWebServerStringFromSockAddr(_remoteAddress.bytes, YES);
|
||||
}
|
||||
|
||||
- (NSString*)description {
|
||||
NSMutableString* description = [NSMutableString stringWithFormat:@"%@ %@", _method, _path];
|
||||
for (NSString* argument in [[_query allKeys] sortedArrayUsingSelector:@selector(compare:)]) {
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import <zlib.h>
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
@@ -90,7 +94,9 @@
|
||||
- (BOOL)open:(NSError**)error {
|
||||
int result = deflateInit2(&_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
|
||||
if (result != Z_OK) {
|
||||
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (![super open:error]) {
|
||||
@@ -126,8 +132,9 @@
|
||||
if (result == Z_STREAM_END) {
|
||||
_finished = YES;
|
||||
} else if (result != Z_OK) {
|
||||
ARC_RELEASE(encodedData);
|
||||
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
length += maxLength - _stream.avail_out;
|
||||
@@ -140,7 +147,7 @@
|
||||
} while (length == 0); // Make sure we don't return an empty NSData if not in finished state
|
||||
encodedData.length = length;
|
||||
}
|
||||
return ARC_AUTORELEASE(encodedData);
|
||||
return encodedData;
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
@@ -174,7 +181,7 @@
|
||||
gzipContentEncodingEnabled=_gzipped, additionalHeaders=_headers;
|
||||
|
||||
+ (instancetype)response {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] init]);
|
||||
return [[[self class] alloc] init];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
@@ -189,16 +196,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_type);
|
||||
ARC_RELEASE(_lastModified);
|
||||
ARC_RELEASE(_eTag);
|
||||
ARC_RELEASE(_headers);
|
||||
ARC_RELEASE(_encoders);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (void)setValue:(NSString*)value forAdditionalHeader:(NSString*)header {
|
||||
[_headers setValue:value forKey:header];
|
||||
}
|
||||
@@ -228,7 +225,6 @@
|
||||
if (_gzipped) {
|
||||
GCDWebServerGZipEncoder* encoder = [[GCDWebServerGZipEncoder alloc] initWithResponse:self reader:_reader];
|
||||
[_encoders addObject:encoder];
|
||||
ARC_RELEASE(encoder);
|
||||
_reader = encoder;
|
||||
}
|
||||
}
|
||||
@@ -288,11 +284,11 @@
|
||||
@implementation GCDWebServerResponse (Extensions)
|
||||
|
||||
+ (instancetype)responseWithStatusCode:(NSInteger)statusCode {
|
||||
return ARC_AUTORELEASE([[self alloc] initWithStatusCode:statusCode]);
|
||||
return [[self alloc] initWithStatusCode:statusCode];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithRedirect:(NSURL*)location permanent:(BOOL)permanent {
|
||||
return ARC_AUTORELEASE([[self alloc] initWithRedirect:location permanent:permanent]);
|
||||
return [[self alloc] initWithRedirect:location permanent:permanent];
|
||||
}
|
||||
|
||||
- (instancetype)initWithStatusCode:(NSInteger)statusCode {
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
|
||||
@interface GCDWebServerDataRequest () {
|
||||
@@ -40,14 +44,6 @@
|
||||
|
||||
@synthesize data=_data;
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_data);
|
||||
ARC_RELEASE(_text);
|
||||
ARC_RELEASE(_jsonObject);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)open:(NSError**)error {
|
||||
if (self.contentLength != NSUIntegerMax) {
|
||||
_data = [[NSMutableData alloc] initWithCapacity:self.contentLength];
|
||||
@@ -55,7 +51,9 @@
|
||||
_data = [[NSMutableData alloc] init];
|
||||
}
|
||||
if (_data == nil) {
|
||||
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed allocating memory"}];
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed allocating memory"}];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
@@ -99,7 +97,7 @@
|
||||
if (_jsonObject == nil) {
|
||||
NSString* mimeType = GCDWebServerTruncateHeaderValue(self.contentType);
|
||||
if ([mimeType isEqualToString:@"application/json"] || [mimeType isEqualToString:@"text/json"] || [mimeType isEqualToString:@"text/javascript"]) {
|
||||
_jsonObject = ARC_RETAIN([NSJSONSerialization JSONObjectWithData:_data options:0 error:NULL]);
|
||||
_jsonObject = [NSJSONSerialization JSONObjectWithData:_data options:0 error:NULL];
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
|
||||
@interface GCDWebServerFileRequest () {
|
||||
@@ -40,22 +44,21 @@
|
||||
|
||||
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
|
||||
if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) {
|
||||
_temporaryPath = ARC_RETAIN([NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]);
|
||||
_temporaryPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
unlink([_temporaryPath fileSystemRepresentation]);
|
||||
ARC_RELEASE(_temporaryPath);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)open:(NSError**)error {
|
||||
_file = open([_temporaryPath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (_file <= 0) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
if (error) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
@@ -63,7 +66,9 @@
|
||||
|
||||
- (BOOL)writeData:(NSData*)data error:(NSError**)error {
|
||||
if (write(_file, data.bytes, data.length) != (ssize_t)data.length) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
if (error) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
@@ -71,7 +76,9 @@
|
||||
|
||||
- (BOOL)close:(NSError**)error {
|
||||
if (close(_file) < 0) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
if (error) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
#ifdef __GCDWEBSERVER_ENABLE_TESTING__
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
|
||||
#define kMultiPartBufferSize (256 * 1024)
|
||||
@@ -63,19 +67,11 @@ static NSData* _dashNewlineData = nil;
|
||||
if ((self = [super init])) {
|
||||
_controlName = [name copy];
|
||||
_contentType = [type copy];
|
||||
_mimeType = ARC_RETAIN(GCDWebServerTruncateHeaderValue(_contentType));
|
||||
_mimeType = GCDWebServerTruncateHeaderValue(_contentType);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_controlName);
|
||||
ARC_RELEASE(_contentType);
|
||||
ARC_RELEASE(_mimeType);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface GCDWebServerMultiPartArgument () {
|
||||
@@ -91,7 +87,7 @@ static NSData* _dashNewlineData = nil;
|
||||
|
||||
- (id)initWithControlName:(NSString*)name contentType:(NSString*)type data:(NSData*)data {
|
||||
if ((self = [super initWithControlName:name contentType:type])) {
|
||||
_data = ARC_RETAIN(data);
|
||||
_data = data;
|
||||
|
||||
if ([self.contentType hasPrefix:@"text/"]) {
|
||||
NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset");
|
||||
@@ -101,13 +97,6 @@ static NSData* _dashNewlineData = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_data);
|
||||
ARC_RELEASE(_string);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (NSString*)description {
|
||||
return [NSString stringWithFormat:@"<%@ | '%@' | %lu bytes>", [self class], self.mimeType, (unsigned long)_data.length];
|
||||
}
|
||||
@@ -135,11 +124,6 @@ static NSData* _dashNewlineData = nil;
|
||||
|
||||
- (void)dealloc {
|
||||
unlink([_temporaryPath fileSystemRepresentation]);
|
||||
|
||||
ARC_RELEASE(_fileName);
|
||||
ARC_RELEASE(_temporaryPath);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (NSString*)description {
|
||||
@@ -187,14 +171,13 @@ static NSData* _dashNewlineData = nil;
|
||||
NSData* data = boundary.length ? [[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSASCIIStringEncoding] : nil;
|
||||
if (data == nil) {
|
||||
GWS_DNOT_REACHED();
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
if ((self = [super init])) {
|
||||
_boundary = ARC_RETAIN(data);
|
||||
_defaultcontrolName = ARC_RETAIN(name);
|
||||
_arguments = ARC_RETAIN(arguments);
|
||||
_files = ARC_RETAIN(files);
|
||||
_boundary = data;
|
||||
_defaultcontrolName = name;
|
||||
_arguments = arguments;
|
||||
_files = files;
|
||||
_data = [[NSMutableData alloc] initWithCapacity:kMultiPartBufferSize];
|
||||
_state = kParserState_Start;
|
||||
}
|
||||
@@ -202,23 +185,10 @@ static NSData* _dashNewlineData = nil;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_boundary);
|
||||
ARC_RELEASE(_defaultcontrolName);
|
||||
ARC_RELEASE(_data);
|
||||
ARC_RELEASE(_arguments);
|
||||
ARC_RELEASE(_files);
|
||||
|
||||
ARC_RELEASE(_controlName);
|
||||
ARC_RELEASE(_fileName);
|
||||
ARC_RELEASE(_contentType);
|
||||
if (_tmpFile > 0) {
|
||||
close(_tmpFile);
|
||||
unlink([_tmpPath fileSystemRepresentation]);
|
||||
}
|
||||
ARC_RELEASE(_tmpPath);
|
||||
ARC_RELEASE(_subParser);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2
|
||||
@@ -229,15 +199,10 @@ static NSData* _dashNewlineData = nil;
|
||||
NSRange range = [_data rangeOfData:_newlinesData options:0 range:NSMakeRange(0, _data.length)];
|
||||
if (range.location != NSNotFound) {
|
||||
|
||||
ARC_RELEASE(_controlName);
|
||||
_controlName = nil;
|
||||
ARC_RELEASE(_fileName);
|
||||
_fileName = nil;
|
||||
ARC_RELEASE(_contentType);
|
||||
_contentType = nil;
|
||||
ARC_RELEASE(_tmpPath);
|
||||
_tmpPath = nil;
|
||||
ARC_RELEASE(_subParser);
|
||||
_subParser = nil;
|
||||
NSString* headers = [[NSString alloc] initWithData:[_data subdataWithRange:NSMakeRange(0, range.location)] encoding:NSUTF8StringEncoding];
|
||||
if (headers) {
|
||||
@@ -247,15 +212,15 @@ static NSData* _dashNewlineData = nil;
|
||||
NSString* name = [header substringToIndex:subRange.location];
|
||||
NSString* value = [[header substringFromIndex:(subRange.location + subRange.length)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
if ([name caseInsensitiveCompare:@"Content-Type"] == NSOrderedSame) {
|
||||
_contentType = ARC_RETAIN(GCDWebServerNormalizeHeaderValue(value));
|
||||
_contentType = GCDWebServerNormalizeHeaderValue(value);
|
||||
} else if ([name caseInsensitiveCompare:@"Content-Disposition"] == NSOrderedSame) {
|
||||
NSString* contentDisposition = GCDWebServerNormalizeHeaderValue(value);
|
||||
if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"form-data"]) {
|
||||
_controlName = ARC_RETAIN(GCDWebServerExtractHeaderValueParameter(contentDisposition, @"name"));
|
||||
_fileName = ARC_RETAIN(GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename"));
|
||||
_controlName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"name");
|
||||
_fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename");
|
||||
} else if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"file"]) {
|
||||
_controlName = ARC_RETAIN(_defaultcontrolName);
|
||||
_fileName = ARC_RETAIN(GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename"));
|
||||
_controlName = _defaultcontrolName;
|
||||
_fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -265,7 +230,6 @@ static NSData* _dashNewlineData = nil;
|
||||
if (_contentType == nil) {
|
||||
_contentType = @"text/plain";
|
||||
}
|
||||
ARC_RELEASE(headers);
|
||||
} else {
|
||||
GWS_LOG_ERROR(@"Failed decoding headers in part of 'multipart/form-data'");
|
||||
GWS_DNOT_REACHED();
|
||||
@@ -314,7 +278,6 @@ static NSData* _dashNewlineData = nil;
|
||||
GWS_DNOT_REACHED();
|
||||
success = NO;
|
||||
}
|
||||
ARC_RELEASE(_subParser);
|
||||
_subParser = nil;
|
||||
} else if (_tmpPath) {
|
||||
ssize_t result = write(_tmpFile, dataBytes, dataLength);
|
||||
@@ -323,7 +286,6 @@ static NSData* _dashNewlineData = nil;
|
||||
_tmpFile = 0;
|
||||
GCDWebServerMultiPartFile* file = [[GCDWebServerMultiPartFile alloc] initWithControlName:_controlName contentType:_contentType fileName:_fileName temporaryPath:_tmpPath];
|
||||
[_files addObject:file];
|
||||
ARC_RELEASE(file);
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
success = NO;
|
||||
@@ -332,14 +294,11 @@ static NSData* _dashNewlineData = nil;
|
||||
GWS_DNOT_REACHED();
|
||||
success = NO;
|
||||
}
|
||||
ARC_RELEASE(_tmpPath);
|
||||
_tmpPath = nil;
|
||||
} else {
|
||||
NSData* data = [[NSData alloc] initWithBytes:(void*)dataBytes length:dataLength];
|
||||
GCDWebServerMultiPartArgument* argument = [[GCDWebServerMultiPartArgument alloc] initWithControlName:_controlName contentType:_contentType data:data];
|
||||
[_arguments addObject:argument];
|
||||
ARC_RELEASE(argument);
|
||||
ARC_RELEASE(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,18 +372,13 @@ static NSData* _dashNewlineData = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_arguments);
|
||||
ARC_RELEASE(_files);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)open:(NSError**)error {
|
||||
NSString* boundary = GCDWebServerExtractHeaderValueParameter(self.contentType, @"boundary");
|
||||
_parser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:nil arguments:_arguments files:_files];
|
||||
if (_parser == nil) {
|
||||
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed starting to parse multipart form data"}];
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed starting to parse multipart form data"}];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
@@ -432,7 +386,9 @@ static NSData* _dashNewlineData = nil;
|
||||
|
||||
- (BOOL)writeData:(NSData*)data error:(NSError**)error {
|
||||
if (![_parser appendBytes:data.bytes length:data.length]) {
|
||||
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed continuing to parse multipart form data"}];
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed continuing to parse multipart form data"}];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
@@ -440,10 +396,11 @@ static NSData* _dashNewlineData = nil;
|
||||
|
||||
- (BOOL)close:(NSError**)error {
|
||||
BOOL atEnd = [_parser isAtEnd];
|
||||
ARC_RELEASE(_parser);
|
||||
_parser = nil;
|
||||
if (!atEnd) {
|
||||
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed finishing to parse multipart form data"}];
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed finishing to parse multipart form data"}];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
|
||||
@interface GCDWebServerURLEncodedFormRequest () {
|
||||
@@ -41,12 +45,6 @@
|
||||
return @"application/x-www-form-urlencoded";
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_arguments);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)close:(NSError**)error {
|
||||
if (![super close:error]) {
|
||||
return NO;
|
||||
@@ -54,9 +52,8 @@
|
||||
|
||||
NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset");
|
||||
NSString* string = [[NSString alloc] initWithData:self.data encoding:GCDWebServerStringEncodingFromCharset(charset)];
|
||||
_arguments = ARC_RETAIN(GCDWebServerParseURLEncodedForm(string));
|
||||
_arguments = GCDWebServerParseURLEncodedForm(string);
|
||||
GWS_DCHECK(_arguments);
|
||||
ARC_RELEASE(string);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
|
||||
@interface GCDWebServerDataResponse () {
|
||||
@@ -37,18 +41,17 @@
|
||||
@implementation GCDWebServerDataResponse
|
||||
|
||||
+ (instancetype)responseWithData:(NSData*)data contentType:(NSString*)type {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithData:data contentType:type]);
|
||||
return [[[self class] alloc] initWithData:data contentType:type];
|
||||
}
|
||||
|
||||
- (instancetype)initWithData:(NSData*)data contentType:(NSString*)type {
|
||||
if (data == nil) {
|
||||
GWS_DNOT_REACHED();
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ((self = [super init])) {
|
||||
_data = ARC_RETAIN(data);
|
||||
_data = data;
|
||||
|
||||
self.contentType = type;
|
||||
self.contentLength = data.length;
|
||||
@@ -56,12 +59,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_data);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (NSData*)readData:(NSError**)error {
|
||||
NSData* data;
|
||||
if (_done) {
|
||||
@@ -85,30 +82,29 @@
|
||||
@implementation GCDWebServerDataResponse (Extensions)
|
||||
|
||||
+ (instancetype)responseWithText:(NSString*)text {
|
||||
return ARC_AUTORELEASE([[self alloc] initWithText:text]);
|
||||
return [[self alloc] initWithText:text];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithHTML:(NSString*)html {
|
||||
return ARC_AUTORELEASE([[self alloc] initWithHTML:html]);
|
||||
return [[self alloc] initWithHTML:html];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithHTMLTemplate:(NSString*)path variables:(NSDictionary*)variables {
|
||||
return ARC_AUTORELEASE([[self alloc] initWithHTMLTemplate:path variables:variables]);
|
||||
return [[self alloc] initWithHTMLTemplate:path variables:variables];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithJSONObject:(id)object {
|
||||
return ARC_AUTORELEASE([[self alloc] initWithJSONObject:object]);
|
||||
return [[self alloc] initWithJSONObject:object];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithJSONObject:(id)object contentType:(NSString*)type {
|
||||
return ARC_AUTORELEASE([[self alloc] initWithJSONObject:object contentType:type]);
|
||||
return [[self alloc] initWithJSONObject:object contentType:type];
|
||||
}
|
||||
|
||||
- (instancetype)initWithText:(NSString*)text {
|
||||
NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding];
|
||||
if (data == nil) {
|
||||
GWS_DNOT_REACHED();
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
return [self initWithData:data contentType:@"text/plain; charset=utf-8"];
|
||||
@@ -118,7 +114,6 @@
|
||||
NSData* data = [html dataUsingEncoding:NSUTF8StringEncoding];
|
||||
if (data == nil) {
|
||||
GWS_DNOT_REACHED();
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
return [self initWithData:data contentType:@"text/html; charset=utf-8"];
|
||||
@@ -130,7 +125,6 @@
|
||||
[html replaceOccurrencesOfString:[NSString stringWithFormat:@"%%%@%%", key] withString:value options:0 range:NSMakeRange(0, html.length)];
|
||||
}];
|
||||
id response = [self initWithHTML:html];
|
||||
ARC_RELEASE(html);
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -141,7 +135,6 @@
|
||||
- (instancetype)initWithJSONObject:(id)object contentType:(NSString*)type {
|
||||
NSData* data = [NSJSONSerialization dataWithJSONObject:object options:0 error:NULL];
|
||||
if (data == nil) {
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
return [self initWithData:data contentType:type];
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
|
||||
@interface GCDWebServerErrorResponse ()
|
||||
@@ -37,7 +41,7 @@
|
||||
GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500));
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
GCDWebServerErrorResponse* response = ARC_AUTORELEASE([[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments]);
|
||||
GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments];
|
||||
va_end(arguments);
|
||||
return response;
|
||||
}
|
||||
@@ -46,7 +50,7 @@
|
||||
GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600));
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
GCDWebServerErrorResponse* response = ARC_AUTORELEASE([[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments]);
|
||||
GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments];
|
||||
va_end(arguments);
|
||||
return response;
|
||||
}
|
||||
@@ -55,7 +59,7 @@
|
||||
GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500));
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
GCDWebServerErrorResponse* response = ARC_AUTORELEASE([[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments]);
|
||||
GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments];
|
||||
va_end(arguments);
|
||||
return response;
|
||||
}
|
||||
@@ -64,7 +68,7 @@
|
||||
GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600));
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
GCDWebServerErrorResponse* response = ARC_AUTORELEASE([[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments]);
|
||||
GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments];
|
||||
va_end(arguments);
|
||||
return response;
|
||||
}
|
||||
@@ -82,7 +86,6 @@ static inline NSString* _EscapeHTMLString(NSString* string) {
|
||||
if ((self = [self initWithHTML:html])) {
|
||||
self.statusCode = statusCode;
|
||||
}
|
||||
ARC_RELEASE(message);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import <sys/stat.h>
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
@@ -43,19 +47,19 @@
|
||||
@implementation GCDWebServerFileResponse
|
||||
|
||||
+ (instancetype)responseWithFile:(NSString*)path {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path]);
|
||||
return [[[self class] alloc] initWithFile:path];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithFile:(NSString*)path isAttachment:(BOOL)attachment {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path isAttachment:attachment]);
|
||||
return [[[self class] alloc] initWithFile:path isAttachment:attachment];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path byteRange:range]);
|
||||
return [[[self class] alloc] initWithFile:path byteRange:range];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path byteRange:range isAttachment:attachment]);
|
||||
return [[[self class] alloc] initWithFile:path byteRange:range isAttachment:attachment];
|
||||
}
|
||||
|
||||
- (instancetype)initWithFile:(NSString*)path {
|
||||
@@ -78,13 +82,11 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
|
||||
struct stat info;
|
||||
if (lstat([path fileSystemRepresentation], &info) || !(info.st_mode & S_IFREG)) {
|
||||
GWS_DNOT_REACHED();
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
#ifndef __LP64__
|
||||
if (info.st_size >= (off_t)4294967295) { // In 32 bit mode, we can't handle files greater than 4 GiBs (don't use "NSUIntegerMax" here to avoid potential unsigned to signed conversion issues)
|
||||
GWS_DNOT_REACHED();
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
@@ -100,7 +102,6 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
|
||||
range.location = fileSize - range.length;
|
||||
}
|
||||
if (range.length == 0) {
|
||||
ARC_RELEASE(self);
|
||||
return nil; // TODO: Return 416 status code and "Content-Range: bytes */{file length}" header
|
||||
}
|
||||
} else {
|
||||
@@ -125,7 +126,6 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
|
||||
if (lossyFileName) {
|
||||
NSString* value = [NSString stringWithFormat:@"attachment; filename=\"%@\"; filename*=UTF-8''%@", lossyFileName, GCDWebServerEscapeURLString(fileName)];
|
||||
[self setValue:value forAdditionalHeader:@"Content-Disposition"];
|
||||
ARC_RELEASE(lossyFileName);
|
||||
} else {
|
||||
GWS_DNOT_REACHED();
|
||||
}
|
||||
@@ -139,20 +139,18 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_path);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)open:(NSError**)error {
|
||||
_file = open([_path fileSystemRepresentation], O_NOFOLLOW | O_RDONLY);
|
||||
if (_file <= 0) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
if (error) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (lseek(_file, _offset, SEEK_SET) != (off_t)_offset) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
if (error) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
}
|
||||
close(_file);
|
||||
return NO;
|
||||
}
|
||||
@@ -164,14 +162,16 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
|
||||
NSMutableData* data = [[NSMutableData alloc] initWithLength:length];
|
||||
ssize_t result = read(_file, data.mutableBytes, length);
|
||||
if (result < 0) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
if (error) {
|
||||
*error = GCDWebServerMakePosixError(errno);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
if (result > 0) {
|
||||
[data setLength:result];
|
||||
_size -= result;
|
||||
}
|
||||
return ARC_AUTORELEASE(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
/**
|
||||
* The GCDWebServerStreamBlock is called to stream the data for the HTTP body.
|
||||
* The block must return empty NSData when done or nil on error and set the
|
||||
* "error" argument which is guaranteed to be non-NULL.
|
||||
* The block must return either a chunk of data, an empty NSData when done, or
|
||||
* nil on error and set the "error" argument which is guaranteed to be non-NULL.
|
||||
*/
|
||||
typedef NSData* (^GCDWebServerStreamBlock)(NSError** error);
|
||||
|
||||
@@ -39,13 +39,10 @@ typedef NSData* (^GCDWebServerStreamBlock)(NSError** error);
|
||||
* except the streamed data can be returned at a later time allowing for
|
||||
* truly asynchronous generation of the data.
|
||||
*
|
||||
* The block must return empty NSData when done or nil on error and set the
|
||||
* "error" argument which is guaranteed to be non-NULL.
|
||||
* The block must call "completionBlock" passing the new chunk of data when ready,
|
||||
* an empty NSData when done, or nil on error and pass a NSError.
|
||||
*
|
||||
* The block must regularly call "completionBlock" passing new streamed data.
|
||||
* Eventually it must call "completionBlock" passing an empty NSData indicating
|
||||
* the end of the stream has been reached, or pass nil and an NSError in case of
|
||||
* error.
|
||||
* The block cannot call "completionBlock" more than once per invocation.
|
||||
*/
|
||||
typedef void (^GCDWebServerAsyncStreamBlock)(GCDWebServerBodyReaderCompletionBlock completionBlock);
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebServer requires ARC
|
||||
#endif
|
||||
|
||||
#import "GCDWebServerPrivate.h"
|
||||
|
||||
@interface GCDWebServerStreamedResponse () {
|
||||
@@ -36,11 +40,11 @@
|
||||
@implementation GCDWebServerStreamedResponse
|
||||
|
||||
+ (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type streamBlock:block]);
|
||||
return [[[self class] alloc] initWithContentType:type streamBlock:block];
|
||||
}
|
||||
|
||||
+ (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type asyncStreamBlock:block]);
|
||||
return [[[self class] alloc] initWithContentType:type asyncStreamBlock:block];
|
||||
}
|
||||
|
||||
- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
|
||||
@@ -62,12 +66,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
ARC_RELEASE(_block);
|
||||
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (void)asyncReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block {
|
||||
_block(block);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<div id="alerts"></div>
|
||||
|
||||
<div class="btn-toolbar">
|
||||
<button type="button" class="btn btn-primary fileinput-button">
|
||||
<button type="button" class="btn btn-primary fileinput-button" id="upload-file">
|
||||
<span class="glyphicon glyphicon-upload"></span> Upload Files…
|
||||
<input id="fileupload" type="file" name="files[]" multiple>
|
||||
</button>
|
||||
|
||||
@@ -178,6 +178,17 @@ function _reload(path) {
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
// Workaround Firefox and IE not showing file selection dialog when clicking on "upload-file" <button>
|
||||
// Making it a <div> instead also works but then it the button doesn't work anymore with tab selection or accessibility
|
||||
$("#upload-file").click(function(event) {
|
||||
$("#fileupload").click();
|
||||
});
|
||||
|
||||
// Prevent event bubbling when using workaround above
|
||||
$("#fileupload").click(function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
$("#fileupload").fileupload({
|
||||
dropZone: $(document),
|
||||
pasteZone: null,
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error GCDWebUploader requires ARC
|
||||
#endif
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <UIKit/UIKit.h>
|
||||
@@ -288,21 +292,16 @@
|
||||
@synthesize uploadDirectory=_uploadDirectory, allowedFileExtensions=_allowedExtensions, allowHiddenItems=_allowHidden,
|
||||
title=_title, header=_header, prologue=_prologue, epilogue=_epilogue, footer=_footer;
|
||||
|
||||
@dynamic delegate;
|
||||
|
||||
- (instancetype)initWithUploadDirectory:(NSString*)path {
|
||||
if ((self = [super init])) {
|
||||
NSBundle* siteBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"GCDWebUploader" ofType:@"bundle"]];
|
||||
if (siteBundle == nil) {
|
||||
#if !__has_feature(objc_arc)
|
||||
[self release];
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
_uploadDirectory = [[path stringByStandardizingPath] copy];
|
||||
#if __has_feature(objc_arc)
|
||||
GCDWebUploader* __unsafe_unretained server = self;
|
||||
#else
|
||||
__block GCDWebUploader* server = self;
|
||||
#endif
|
||||
|
||||
// Resource files
|
||||
[self addGETHandlerForBasePath:@"/" directoryPath:[siteBundle resourcePath] indexFilename:nil cacheAge:3600 allowRangeRequests:NO];
|
||||
@@ -313,11 +312,7 @@
|
||||
#if TARGET_OS_IPHONE
|
||||
NSString* device = [[UIDevice currentDevice] name];
|
||||
#else
|
||||
#if __has_feature(objc_arc)
|
||||
NSString* device = CFBridgingRelease(SCDynamicStoreCopyComputerName(NULL, NULL));
|
||||
#else
|
||||
NSString* device = [(id)SCDynamicStoreCopyComputerName(NULL, NULL) autorelease];
|
||||
#endif
|
||||
#endif
|
||||
NSString* title = server.title;
|
||||
if (title == nil) {
|
||||
@@ -401,22 +396,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
|
||||
- (void)dealloc {
|
||||
[_uploadDirectory release];
|
||||
[_allowedExtensions release];
|
||||
[_title release];
|
||||
[_header release];
|
||||
[_prologue release];
|
||||
[_epilogue release];
|
||||
[_footer release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@implementation GCDWebUploader (Subclassing)
|
||||
|
||||
40
Mac/main.m
40
Mac/main.m
@@ -141,9 +141,10 @@ int main(int argc, const char* argv[]) {
|
||||
NSString* authenticationRealm = nil;
|
||||
NSString* authenticationUser = nil;
|
||||
NSString* authenticationPassword = nil;
|
||||
BOOL bindToLocalhost = NO;
|
||||
|
||||
if (argc == 1) {
|
||||
fprintf(stdout, "Usage: %s [-mode webServer | htmlPage | htmlForm | htmlFileUpload | webDAV | webUploader | streamingResponse | asyncResponse] [-record] [-root directory] [-tests directory] [-authenticationMethod Basic | Digest] [-authenticationRealm realm] [-authenticationUser user] [-authenticationPassword password]\n\n", basename((char*)argv[0]));
|
||||
fprintf(stdout, "Usage: %s [-mode webServer | htmlPage | htmlForm | htmlFileUpload | webDAV | webUploader | streamingResponse | asyncResponse] [-record] [-root directory] [-tests directory] [-authenticationMethod Basic | Digest] [-authenticationRealm realm] [-authenticationUser user] [-authenticationPassword password] [--localhost]\n\n", basename((char*)argv[0]));
|
||||
} else {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] != '-') {
|
||||
@@ -188,6 +189,8 @@ int main(int argc, const char* argv[]) {
|
||||
} else if (!strcmp(argv[i], "-authenticationPassword") && (i + 1 < argc)) {
|
||||
++i;
|
||||
authenticationPassword = [NSString stringWithUTF8String:argv[i]];
|
||||
} else if (!strcmp(argv[i], "--localhost")) {
|
||||
bindToLocalhost = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,7 +357,7 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stdout, "Running in Async Response mode");
|
||||
webServer = [[GCDWebServer alloc] init];
|
||||
[webServer addHandlerForMethod:@"GET"
|
||||
path:@"/"
|
||||
path:@"/async"
|
||||
requestClass:[GCDWebServerRequest class]
|
||||
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
|
||||
@@ -363,16 +366,34 @@ int main(int argc, const char* argv[]) {
|
||||
completionBlock(response);
|
||||
});
|
||||
|
||||
}];
|
||||
[webServer addHandlerForMethod:@"GET"
|
||||
path:@"/async2"
|
||||
requestClass:[GCDWebServerRequest class]
|
||||
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock handlerCompletionBlock) {
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
__block int countDown = 10;
|
||||
GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:@"text/plain" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock readerCompletionBlock) {
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
|
||||
NSData* data = countDown ? [[NSString stringWithFormat:@"%i\n", countDown--] dataUsingEncoding:NSUTF8StringEncoding] : [NSData data];
|
||||
readerCompletionBlock(data, nil);
|
||||
|
||||
});
|
||||
|
||||
}];
|
||||
handlerCompletionBlock(response);
|
||||
|
||||
});
|
||||
|
||||
}];
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#if __has_feature(objc_arc)
|
||||
fprintf(stdout, " (ARC is ON)\n");
|
||||
#else
|
||||
fprintf(stdout, " (ARC is OFF)\n");
|
||||
#endif
|
||||
|
||||
if (webServer) {
|
||||
Delegate* delegate = [[Delegate alloc] init];
|
||||
@@ -391,6 +412,7 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stdout, "\n");
|
||||
NSMutableDictionary* options = [NSMutableDictionary dictionary];
|
||||
[options setObject:@8080 forKey:GCDWebServerOption_Port];
|
||||
[options setObject:@(bindToLocalhost) forKey:GCDWebServerOption_BindToLocalhost];
|
||||
[options setObject:@"" forKey:GCDWebServerOption_BonjourName];
|
||||
if (authenticationUser && authenticationPassword) {
|
||||
[options setValue:authenticationRealm forKey:GCDWebServerOption_AuthenticationRealm];
|
||||
@@ -406,10 +428,6 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
}
|
||||
webServer.delegate = nil;
|
||||
#if !__has_feature(objc_arc)
|
||||
[delegate release];
|
||||
[webServer release];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
138
README.md
138
README.md
@@ -6,8 +6,6 @@ Overview
|
||||
[](https://github.com/swisspol/GCDWebServer)
|
||||
[](LICENSE)
|
||||
|
||||
*ANNOUNCEMENT: If you like GCDWebServer, check out [XLFacility](https://github.com/swisspol/XLFacility), an elegant and powerful logging facility for OS X & iOS by the same author and also open-source. XLFacility can be used seemlessly to handle logging from GCDWebServer (see "Logging in GCDWebServer" below).*
|
||||
|
||||
GCDWebServer is a modern and lightweight GCD based HTTP 1.1 server designed to be embedded in OS X & iOS 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
|
||||
@@ -38,13 +36,14 @@ What's not supported (but not really required from an embedded HTTP server):
|
||||
Requirements:
|
||||
* OS X 10.7 or later (x86_64)
|
||||
* iOS 5.0 or later (armv7, armv7s or arm64)
|
||||
* ARC memory management only (if you need MRC support use GCDWebServer 3.1 and earlier)
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
Download or check out the [latest release](https://github.com/swisspol/GCDWebServer/releases) 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.
|
||||
|
||||
Alternatively, you can install GCDWebServer using [CocoaPods](http://cocoapods.org/) by simply adding this line to your Xcode project's Podfile:
|
||||
Alternatively, you can install GCDWebServer using [CocoaPods](http://cocoapods.org/) by simply adding this line to your Podfile:
|
||||
```
|
||||
pod "GCDWebServer", "~> 3.0"
|
||||
```
|
||||
@@ -57,11 +56,22 @@ Or this line for GCDWebDAVServer:
|
||||
pod "GCDWebServer/WebDAV", "~> 3.0"
|
||||
```
|
||||
|
||||
And finally run `$ pod install`.
|
||||
|
||||
You can also use [Carthage](https://github.com/Carthage/Carthage) by adding this line to your Cartfile:
|
||||
```
|
||||
github "swisspol/GCDWebServer" "master"
|
||||
```
|
||||
|
||||
Then run `$ carthage update` and add the generated frameworks to your Xcode projects (see [Carthage instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application)).
|
||||
|
||||
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.
|
||||
|
||||
**OS X version (command line tool):**
|
||||
```objectivec
|
||||
#import "GCDWebServer.h"
|
||||
@@ -136,7 +146,7 @@ import Foundation
|
||||
|
||||
let webServer = GCDWebServer()
|
||||
|
||||
webServer.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerRequest.self) { request in
|
||||
webServer.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerRequest.self, processBlock: {request in
|
||||
return GCDWebServerDataResponse(HTML:"<html><body><p>Hello World</p></body></html>")
|
||||
}
|
||||
|
||||
@@ -151,65 +161,6 @@ println("Visit \(webServer.serverURL) in your web browser")
|
||||
#import "GCDWebServerDataResponse.h"
|
||||
```
|
||||
|
||||
Asynchronous HTTP Responses
|
||||
===========================
|
||||
|
||||
New in GCDWebServer 3.0 is the ability to process HTTP requests aysnchronously 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:
|
||||
```objectivec
|
||||
[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:
|
||||
```objectivec
|
||||
[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:
|
||||
```objectivec
|
||||
[webServer addDefaultHandlerForMethod:@"GET"
|
||||
requestClass:[GCDWebServerRequest class]
|
||||
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
|
||||
|
||||
GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:@"text/html" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) {
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
completionBlock([@"<html><body><p>Hello" dataUsingEncoding:NSUTF8StringEncoding], nil); // Generate the 1st part of the stream data
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
completionBlock([@"World</p></body></html>" dataUsingEncoding:NSUTF8StringEncoding], nil); // Generate the 2nd part of the stream data
|
||||
|
||||
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!*
|
||||
|
||||
Web Based Uploads in iOS Apps
|
||||
=============================
|
||||
|
||||
@@ -273,6 +224,7 @@ 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"](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) header should be set):
|
||||
|
||||
**OS X version (command line tool):**
|
||||
```objectivec
|
||||
#import "GCDWebServer.h"
|
||||
|
||||
@@ -317,6 +269,66 @@ Handlers require 2 GCD blocks:
|
||||
|
||||
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 aysnchronously 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:
|
||||
```objectivec
|
||||
[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:
|
||||
```objectivec
|
||||
[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:
|
||||
```objectivec
|
||||
[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
|
||||
===========================================
|
||||
|
||||
|
||||
74
Run-Tests.sh
74
Run-Tests.sh
@@ -11,13 +11,11 @@ OSX_TARGET="GCDWebServer (Mac)"
|
||||
IOS_TARGET="GCDWebServer (iOS)"
|
||||
CONFIGURATION="Release"
|
||||
|
||||
MRC_BUILD_DIR="/tmp/GCDWebServer-MRC"
|
||||
MRC_PRODUCT="$MRC_BUILD_DIR/$CONFIGURATION/GCDWebServer"
|
||||
ARC_BUILD_DIR="/tmp/GCDWebServer-ARC"
|
||||
ARC_PRODUCT="$ARC_BUILD_DIR/$CONFIGURATION/GCDWebServer"
|
||||
BUILD_DIR="/tmp/GCDWebServer-Build"
|
||||
PRODUCT="$BUILD_DIR/$CONFIGURATION/GCDWebServer"
|
||||
|
||||
PAYLOAD_ZIP="Tests/Payload.zip"
|
||||
PAYLOAD_DIR="/tmp/GCDWebServer"
|
||||
PAYLOAD_DIR="/tmp/GCDWebServer-Payload"
|
||||
|
||||
function runTests {
|
||||
rm -rf "$PAYLOAD_DIR"
|
||||
@@ -26,61 +24,37 @@ function runTests {
|
||||
if [ "$4" != "" ]; then
|
||||
cp -f "$4" "$PAYLOAD_DIR/Payload"
|
||||
pushd "$PAYLOAD_DIR/Payload"
|
||||
SetFile -d "1/1/2014 00:00:00" -m "1/1/2014 00:00:00" `basename "$4"`
|
||||
TZ=GMT SetFile -d "1/1/2014 00:00:00" -m "1/1/2014 00:00:00" `basename "$4"`
|
||||
popd
|
||||
fi
|
||||
logLevel=2 $1 -mode "$2" -root "$PAYLOAD_DIR/Payload" -tests "$3"
|
||||
}
|
||||
|
||||
# Build for iOS in manual memory management mode and for oldest deployment target (TODO: run tests on iOS)
|
||||
rm -rf "$MRC_BUILD_DIR"
|
||||
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$MRC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=NO" "IPHONEOS_DEPLOYMENT_TARGET=5.1.1" > /dev/null
|
||||
# Build for iOS for oldest deployment target (TODO: run tests on iOS)
|
||||
rm -rf "$BUILD_DIR"
|
||||
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$BUILD_DIR" "IPHONEOS_DEPLOYMENT_TARGET=5.1.1" > /dev/null
|
||||
|
||||
# Build for iOS in manual memory management mode and for default deployment target (TODO: run tests on iOS)
|
||||
rm -rf "$MRC_BUILD_DIR"
|
||||
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$MRC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=NO" > /dev/null
|
||||
# Build for iOS for default deployment target (TODO: run tests on iOS)
|
||||
rm -rf "$BUILD_DIR"
|
||||
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$BUILD_DIR" > /dev/null
|
||||
|
||||
# Build for iOS in ARC mode and for oldest deployment target (TODO: run tests on iOS)
|
||||
rm -rf "$ARC_BUILD_DIR"
|
||||
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" "IPHONEOS_DEPLOYMENT_TARGET=5.1.1" > /dev/null
|
||||
# Build for OS X for oldest deployment target
|
||||
rm -rf "$BUILD_DIR"
|
||||
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$BUILD_DIR" "MACOSX_DEPLOYMENT_TARGET=10.7" > /dev/null
|
||||
|
||||
# Build for iOS in ARC mode and for default deployment target (TODO: run tests on iOS)
|
||||
rm -rf "$ARC_BUILD_DIR"
|
||||
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" > /dev/null
|
||||
|
||||
# Build for OS X in manual memory management mode and for oldest deployment target
|
||||
rm -rf "$MRC_BUILD_DIR"
|
||||
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$MRC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=NO" "MACOSX_DEPLOYMENT_TARGET=10.7" > /dev/null
|
||||
|
||||
# Build for OS X in manual memory management mode and for default deployment target
|
||||
rm -rf "$MRC_BUILD_DIR"
|
||||
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$MRC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=NO" > /dev/null
|
||||
|
||||
# Build for OS X in ARC mode and for oldest deployment target
|
||||
rm -rf "$ARC_BUILD_DIR"
|
||||
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" "MACOSX_DEPLOYMENT_TARGET=10.7" > /dev/null
|
||||
|
||||
# Build for OS X in ARC mode and for default deployment target
|
||||
rm -rf "$ARC_BUILD_DIR"
|
||||
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" > /dev/null
|
||||
# Build for OS X for default deployment target
|
||||
rm -rf "$BUILD_DIR"
|
||||
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$BUILD_DIR" > /dev/null
|
||||
|
||||
# Run tests
|
||||
runTests $MRC_PRODUCT "htmlForm" "Tests/HTMLForm"
|
||||
runTests $ARC_PRODUCT "htmlForm" "Tests/HTMLForm"
|
||||
runTests $MRC_PRODUCT "htmlFileUpload" "Tests/HTMLFileUpload"
|
||||
runTests $ARC_PRODUCT "htmlFileUpload" "Tests/HTMLFileUpload"
|
||||
runTests $MRC_PRODUCT "webServer" "Tests/WebServer"
|
||||
runTests $ARC_PRODUCT "webServer" "Tests/WebServer"
|
||||
runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Transmit"
|
||||
runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Transmit"
|
||||
runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Cyberduck"
|
||||
runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Cyberduck"
|
||||
runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Finder"
|
||||
runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Finder"
|
||||
runTests $MRC_PRODUCT "webUploader" "Tests/WebUploader"
|
||||
runTests $ARC_PRODUCT "webUploader" "Tests/WebUploader"
|
||||
runTests $MRC_PRODUCT "webServer" "Tests/WebServer-Sample-Movie" "Tests/Sample-Movie.mp4"
|
||||
runTests $ARC_PRODUCT "webServer" "Tests/WebServer-Sample-Movie" "Tests/Sample-Movie.mp4"
|
||||
runTests $PRODUCT "htmlForm" "Tests/HTMLForm"
|
||||
runTests $PRODUCT "htmlFileUpload" "Tests/HTMLFileUpload"
|
||||
runTests $PRODUCT "webServer" "Tests/WebServer"
|
||||
runTests $PRODUCT "webDAV" "Tests/WebDAV-Transmit"
|
||||
runTests $PRODUCT "webDAV" "Tests/WebDAV-Cyberduck"
|
||||
runTests $PRODUCT "webDAV" "Tests/WebDAV-Finder"
|
||||
runTests $PRODUCT "webUploader" "Tests/WebUploader"
|
||||
runTests $PRODUCT "webServer" "Tests/WebServer-Sample-Movie" "Tests/Sample-Movie.mp4"
|
||||
|
||||
# Done
|
||||
echo "\nAll tests completed successfully!"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -36,16 +36,6 @@
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
|
||||
- (void)dealloc {
|
||||
[_window release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
|
||||
CGRect bounds = ([UIScreen instancesRespondToSelector:@selector(nativeBounds)] ? [[UIScreen mainScreen] nativeBounds] : [[UIScreen mainScreen] bounds]);
|
||||
_window = [[UIWindow alloc] initWithFrame:bounds];
|
||||
|
||||
Reference in New Issue
Block a user