Added ARC support

This commit is contained in:
Pierre-Olivier Latour
2014-01-08 22:27:15 -08:00
parent 2e587919ca
commit 78480e004a
8 changed files with 246 additions and 133 deletions

View File

@@ -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,16 @@ static void _SignalHandler(int signal) {
[self stop];
}
[_handlers release];
ARC_RELEASE(_handlers);
[super dealloc];
ARC_DEALLOC(super);
}
- (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 {
@@ -212,8 +212,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 +239,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};
@@ -326,7 +330,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 +367,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 +380,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 +392,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 +423,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 +442,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 {

View File

@@ -84,7 +84,7 @@ static dispatch_queue_t _formatterQueue = NULL;
return true;
});
block(data);
[data release];
ARC_RELEASE(data);
} else {
block(nil);
}
@@ -190,9 +190,15 @@ static dispatch_queue_t _formatterQueue = NULL;
}
- (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, dispatch_get_current_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);
@@ -201,7 +207,7 @@ static dispatch_queue_t _formatterQueue = NULL;
- (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);
}
@@ -245,7 +251,11 @@ static dispatch_queue_t _formatterQueue = NULL;
}
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);
}
@@ -253,7 +263,7 @@ static dispatch_queue_t _formatterQueue = NULL;
_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

View File

@@ -25,6 +25,22 @@
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__)
#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]
#endif
#import "GCDWebServerConnection.h"
#ifdef __GCDWEBSERVER_LOGGING_HEADER__
@@ -47,7 +63,7 @@ static inline void __LogMessage(long level, NSString* format, ...) {
NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
va_end(arguments);
printf("[%s] %s\n", levelNames[level], [message UTF8String]);
[message release];
ARC_RELEASE(message);
}
}

View File

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

View File

@@ -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 {

View File

@@ -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; };
@@ -207,6 +239,7 @@
projectDirPath = "";
projectRoot = "";
targets = (
E274F876187E77D8009E0582 /* Build All */,
8DD76FA90486AB0100D96B5E /* GCDWebServer (Mac) */,
E22112591690B4DE0048D2B2 /* GCDWebServer (iOS) */,
);
@@ -241,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;
@@ -255,7 +300,6 @@
1DEB928708733DD80010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = GCDWebServer;
SDKROOT = macosx;
@@ -265,6 +309,7 @@
1DEB928A08733DD80010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
GCC_OPTIMIZATION_LEVEL = 0;
ONLY_ACTIVE_ARCH = YES;
WARNING_CFLAGS = "-Wall";
@@ -274,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;
@@ -308,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 */
@@ -338,6 +395,15 @@
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 */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;

View File

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

View File

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