mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-02-11 00:00:07 +08:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
628cf6833c | ||
|
|
9392ddadb6 | ||
|
|
5dee044caa | ||
|
|
7c8205caa0 | ||
|
|
965e111280 | ||
|
|
8a69050cca | ||
|
|
a15a49240a | ||
|
|
404b46537e | ||
|
|
811e18e2fa | ||
|
|
78480e004a | ||
|
|
2e587919ca | ||
|
|
544e236144 | ||
|
|
1a1ee2869e | ||
|
|
e665d0a778 | ||
|
|
43cc98ad47 | ||
|
|
1d08a8fcc3 | ||
|
|
2cddc8c939 | ||
|
|
1344ad9e04 | ||
|
|
3eb27a4d7b |
17
.gitignore
vendored
17
.gitignore
vendored
@@ -1,18 +1,3 @@
|
||||
# Xcode
|
||||
.DS_Store
|
||||
build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
*.xcworkspace
|
||||
!default.xcworkspace
|
||||
xcuserdata
|
||||
profile
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
.idea/
|
||||
project.xcworkspace
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
/*
|
||||
Copyright (c) 2012-2013, 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may 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 <COPYRIGHT HOLDER> 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.
|
||||
*/
|
||||
Copyright (c) 2012-2013, 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.
|
||||
*/
|
||||
|
||||
#import "GCDWebServerRequest.h"
|
||||
#import "GCDWebServerResponse.h"
|
||||
@@ -41,6 +41,7 @@ typedef GCDWebServerResponse* (^GCDWebServerProcessBlock)(GCDWebServerRequest* r
|
||||
}
|
||||
@property(nonatomic, readonly, getter=isRunning) BOOL running;
|
||||
@property(nonatomic, readonly) NSUInteger port;
|
||||
@property(nonatomic, readonly) NSString* bonjourName; // Only non-nil if Bonjour registration is active
|
||||
- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock;
|
||||
- (void)removeAllHandlers;
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
@@ -50,9 +50,9 @@ NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension) {
|
||||
if (extension.length) {
|
||||
mimeType = [_overrides objectForKey:extension];
|
||||
if (mimeType == nil) {
|
||||
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)extension, NULL);
|
||||
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (ARC_BRIDGE CFStringRef)extension, NULL);
|
||||
if (uti) {
|
||||
mimeType = [(id)UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType) autorelease];
|
||||
mimeType = ARC_BRIDGE_RELEASE(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType));
|
||||
CFRelease(uti);
|
||||
}
|
||||
}
|
||||
@@ -61,8 +61,8 @@ NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension) {
|
||||
}
|
||||
|
||||
NSString* GCDWebServerUnescapeURLString(NSString* string) {
|
||||
return [(id)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (CFStringRef)string, CFSTR(""),
|
||||
kCFStringEncodingUTF8) autorelease];
|
||||
return ARC_BRIDGE_RELEASE(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (CFStringRef)string, CFSTR(""),
|
||||
kCFStringEncodingUTF8));
|
||||
}
|
||||
|
||||
NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form) {
|
||||
@@ -90,7 +90,7 @@ NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form) {
|
||||
}
|
||||
[scanner setScanLocation:([scanner scanLocation] + 1)];
|
||||
}
|
||||
[scanner release];
|
||||
ARC_RELEASE(scanner);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@@ -105,17 +105,17 @@ static void _SignalHandler(int signal) {
|
||||
|
||||
- (id)initWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock {
|
||||
if ((self = [super init])) {
|
||||
_matchBlock = Block_copy(matchBlock);
|
||||
_processBlock = Block_copy(processBlock);
|
||||
_matchBlock = [matchBlock copy];
|
||||
_processBlock = [processBlock copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
Block_release(_matchBlock);
|
||||
Block_release(_processBlock);
|
||||
ARC_RELEASE(_matchBlock);
|
||||
ARC_RELEASE(_processBlock);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -140,16 +140,21 @@ static void _SignalHandler(int signal) {
|
||||
[self stop];
|
||||
}
|
||||
|
||||
[_handlers release];
|
||||
ARC_RELEASE(_handlers);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (NSString*)bonjourName {
|
||||
CFStringRef name = _service ? CFNetServiceGetName(_service) : NULL;
|
||||
return name && CFStringGetLength(name) ? ARC_BRIDGE_RELEASE(CFStringCreateCopy(kCFAllocatorDefault, name)) : nil;
|
||||
}
|
||||
|
||||
- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)handlerBlock {
|
||||
DCHECK(_source == NULL);
|
||||
GCDWebServerHandler* handler = [[GCDWebServerHandler alloc] initWithMatchBlock:matchBlock processBlock:handlerBlock];
|
||||
[_handlers insertObject:handler atIndex:0];
|
||||
[handler release];
|
||||
ARC_RELEASE(handler);
|
||||
}
|
||||
|
||||
- (void)removeAllHandlers {
|
||||
@@ -166,7 +171,7 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
if (error->error) {
|
||||
LOG_ERROR(@"Bonjour error %i (domain %i)", error->error, (int)error->domain);
|
||||
} else {
|
||||
LOG_VERBOSE(@"Registered Bonjour service \"%@\" with type '%@' on port %i", CFNetServiceGetName(service), CFNetServiceGetType(service), CFNetServiceGetPortNumber(service));
|
||||
LOG_VERBOSE(@"Registered Bonjour service \"%@\" in domain \"%@\" with type '%@' on port %i", CFNetServiceGetName(service), CFNetServiceGetDomain(service), CFNetServiceGetType(service), CFNetServiceGetPortNumber(service));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,8 +217,12 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
|
||||
NSData* data = [NSData dataWithBytes:&addr length:addrlen];
|
||||
Class connectionClass = [[self class] connectionClass];
|
||||
GCDWebServerConnection* connection = [[connectionClass alloc] initWithServer:self address:data socket:socket];
|
||||
[connection release]; // Connection will automatically retain itself while opened
|
||||
GCDWebServerConnection* connection = [[connectionClass alloc] initWithServer:self address:data 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 {
|
||||
LOG_ERROR(@"Failed accepting socket (%i): %s", errno, strerror(errno));
|
||||
}
|
||||
@@ -235,9 +244,9 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
}
|
||||
|
||||
if (name) {
|
||||
_service = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), CFSTR("_http._tcp"), (CFStringRef)name, _port);
|
||||
_service = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), CFSTR("_http._tcp"), (ARC_BRIDGE CFStringRef)name, _port);
|
||||
if (_service) {
|
||||
CFNetServiceClientContext context = {0, self, NULL, NULL, NULL};
|
||||
CFNetServiceClientContext context = {0, (ARC_BRIDGE void*)self, NULL, NULL, NULL};
|
||||
CFNetServiceSetClient(_service, _NetServiceClientCallBack, &context);
|
||||
CFNetServiceScheduleWithRunLoop(_service, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
CFStreamError error = {0};
|
||||
@@ -278,7 +287,7 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
}
|
||||
|
||||
dispatch_source_cancel(_source); // This will close the socket
|
||||
dispatch_release(_source);
|
||||
ARC_DISPATCH_RELEASE(_source);
|
||||
_source = NULL;
|
||||
|
||||
LOG_VERBOSE(@"%@ stopped", [self class]);
|
||||
@@ -326,7 +335,7 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)class processBlock:(GCDWebServerProcessBlock)block {
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
return [[[class alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery] autorelease];
|
||||
return ARC_AUTORELEASE([[class alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
||||
|
||||
} processBlock:block];
|
||||
}
|
||||
@@ -363,6 +372,11 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
|
||||
- (void)addHandlerForBasePath:(NSString*)basePath localPath:(NSString*)localPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge {
|
||||
if ([basePath hasPrefix:@"/"] && [basePath hasSuffix:@"/"]) {
|
||||
#if __has_feature(objc_arc)
|
||||
__unsafe_unretained GCDWebServer* server = self;
|
||||
#else
|
||||
GCDWebServer* server = self;
|
||||
#endif
|
||||
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
|
||||
|
||||
if (![requestMethod isEqualToString:@"GET"]) {
|
||||
@@ -371,7 +385,7 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
if (![urlPath hasPrefix:basePath]) {
|
||||
return nil;
|
||||
}
|
||||
return [[[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery] autorelease];
|
||||
return ARC_AUTORELEASE([[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
||||
|
||||
} processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||
|
||||
@@ -383,12 +397,12 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
if (indexFilename) {
|
||||
NSString* indexPath = [filePath stringByAppendingPathComponent:indexFilename];
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:indexPath isDirectory:&isDirectory] && !isDirectory) {
|
||||
return [self _responseWithContentsOfFile:indexPath];
|
||||
return [server _responseWithContentsOfFile:indexPath];
|
||||
}
|
||||
}
|
||||
response = [self _responseWithContentsOfDirectory:filePath];
|
||||
response = [server _responseWithContentsOfDirectory:filePath];
|
||||
} else {
|
||||
response = [self _responseWithContentsOfFile:filePath];
|
||||
response = [server _responseWithContentsOfFile:filePath];
|
||||
}
|
||||
}
|
||||
if (response) {
|
||||
@@ -414,7 +428,7 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
if ([urlPath caseInsensitiveCompare:path] != NSOrderedSame) {
|
||||
return nil;
|
||||
}
|
||||
return [[[class alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery] autorelease];
|
||||
return ARC_AUTORELEASE([[class alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
||||
|
||||
} processBlock:block];
|
||||
} else {
|
||||
@@ -433,7 +447,7 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
|
||||
if ([expression firstMatchInString:urlPath options:0 range:NSMakeRange(0, urlPath.length)] == nil) {
|
||||
return nil;
|
||||
}
|
||||
return [[[class alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery] autorelease];
|
||||
return ARC_AUTORELEASE([[class alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]);
|
||||
|
||||
} processBlock:block];
|
||||
} else {
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
/*
|
||||
Copyright (c) 2012-2013, 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may 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 <COPYRIGHT HOLDER> 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.
|
||||
*/
|
||||
Copyright (c) 2012-2013, 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.
|
||||
*/
|
||||
|
||||
#import "GCDWebServer.h"
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
@@ -84,7 +84,7 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
return true;
|
||||
});
|
||||
block(data);
|
||||
[data release];
|
||||
ARC_RELEASE(data);
|
||||
} else {
|
||||
block(nil);
|
||||
}
|
||||
@@ -190,18 +190,24 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
}
|
||||
|
||||
- (void)_writeData:(NSData*)data withCompletionBlock:(WriteDataCompletionBlock)block {
|
||||
#if !__has_feature(objc_arc)
|
||||
[data retain];
|
||||
dispatch_data_t buffer = dispatch_data_create(data.bytes, data.length, dispatch_get_current_queue(), ^{
|
||||
#endif
|
||||
dispatch_data_t buffer = dispatch_data_create(data.bytes, data.length, dispatch_get_main_queue(), ^{
|
||||
#if __has_feature(objc_arc)
|
||||
[data self]; // Keeps ARC from releasing data too early
|
||||
#else
|
||||
[data release];
|
||||
#endif
|
||||
});
|
||||
[self _writeBuffer:buffer withCompletionBlock:block];
|
||||
dispatch_release(buffer);
|
||||
ARC_DISPATCH_RELEASE(buffer);
|
||||
}
|
||||
|
||||
- (void)_writeHeadersWithCompletionBlock:(WriteHeadersCompletionBlock)block {
|
||||
DCHECK(_responseMessage);
|
||||
CFDataRef message = CFHTTPMessageCopySerializedMessage(_responseMessage);
|
||||
[self _writeData:(NSData*)message withCompletionBlock:block];
|
||||
[self _writeData:(ARC_BRIDGE NSData*)message withCompletionBlock:block];
|
||||
CFRelease(message);
|
||||
}
|
||||
|
||||
@@ -220,7 +226,7 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
}
|
||||
|
||||
}];
|
||||
dispatch_release(wrapper);
|
||||
ARC_DISPATCH_RELEASE(wrapper);
|
||||
} else if (result < 0) {
|
||||
LOG_ERROR(@"Failed reading response body on socket %i (error %i)", _socket, (int)result);
|
||||
block(NO);
|
||||
@@ -238,22 +244,26 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
@synthesize server=_server, address=_address, totalBytesRead=_bytesRead, totalBytesWritten=_bytesWritten;
|
||||
|
||||
+ (void)initialize {
|
||||
DCHECK([NSThread isMainThread]); // NSDateFormatter should be initialized on main thread
|
||||
if (_separatorData == nil) {
|
||||
_separatorData = [[NSData alloc] initWithBytes:"\r\n\r\n" length:4];
|
||||
DCHECK(_separatorData);
|
||||
}
|
||||
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);
|
||||
DCHECK(_continueData);
|
||||
}
|
||||
if (_dateFormatter == nil) {
|
||||
DCHECK([NSThread isMainThread]); // NSDateFormatter should be initialized on main thread
|
||||
_dateFormatter = [[NSDateFormatter alloc] init];
|
||||
_dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
|
||||
_dateFormatter.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'";
|
||||
_dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];
|
||||
_dateFormatter.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]);
|
||||
DCHECK(_dateFormatter);
|
||||
}
|
||||
if (_formatterQueue == NULL) {
|
||||
@@ -265,10 +275,10 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
- (void)_initializeResponseHeadersWithStatusCode:(NSInteger)statusCode {
|
||||
_responseMessage = CFHTTPMessageCreateResponse(kCFAllocatorDefault, statusCode, NULL, kCFHTTPVersion1_1);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Connection"), CFSTR("Close"));
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (CFStringRef)[[_server class] serverName]);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (ARC_BRIDGE CFStringRef)[[_server class] serverName]);
|
||||
dispatch_sync(_formatterQueue, ^{
|
||||
NSString* date = [_dateFormatter stringFromDate:[NSDate date]];
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (CFStringRef)date);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)date);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -288,23 +298,23 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
|
||||
GCDWebServerResponse* response = [self processRequest:_request withBlock:_handler.processBlock];
|
||||
if (![response hasBody] || [response open]) {
|
||||
_response = [response retain];
|
||||
_response = ARC_RETAIN(response);
|
||||
}
|
||||
|
||||
if (_response) {
|
||||
[self _initializeResponseHeadersWithStatusCode:_response.statusCode];
|
||||
NSUInteger maxAge = _response.cacheControlMaxAge;
|
||||
if (maxAge > 0) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)maxAge]);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)maxAge]);
|
||||
} else {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), CFSTR("no-cache"));
|
||||
}
|
||||
[_response.additionalHeaders enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL* stop) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, (CFStringRef)key, (CFStringRef)obj);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, (ARC_BRIDGE CFStringRef)key, (ARC_BRIDGE CFStringRef)obj);
|
||||
}];
|
||||
if ([_response hasBody]) {
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Type"), (CFStringRef)_response.contentType);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Length"), (CFStringRef)[NSString stringWithFormat:@"%i", (int)_response.contentLength]);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Type"), (ARC_BRIDGE CFStringRef)_response.contentType);
|
||||
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Length"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"%i", (int)_response.contentLength]);
|
||||
}
|
||||
[self _writeHeadersWithCompletionBlock:^(BOOL success) {
|
||||
|
||||
@@ -373,22 +383,22 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
[self _readHeadersWithCompletionBlock:^(NSData* extraData) {
|
||||
|
||||
if (extraData) {
|
||||
NSString* requestMethod = [[(id)CFHTTPMessageCopyRequestMethod(_requestMessage) autorelease] uppercaseString];
|
||||
NSString* requestMethod = [ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestMethod(_requestMessage)) uppercaseString];
|
||||
DCHECK(requestMethod);
|
||||
NSURL* requestURL = [(id)CFHTTPMessageCopyRequestURL(_requestMessage) autorelease];
|
||||
NSURL* requestURL = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestURL(_requestMessage));
|
||||
DCHECK(requestURL);
|
||||
NSString* requestPath = GCDWebServerUnescapeURLString([(id)CFURLCopyPath((CFURLRef)requestURL) autorelease]); // Don't use -[NSURL path] which strips the ending slash
|
||||
NSString* requestPath = GCDWebServerUnescapeURLString(ARC_BRIDGE_RELEASE(CFURLCopyPath((CFURLRef)requestURL))); // Don't use -[NSURL path] which strips the ending slash
|
||||
DCHECK(requestPath);
|
||||
NSDictionary* requestQuery = nil;
|
||||
NSString* queryString = [(id)CFURLCopyQueryString((CFURLRef)requestURL, NULL) autorelease]; // Don't use -[NSURL query] to make sure query is not unescaped;
|
||||
NSString* queryString = ARC_BRIDGE_RELEASE(CFURLCopyQueryString((CFURLRef)requestURL, NULL)); // Don't use -[NSURL query] to make sure query is not unescaped;
|
||||
if (queryString.length) {
|
||||
requestQuery = GCDWebServerParseURLEncodedForm(queryString);
|
||||
DCHECK(requestQuery);
|
||||
}
|
||||
NSDictionary* requestHeaders = [(id)CFHTTPMessageCopyAllHeaderFields(_requestMessage) autorelease];
|
||||
NSDictionary* requestHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(_requestMessage));
|
||||
DCHECK(requestHeaders);
|
||||
for (_handler in _server.handlers) {
|
||||
_request = [_handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery) retain];
|
||||
_request = ARC_RETAIN(_handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery));
|
||||
if (_request) {
|
||||
break;
|
||||
}
|
||||
@@ -396,7 +406,7 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
if (_request) {
|
||||
if (_request.hasBody) {
|
||||
if (extraData.length <= _request.contentLength) {
|
||||
NSString* expectHeader = [(id)CFHTTPMessageCopyHeaderFieldValue(_requestMessage, CFSTR("Expect")) autorelease];
|
||||
NSString* expectHeader = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyHeaderFieldValue(_requestMessage, CFSTR("Expect")));
|
||||
if (expectHeader) {
|
||||
if ([expectHeader caseInsensitiveCompare:@"100-continue"] == NSOrderedSame) {
|
||||
[self _writeData:_continueData withCompletionBlock:^(BOOL success) {
|
||||
@@ -432,8 +442,8 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
|
||||
- (id)initWithServer:(GCDWebServer*)server address:(NSData*)address socket:(CFSocketNativeHandle)socket {
|
||||
if ((self = [super init])) {
|
||||
_server = [server retain];
|
||||
_address = [address retain];
|
||||
_server = ARC_RETAIN(server);
|
||||
_address = ARC_RETAIN(address);
|
||||
_socket = socket;
|
||||
|
||||
[self open];
|
||||
@@ -444,20 +454,20 @@ static dispatch_queue_t _formatterQueue = NULL;
|
||||
- (void)dealloc {
|
||||
[self close];
|
||||
|
||||
[_server release];
|
||||
[_address release];
|
||||
ARC_RELEASE(_server);
|
||||
ARC_RELEASE(_address);
|
||||
|
||||
if (_requestMessage) {
|
||||
CFRelease(_requestMessage);
|
||||
}
|
||||
[_request release];
|
||||
ARC_RELEASE(_request);
|
||||
|
||||
if (_responseMessage) {
|
||||
CFRelease(_responseMessage);
|
||||
}
|
||||
[_response release];
|
||||
ARC_RELEASE(_response);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,29 +1,53 @@
|
||||
/*
|
||||
Copyright (c) 2012-2013, Pierre-Olivier Latour
|
||||
All rights reserved.
|
||||
Copyright (c) 2012-2013, 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.
|
||||
*/
|
||||
|
||||
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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
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 <COPYRIGHT HOLDER> 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.
|
||||
*/
|
||||
#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 (TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0)) || (!TARGET_OS_IPHONE && (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8))
|
||||
#define ARC_DISPATCH_RELEASE(__OBJECT__)
|
||||
#else
|
||||
#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_RELEASE(__OBJECT__) dispatch_release(__OBJECT__)
|
||||
#endif
|
||||
|
||||
#import "GCDWebServerConnection.h"
|
||||
|
||||
@@ -46,8 +70,8 @@ static inline void __LogMessage(long level, NSString* format, ...) {
|
||||
va_start(arguments, format);
|
||||
NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
|
||||
va_end(arguments);
|
||||
printf("[%s] %s\n", levelNames[level], [message UTF8String]);
|
||||
[message release];
|
||||
fprintf(stderr, "[%s] %s\n", levelNames[level], [message UTF8String]);
|
||||
ARC_RELEASE(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
@@ -54,7 +54,7 @@ static NSString* _ExtractHeaderParameter(NSString* header, NSString* attribute)
|
||||
[scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:&value];
|
||||
}
|
||||
}
|
||||
[scanner release];
|
||||
ARC_RELEASE(scanner);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -75,16 +75,16 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
- (id)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
|
||||
if ((self = [super init])) {
|
||||
_method = [method copy];
|
||||
_url = [url retain];
|
||||
_headers = [headers retain];
|
||||
_url = ARC_RETAIN(url);
|
||||
_headers = ARC_RETAIN(headers);
|
||||
_path = [path copy];
|
||||
_query = [query retain];
|
||||
_query = ARC_RETAIN(query);
|
||||
|
||||
_type = [[_headers objectForKey:@"Content-Type"] retain];
|
||||
_type = ARC_RETAIN([_headers objectForKey:@"Content-Type"]);
|
||||
NSInteger length = [[_headers objectForKey:@"Content-Length"] integerValue];
|
||||
if (length < 0) {
|
||||
DNOT_REACHED();
|
||||
[self release];
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
_length = length;
|
||||
@@ -97,14 +97,14 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_method release];
|
||||
[_url release];
|
||||
[_headers release];
|
||||
[_path release];
|
||||
[_query release];
|
||||
[_type release];
|
||||
ARC_RELEASE(_method);
|
||||
ARC_RELEASE(_url);
|
||||
ARC_RELEASE(_headers);
|
||||
ARC_RELEASE(_path);
|
||||
ARC_RELEASE(_query);
|
||||
ARC_RELEASE(_type);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)hasBody {
|
||||
@@ -138,9 +138,9 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
|
||||
- (void)dealloc {
|
||||
DCHECK(_data != nil);
|
||||
[_data release];
|
||||
ARC_RELEASE(_data);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)open {
|
||||
@@ -168,7 +168,7 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
|
||||
- (id)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])) {
|
||||
_filePath = [[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]] retain];
|
||||
_filePath = ARC_RETAIN([NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -176,9 +176,9 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
- (void)dealloc {
|
||||
DCHECK(_file < 0);
|
||||
unlink([_filePath fileSystemRepresentation]);
|
||||
[_filePath release];
|
||||
ARC_RELEASE(_filePath);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)open {
|
||||
@@ -210,9 +210,9 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_arguments release];
|
||||
ARC_RELEASE(_arguments);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)close {
|
||||
@@ -222,8 +222,8 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
|
||||
NSString* charset = _ExtractHeaderParameter(self.contentType, @"charset");
|
||||
NSString* string = [[NSString alloc] initWithData:self.data encoding:_StringEncodingFromCharset(charset)];
|
||||
_arguments = [GCDWebServerParseURLEncodedForm(string) retain];
|
||||
[string release];
|
||||
_arguments = ARC_RETAIN(GCDWebServerParseURLEncodedForm(string));
|
||||
ARC_RELEASE(string);
|
||||
|
||||
return (_arguments ? YES : NO);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
_contentType = [contentType copy];
|
||||
NSArray* components = [_contentType componentsSeparatedByString:@";"];
|
||||
if (components.count) {
|
||||
_mimeType = [[[components objectAtIndex:0] lowercaseString] retain];
|
||||
_mimeType = ARC_RETAIN([[components objectAtIndex:0] lowercaseString]);
|
||||
}
|
||||
if (_mimeType == nil) {
|
||||
_mimeType = @"text/plain";
|
||||
@@ -249,10 +249,10 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_contentType release];
|
||||
[_mimeType release];
|
||||
ARC_RELEASE(_contentType);
|
||||
ARC_RELEASE(_mimeType);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -263,7 +263,7 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
|
||||
- (id)initWithContentType:(NSString*)contentType data:(NSData*)data {
|
||||
if ((self = [super initWithContentType:contentType])) {
|
||||
_data = [data retain];
|
||||
_data = ARC_RETAIN(data);
|
||||
|
||||
if ([self.mimeType hasPrefix:@"text/"]) {
|
||||
NSString* charset = _ExtractHeaderParameter(self.contentType, @"charset");
|
||||
@@ -274,10 +274,10 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_data release];
|
||||
[_string release];
|
||||
ARC_RELEASE(_data);
|
||||
ARC_RELEASE(_string);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (NSString*)description {
|
||||
@@ -301,10 +301,10 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
- (void)dealloc {
|
||||
unlink([_temporaryPath fileSystemRepresentation]);
|
||||
|
||||
[_fileName release];
|
||||
[_temporaryPath release];
|
||||
ARC_RELEASE(_fileName);
|
||||
ARC_RELEASE(_temporaryPath);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (NSString*)description {
|
||||
@@ -340,11 +340,12 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) {
|
||||
NSString* boundary = _ExtractHeaderParameter(self.contentType, @"boundary");
|
||||
if (boundary) {
|
||||
_boundary = [[[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSASCIIStringEncoding] retain];
|
||||
NSData* data = [[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSASCIIStringEncoding];
|
||||
_boundary = ARC_RETAIN(data);
|
||||
}
|
||||
if (_boundary == nil) {
|
||||
DNOT_REACHED();
|
||||
[self release];
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -369,13 +370,13 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
NSRange range = [_parserData rangeOfData:_newlinesData options:0 range:NSMakeRange(0, _parserData.length)];
|
||||
if (range.location != NSNotFound) {
|
||||
|
||||
[_controlName release];
|
||||
ARC_RELEASE(_controlName);
|
||||
_controlName = nil;
|
||||
[_fileName release];
|
||||
ARC_RELEASE(_fileName);
|
||||
_fileName = nil;
|
||||
[_contentType release];
|
||||
ARC_RELEASE(_contentType);
|
||||
_contentType = nil;
|
||||
[_tmpPath release];
|
||||
ARC_RELEASE(_tmpPath);
|
||||
_tmpPath = nil;
|
||||
CFHTTPMessageRef message = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, true);
|
||||
const char* temp = "GET / HTTP/1.0\r\n";
|
||||
@@ -384,7 +385,7 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
if (CFHTTPMessageIsHeaderComplete(message)) {
|
||||
NSString* controlName = nil;
|
||||
NSString* fileName = nil;
|
||||
NSDictionary* headers = [(id)CFHTTPMessageCopyAllHeaderFields(message) autorelease];
|
||||
NSDictionary* headers = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(message));
|
||||
NSString* contentDisposition = [headers objectForKey:@"Content-Disposition"];
|
||||
if ([[contentDisposition lowercaseString] hasPrefix:@"form-data;"]) {
|
||||
controlName = _ExtractHeaderParameter(contentDisposition, @"name");
|
||||
@@ -392,7 +393,7 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
}
|
||||
_controlName = [controlName copy];
|
||||
_fileName = [fileName copy];
|
||||
_contentType = [[headers objectForKey:@"Content-Type"] retain];
|
||||
_contentType = ARC_RETAIN([headers objectForKey:@"Content-Type"]);
|
||||
}
|
||||
CFRelease(message);
|
||||
if (_controlName) {
|
||||
@@ -434,7 +435,7 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
_tmpFile = 0;
|
||||
GCDWebServerMultiPartFile* file = [[GCDWebServerMultiPartFile alloc] initWithContentType:_contentType fileName:_fileName temporaryPath:_tmpPath];
|
||||
[_files setObject:file forKey:_controlName];
|
||||
[file release];
|
||||
ARC_RELEASE(file);
|
||||
} else {
|
||||
DNOT_REACHED();
|
||||
success = NO;
|
||||
@@ -443,14 +444,14 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
DNOT_REACHED();
|
||||
success = NO;
|
||||
}
|
||||
[_tmpPath release];
|
||||
ARC_RELEASE(_tmpPath);
|
||||
_tmpPath = nil;
|
||||
} else {
|
||||
NSData* data = [[NSData alloc] initWithBytesNoCopy:(void*)dataBytes length:dataLength freeWhenDone:NO];
|
||||
GCDWebServerMultiPartArgument* argument = [[GCDWebServerMultiPartArgument alloc] initWithContentType:_contentType data:data];
|
||||
[_arguments setObject:argument forKey:_controlName];
|
||||
[argument release];
|
||||
[data release];
|
||||
ARC_RELEASE(argument);
|
||||
ARC_RELEASE(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,26 +488,31 @@ static NSStringEncoding _StringEncodingFromCharset(NSString* charset) {
|
||||
|
||||
- (BOOL)close {
|
||||
DCHECK(_parserData != nil);
|
||||
[_parserData release];
|
||||
ARC_RELEASE(_parserData);
|
||||
_parserData = nil;
|
||||
[_controlName release];
|
||||
[_fileName release];
|
||||
[_contentType release];
|
||||
ARC_RELEASE(_controlName);
|
||||
_controlName = nil;
|
||||
ARC_RELEASE(_fileName);
|
||||
_fileName = nil;
|
||||
ARC_RELEASE(_contentType);
|
||||
_contentType = nil;
|
||||
if (_tmpFile > 0) {
|
||||
close(_tmpFile);
|
||||
unlink([_tmpPath fileSystemRepresentation]);
|
||||
_tmpFile = 0;
|
||||
}
|
||||
[_tmpPath release];
|
||||
ARC_RELEASE(_tmpPath);
|
||||
_tmpPath = nil;
|
||||
return (_parserState == kParserState_End ? YES : NO);
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
DCHECK(_parserData == nil);
|
||||
[_arguments release];
|
||||
[_files release];
|
||||
[_boundary release];
|
||||
ARC_RELEASE(_arguments);
|
||||
ARC_RELEASE(_files);
|
||||
ARC_RELEASE(_boundary);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
@@ -33,8 +33,8 @@
|
||||
|
||||
@synthesize contentType=_type, contentLength=_length, statusCode=_status, cacheControlMaxAge=_maxAge, additionalHeaders=_headers;
|
||||
|
||||
+(GCDWebServerResponse*) response {
|
||||
return [[[[self class] alloc] init] autorelease];
|
||||
+ (GCDWebServerResponse*)response {
|
||||
return ARC_AUTORELEASE([[[self class] alloc] init]);
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
@@ -57,10 +57,10 @@
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_type release];
|
||||
[_headers release];
|
||||
ARC_RELEASE(_type);
|
||||
ARC_RELEASE(_headers);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (void)setValue:(NSString*)value forAdditionalHeader:(NSString*)header {
|
||||
@@ -95,11 +95,11 @@
|
||||
@implementation GCDWebServerResponse (Extensions)
|
||||
|
||||
+ (GCDWebServerResponse*)responseWithStatusCode:(NSInteger)statusCode {
|
||||
return [[[self alloc] initWithStatusCode:statusCode] autorelease];
|
||||
return ARC_AUTORELEASE([[self alloc] initWithStatusCode:statusCode]);
|
||||
}
|
||||
|
||||
+ (GCDWebServerResponse*)responseWithRedirect:(NSURL*)location permanent:(BOOL)permanent {
|
||||
return [[[self alloc] initWithRedirect:location permanent:permanent] autorelease];
|
||||
return ARC_AUTORELEASE([[self alloc] initWithRedirect:location permanent:permanent]);
|
||||
}
|
||||
|
||||
- (id)initWithStatusCode:(NSInteger)statusCode {
|
||||
@@ -122,18 +122,18 @@
|
||||
@implementation GCDWebServerDataResponse
|
||||
|
||||
+ (GCDWebServerDataResponse*)responseWithData:(NSData*)data contentType:(NSString*)type {
|
||||
return [[[[self class] alloc] initWithData:data contentType:type] autorelease];
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithData:data contentType:type]);
|
||||
}
|
||||
|
||||
- (id)initWithData:(NSData*)data contentType:(NSString*)type {
|
||||
if (data == nil) {
|
||||
DNOT_REACHED();
|
||||
[self release];
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ((self = [super initWithContentType:type contentLength:data.length])) {
|
||||
_data = [data retain];
|
||||
_data = ARC_RETAIN(data);
|
||||
_offset = -1;
|
||||
}
|
||||
return self;
|
||||
@@ -141,9 +141,9 @@
|
||||
|
||||
- (void)dealloc {
|
||||
DCHECK(_offset < 0);
|
||||
[_data release];
|
||||
ARC_RELEASE(_data);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)open {
|
||||
@@ -174,22 +174,22 @@
|
||||
@implementation GCDWebServerDataResponse (Extensions)
|
||||
|
||||
+ (GCDWebServerDataResponse*)responseWithText:(NSString*)text {
|
||||
return [[[self alloc] initWithText:text] autorelease];
|
||||
return ARC_AUTORELEASE([[self alloc] initWithText:text]);
|
||||
}
|
||||
|
||||
+ (GCDWebServerDataResponse*)responseWithHTML:(NSString*)html {
|
||||
return [[[self alloc] initWithHTML:html] autorelease];
|
||||
return ARC_AUTORELEASE([[self alloc] initWithHTML:html]);
|
||||
}
|
||||
|
||||
+ (GCDWebServerDataResponse*)responseWithHTMLTemplate:(NSString*)path variables:(NSDictionary*)variables {
|
||||
return [[[self alloc] initWithHTMLTemplate:path variables:variables] autorelease];
|
||||
return ARC_AUTORELEASE([[self alloc] initWithHTMLTemplate:path variables:variables]);
|
||||
}
|
||||
|
||||
- (id)initWithText:(NSString*)text {
|
||||
NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding];
|
||||
if (data == nil) {
|
||||
DNOT_REACHED();
|
||||
[self release];
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
return [self initWithData:data contentType:@"text/plain; charset=utf-8"];
|
||||
@@ -199,7 +199,7 @@
|
||||
NSData* data = [html dataUsingEncoding:NSUTF8StringEncoding];
|
||||
if (data == nil) {
|
||||
DNOT_REACHED();
|
||||
[self release];
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
return [self initWithData:data contentType:@"text/html; charset=utf-8"];
|
||||
@@ -211,7 +211,7 @@
|
||||
[html replaceOccurrencesOfString:[NSString stringWithFormat:@"%%%@%%", key] withString:value options:0 range:NSMakeRange(0, html.length)];
|
||||
}];
|
||||
id response = [self initWithHTML:html];
|
||||
[html release];
|
||||
ARC_RELEASE(html);
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -220,11 +220,11 @@
|
||||
@implementation GCDWebServerFileResponse
|
||||
|
||||
+ (GCDWebServerFileResponse*)responseWithFile:(NSString*)path {
|
||||
return [[[[self class] alloc] initWithFile:path] autorelease];
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path]);
|
||||
}
|
||||
|
||||
+ (GCDWebServerFileResponse*)responseWithFile:(NSString*)path isAttachment:(BOOL)attachment {
|
||||
return [[[[self class] alloc] initWithFile:path isAttachment:attachment] autorelease];
|
||||
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path isAttachment:attachment]);
|
||||
}
|
||||
|
||||
- (id)initWithFile:(NSString*)path {
|
||||
@@ -235,7 +235,7 @@
|
||||
struct stat info;
|
||||
if (lstat([path fileSystemRepresentation], &info) || !(info.st_mode & S_IFREG)) {
|
||||
DNOT_REACHED();
|
||||
[self release];
|
||||
ARC_RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
NSString* type = GCDWebServerGetMimeTypeForExtension([path pathExtension]);
|
||||
@@ -250,7 +250,7 @@
|
||||
NSString* fileName = data ? [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding] : nil;
|
||||
if (fileName) {
|
||||
[self setValue:[NSString stringWithFormat:@"attachment; filename=\"%@\"", fileName] forAdditionalHeader:@"Content-Disposition"];
|
||||
[fileName release];
|
||||
ARC_RELEASE(fileName);
|
||||
} else {
|
||||
DNOT_REACHED();
|
||||
}
|
||||
@@ -261,9 +261,9 @@
|
||||
|
||||
- (void)dealloc {
|
||||
DCHECK(_file <= 0);
|
||||
[_path release];
|
||||
ARC_RELEASE(_path);
|
||||
|
||||
[super dealloc];
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (BOOL)open {
|
||||
|
||||
18
GCDWebServer.podspec
Normal file
18
GCDWebServer.podspec
Normal file
@@ -0,0 +1,18 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'GCDWebServer'
|
||||
s.version = '1.2'
|
||||
s.author = { 'Pierre-Olivier Latour' => 'info@pol-online.net' }
|
||||
s.license = { :type => 'BSD', :file => 'LICENSE' }
|
||||
s.homepage = 'https://github.com/swisspol/GCDWebServer'
|
||||
s.summary = 'Lightweight GCD based HTTP server for Mac OS X & iOS apps'
|
||||
s.source = { :git => 'https://github.com/swisspol/GCDWebServer.git', :tag => s.version.to_s }
|
||||
|
||||
s.requires_arc = true
|
||||
|
||||
s.source_files = 'CGDWebServer/*.{h,m}'
|
||||
|
||||
s.ios.deployment_target = '5.0'
|
||||
s.osx.deployment_target = '10.7'
|
||||
|
||||
s.ios.framework = 'MobileCoreServices'
|
||||
end
|
||||
@@ -6,6 +6,21 @@
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
E274F876187E77D8009E0582 /* Build All */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = E274F879187E77D8009E0582 /* Build configuration list for PBXAggregateTarget "Build All" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
E274F87D187E77E5009E0582 /* PBXTargetDependency */,
|
||||
E274F87B187E77E3009E0582 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Build All";
|
||||
productName = "Build All";
|
||||
};
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E208D149167B76B700500836 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E208D148167B76B700500836 /* CFNetwork.framework */; };
|
||||
E208D1B3167BB17E00500836 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E208D1B2167BB17E00500836 /* CoreServices.framework */; };
|
||||
@@ -25,6 +40,23 @@
|
||||
E221129D1690B7BA0048D2B2 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E221129C1690B7BA0048D2B2 /* MobileCoreServices.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
E274F87A187E77E3009E0582 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 8DD76FA90486AB0100D96B5E;
|
||||
remoteInfo = "GCDWebServer (Mac)";
|
||||
};
|
||||
E274F87C187E77E5009E0582 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = E22112591690B4DE0048D2B2;
|
||||
remoteInfo = "GCDWebServer (iOS)";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
8DD76FB20486AB0100D96B5E /* GCDWebServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = GCDWebServer; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E208D148167B76B700500836 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
|
||||
@@ -189,6 +221,9 @@
|
||||
/* Begin PBXProject section */
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
};
|
||||
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "GCDWebServer" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
@@ -204,6 +239,7 @@
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
E274F876187E77D8009E0582 /* Build All */,
|
||||
8DD76FA90486AB0100D96B5E /* GCDWebServer (Mac) */,
|
||||
E22112591690B4DE0048D2B2 /* GCDWebServer (iOS) */,
|
||||
);
|
||||
@@ -238,11 +274,23 @@
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
E274F87B187E77E3009E0582 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 8DD76FA90486AB0100D96B5E /* GCDWebServer (Mac) */;
|
||||
targetProxy = E274F87A187E77E3009E0582 /* PBXContainerItemProxy */;
|
||||
};
|
||||
E274F87D187E77E5009E0582 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = E22112591690B4DE0048D2B2 /* GCDWebServer (iOS) */;
|
||||
targetProxy = E274F87C187E77E5009E0582 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1DEB928608733DD80010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
PRODUCT_NAME = GCDWebServer;
|
||||
SDKROOT = macosx;
|
||||
@@ -252,7 +300,6 @@
|
||||
1DEB928708733DD80010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
PRODUCT_NAME = GCDWebServer;
|
||||
SDKROOT = macosx;
|
||||
@@ -262,6 +309,7 @@
|
||||
1DEB928A08733DD80010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
@@ -271,10 +319,8 @@
|
||||
1DEB928B08733DD80010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
NDEBUG,
|
||||
NS_BLOCK_ASSERTIONS,
|
||||
);
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
};
|
||||
name = Release;
|
||||
@@ -305,6 +351,20 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E274F877187E77D8009E0582 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E274F878187E77D8009E0582 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
@@ -333,6 +393,16 @@
|
||||
E22112771690B4DF0048D2B2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E274F879187E77D8009E0582 /* Build configuration list for PBXAggregateTarget "Build All" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E274F877187E77D8009E0582 /* Debug */,
|
||||
E274F878187E77D8009E0582 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
|
||||
8
LICENSE
8
LICENSE
@@ -8,14 +8,14 @@ modification, are permitted provided that the following conditions are met:
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
|
||||
10
Mac/main.m
10
Mac/main.m
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
@@ -81,7 +81,9 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
}
|
||||
success = [webServer runWithPort:8080];
|
||||
#if !__has_feature(objc_arc)
|
||||
[webServer release];
|
||||
#endif
|
||||
}
|
||||
return success ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ GCDWebServer is a lightweight GCD based HTTP 1.1 server designed to be embedded
|
||||
* Support for streaming large HTTP bodies for requests and responses to minimize memory usage
|
||||
* Built-in parser for web forms submitted using "application/x-www-form-urlencoded" or "multipart/form-data" encodings (including file uploads)
|
||||
* Minimal number of source files and no dependencies on third-party source code
|
||||
* Available under a friendly [New BSD License](GCDWebServer/blob/master/LICENSE)
|
||||
* Available under a friendly [New BSD License](LICENSE)
|
||||
|
||||
What's not available out of the box but can be implemented on top of the API:
|
||||
* Authentication like Basic Authentication
|
||||
@@ -91,8 +91,8 @@ Understanding GCDWebServer Architecture
|
||||
GCDWebServer is made of only 4 core classes:
|
||||
* 'GCDWebServer' manages the socket that listens for new HTTP connections and the list of handlers used by the server.
|
||||
* 'GCDWebServerConnection' is instantiated by 'GCDWebServer' to handle each new HTTP connection. Each instance stays alive until the connection is closed. You cannot use this class directly, but it is exposed so you can subclass it to override some hooks.
|
||||
* 'GCDWebServerRequest' is created by the 'GCDWebServerConnection' instance after HTTP headers have been received. It wraps the request and handles the HTTP body if any. GCDWebServer comes with several subclasses of 'GCDWebServerRequest' to handle common cases like storing the body in memory or stream it to a file on disk. See [GCDWebServerRequest.h](GCDWebServer/blob/master/CGDWebServer/GCDWebServerRequest.h) for the full list.
|
||||
* 'GCDWebServerResponse' is created by the request handler and wraps the response HTTP headers and optional body. GCDWebServer provides several subclasses of 'GCDWebServerResponse' to handle common cases like HTML text in memory or streaming a file from disk. See [GCDWebServerResponse.h](GCDWebServer/blob/master/CGDWebServer/GCDWebServerResponse.h) for the full list.
|
||||
* 'GCDWebServerRequest' is created by the 'GCDWebServerConnection' instance after HTTP headers have been received. It wraps the request and handles the HTTP body if any. GCDWebServer comes with several subclasses of 'GCDWebServerRequest' to handle common cases like storing the body in memory or stream it to a file on disk. See [GCDWebServerRequest.h](CGDWebServer/GCDWebServerRequest.h) for the full list.
|
||||
* 'GCDWebServerResponse' is created by the request handler and wraps the response HTTP headers and optional body. GCDWebServer provides several subclasses of 'GCDWebServerResponse' to handle common cases like HTML text in memory or streaming a file from disk. See [GCDWebServerResponse.h](CGDWebServer/GCDWebServerResponse.h) for the full list.
|
||||
|
||||
Implementing Handlers
|
||||
=====================
|
||||
@@ -203,4 +203,4 @@ Final Example: File Downloads and Uploads From iOS App
|
||||
|
||||
GCDWebServer was originally written for the [ComicFlow](http://itunes.apple.com/us/app/comicflow/id409290355?mt=8) comic reader app for iPad. It uses it to provide a web server for people to upload and download comic files directly over WiFi to and from the app.
|
||||
|
||||
ComicFlow is [entirely open-source](https://code.google.com/p/comicflow/) and you can see how it uses GCDWebServer in the [WebServer.m](http://code.google.com/p/comicflow/source/browse/Classes/WebServer.m) file.
|
||||
ComicFlow is [entirely open-source](https://github.com/swisspol/ComicFlow) and you can see how it uses GCDWebServer in the [WebServer.m](https://github.com/swisspol/ComicFlow/blob/master/Classes/WebServer.m) file.
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
@@ -29,12 +29,16 @@
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
|
||||
- (void)dealloc {
|
||||
[_window release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
|
||||
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
_window.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
* 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.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
* 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 <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user