5 Commits
3.1 ... 3.2

Author SHA1 Message Date
Pierre-Olivier Latour
9d9546bb6d Bumped version 2014-11-07 11:44:11 +09:00
Pierre-Olivier Latour
2ff05b1aa0 Bumped version 2014-11-07 11:43:10 +09:00
Pierre-Olivier Latour
bf2c9a170d Workaround Firefox and IE not showing file selection dialog 2014-11-07 11:42:36 +09:00
Pierre-Olivier Latour
15caa9cd20 Fix 2014-10-18 12:42:38 -07:00
Pierre-Olivier Latour
32ba49ae34 Removed MRC support entirely 2014-10-18 09:32:24 -07:00
23 changed files with 209 additions and 437 deletions

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebDAVServer requires ARC
#endif
// WebDAV specifications: http://webdav.org/specs/rfc4918.html // WebDAV specifications: http://webdav.org/specs/rfc4918.html
// Requires "HEADER_SEARCH_PATHS = $(SDKROOT)/usr/include/libxml2" in Xcode build settings // Requires "HEADER_SEARCH_PATHS = $(SDKROOT)/usr/include/libxml2" in Xcode build settings
@@ -418,9 +422,6 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
} }
if (!success) { if (!success) {
NSString* string = [[NSString alloc] initWithData:request.data encoding:NSUTF8StringEncoding]; NSString* string = [[NSString alloc] initWithData:request.data encoding:NSUTF8StringEncoding];
#if !__has_feature(objc_arc)
[string autorelease];
#endif
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Invalid DAV properties:\n%@", string]; return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Invalid DAV properties:\n%@", string];
} }
} else { } else {
@@ -519,9 +520,6 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
} }
if (!success) { if (!success) {
NSString* string = [[NSString alloc] initWithData:request.data encoding:NSUTF8StringEncoding]; NSString* string = [[NSString alloc] initWithData:request.data encoding:NSUTF8StringEncoding];
#if !__has_feature(objc_arc)
[string autorelease];
#endif
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Invalid DAV properties:\n%@", string]; return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Invalid DAV properties:\n%@", string];
} }
@@ -607,11 +605,7 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
- (instancetype)initWithUploadDirectory:(NSString*)path { - (instancetype)initWithUploadDirectory:(NSString*)path {
if ((self = [super init])) { if ((self = [super init])) {
_uploadDirectory = [[path stringByStandardizingPath] copy]; _uploadDirectory = [[path stringByStandardizingPath] copy];
#if __has_feature(objc_arc)
GCDWebDAVServer* __unsafe_unretained server = self; GCDWebDAVServer* __unsafe_unretained server = self;
#else
__block GCDWebDAVServer* server = self;
#endif
// 9.1 PROPFIND method // 9.1 PROPFIND method
[self addDefaultHandlerForMethod:@"PROPFIND" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { [self addDefaultHandlerForMethod:@"PROPFIND" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
@@ -667,17 +661,6 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
return self; return self;
} }
#if !__has_feature(objc_arc)
- (void)dealloc {
[_uploadDirectory release];
[_allowedExtensions release];
[super dealloc];
}
#endif
@end @end
@implementation GCDWebDAVServer (Subclassing) @implementation GCDWebDAVServer (Subclassing)

View File

@@ -7,7 +7,7 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'GCDWebServer' s.name = 'GCDWebServer'
s.version = '3.1' s.version = '3.2'
s.author = { 'Pierre-Olivier Latour' => 'info@pol-online.net' } s.author = { 'Pierre-Olivier Latour' => 'info@pol-online.net' }
s.license = { :type => 'BSD', :file => 'LICENSE' } s.license = { :type => 'BSD', :file => 'LICENSE' }
s.homepage = 'https://github.com/swisspol/GCDWebServer' s.homepage = 'https://github.com/swisspol/GCDWebServer'

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import <TargetConditionals.h> #import <TargetConditionals.h>
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@@ -93,7 +97,6 @@ void GCDWebServerLogMessage(GCDWebServerLoggingLevel level, NSString* format, ..
NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments]; NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
va_end(arguments); va_end(arguments);
fprintf(stderr, "[%s] %s\n", levelNames[level], [message UTF8String]); fprintf(stderr, "[%s] %s\n", levelNames[level], [message UTF8String]);
ARC_RELEASE(message);
} }
} }
@@ -142,13 +145,6 @@ static void _ExecuteMainThreadRunLoopSources() {
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_matchBlock);
ARC_RELEASE(_asyncProcessBlock);
ARC_DEALLOC(super);
}
@end @end
@interface GCDWebServer () { @interface GCDWebServer () {
@@ -212,11 +208,10 @@ static void _ExecuteMainThreadRunLoopSources() {
GWS_DCHECK(_options == nil); // The server can never be dealloc'ed while running because of the retain-cycle with the dispatch source GWS_DCHECK(_options == nil); // The server can never be dealloc'ed while running because of the retain-cycle with the dispatch source
GWS_DCHECK(_disconnectTimer == NULL); // The server can never be dealloc'ed while the disconnect timer is pending because of the retain-cycle GWS_DCHECK(_disconnectTimer == NULL); // The server can never be dealloc'ed while the disconnect timer is pending because of the retain-cycle
ARC_RELEASE(_handlers); #if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
ARC_DISPATCH_RELEASE(_sourceGroup); dispatch_release(_sourceGroup);
ARC_DISPATCH_RELEASE(_syncQueue); dispatch_release(_syncQueue);
#endif
ARC_DEALLOC(super);
} }
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
@@ -339,12 +334,12 @@ static void _ExecuteMainThreadRunLoopSources() {
- (NSString*)bonjourName { - (NSString*)bonjourName {
CFStringRef name = _resolutionService ? CFNetServiceGetName(_resolutionService) : NULL; CFStringRef name = _resolutionService ? CFNetServiceGetName(_resolutionService) : NULL;
return name && CFStringGetLength(name) ? ARC_BRIDGE_RELEASE(CFStringCreateCopy(kCFAllocatorDefault, name)) : nil; return name && CFStringGetLength(name) ? CFBridgingRelease(CFStringCreateCopy(kCFAllocatorDefault, name)) : nil;
} }
- (NSString*)bonjourType { - (NSString*)bonjourType {
CFStringRef type = _resolutionService ? CFNetServiceGetType(_resolutionService) : NULL; CFStringRef type = _resolutionService ? CFNetServiceGetType(_resolutionService) : NULL;
return type && CFStringGetLength(type) ? ARC_BRIDGE_RELEASE(CFStringCreateCopy(kCFAllocatorDefault, type)) : nil; return type && CFStringGetLength(type) ? CFBridgingRelease(CFStringCreateCopy(kCFAllocatorDefault, type)) : nil;
} }
- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock { - (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock {
@@ -357,7 +352,6 @@ static void _ExecuteMainThreadRunLoopSources() {
GWS_DCHECK(_options == nil); GWS_DCHECK(_options == nil);
GCDWebServerHandler* handler = [[GCDWebServerHandler alloc] initWithMatchBlock:matchBlock asyncProcessBlock:processBlock]; GCDWebServerHandler* handler = [[GCDWebServerHandler alloc] initWithMatchBlock:matchBlock asyncProcessBlock:processBlock];
[_handlers insertObject:handler atIndex:0]; [_handlers insertObject:handler atIndex:0];
ARC_RELEASE(handler);
} }
- (void)removeAllHandlers { - (void)removeAllHandlers {
@@ -371,7 +365,7 @@ static void _NetServiceRegisterCallBack(CFNetServiceRef service, CFStreamError*
if (error->error) { if (error->error) {
GWS_LOG_ERROR(@"Bonjour registration error %i (domain %i)", (int)error->error, (int)error->domain); GWS_LOG_ERROR(@"Bonjour registration error %i (domain %i)", (int)error->error, (int)error->domain);
} else { } else {
GCDWebServer* server = (ARC_BRIDGE GCDWebServer*)info; GCDWebServer* server = (__bridge GCDWebServer*)info;
GWS_LOG_VERBOSE(@"Bonjour registration complete for %@", [server class]); GWS_LOG_VERBOSE(@"Bonjour registration complete for %@", [server class]);
CFNetServiceResolveWithTimeout(server->_resolutionService, 1.0, NULL); CFNetServiceResolveWithTimeout(server->_resolutionService, 1.0, NULL);
} }
@@ -386,7 +380,7 @@ static void _NetServiceResolveCallBack(CFNetServiceRef service, CFStreamError* e
GWS_LOG_ERROR(@"Bonjour resolution error %i (domain %i)", (int)error->error, (int)error->domain); GWS_LOG_ERROR(@"Bonjour resolution error %i (domain %i)", (int)error->error, (int)error->domain);
} }
} else { } else {
GCDWebServer* server = (ARC_BRIDGE GCDWebServer*)info; GCDWebServer* server = (__bridge GCDWebServer*)info;
GWS_LOG_INFO(@"%@ now reachable at %@", [server class], server.bonjourServerURL); GWS_LOG_INFO(@"%@ now reachable at %@", [server class], server.bonjourServerURL);
if ([server.delegate respondsToSelector:@selector(webServerDidCompleteBonjourRegistration:)]) { if ([server.delegate respondsToSelector:@selector(webServerDidCompleteBonjourRegistration:)]) {
[server.delegate webServerDidCompleteBonjourRegistration:server]; [server.delegate webServerDidCompleteBonjourRegistration:server];
@@ -407,7 +401,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
return [data base64Encoding]; return [data base64Encoding];
} }
#endif #endif
return ARC_AUTORELEASE([[NSString alloc] initWithData:[data base64EncodedDataWithOptions:0] encoding:NSASCIIStringEncoding]); return [[NSString alloc] initWithData:[data base64EncodedDataWithOptions:0] encoding:NSASCIIStringEncoding];
} }
- (int)_createListeningSocket:(BOOL)useIPv6 - (int)_createListeningSocket:(BOOL)useIPv6
@@ -487,11 +481,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &noSigPipe, sizeof(noSigPipe)); // Make sure this socket cannot generate SIG_PIPE setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &noSigPipe, sizeof(noSigPipe)); // Make sure this socket cannot generate SIG_PIPE
GCDWebServerConnection* connection = [[_connectionClass alloc] initWithServer:self localAddress:localAddress remoteAddress:remoteAddress socket:socket]; // Connection will automatically retain itself while opened GCDWebServerConnection* connection = [[_connectionClass alloc] initWithServer:self localAddress:localAddress remoteAddress:remoteAddress socket:socket]; // Connection will automatically retain itself while opened
#if __has_feature(objc_arc)
[connection self]; // Prevent compiler from complaining about unused variable / useless statement [connection self]; // Prevent compiler from complaining about unused variable / useless statement
#else
[connection release];
#endif
} else { } else {
GWS_LOG_ERROR(@"Failed accepting %s socket: %s (%i)", isIPv6 ? "IPv6" : "IPv4", strerror(errno), errno); GWS_LOG_ERROR(@"Failed accepting %s socket: %s (%i)", isIPv6 ? "IPv6" : "IPv4", strerror(errno), errno);
} }
@@ -568,9 +558,9 @@ static inline NSString* _EncodeBase64(NSString* string) {
NSString* bonjourName = _GetOption(_options, GCDWebServerOption_BonjourName, @""); NSString* bonjourName = _GetOption(_options, GCDWebServerOption_BonjourName, @"");
NSString* bonjourType = _GetOption(_options, GCDWebServerOption_BonjourType, @"_http._tcp"); NSString* bonjourType = _GetOption(_options, GCDWebServerOption_BonjourType, @"_http._tcp");
if (bonjourName) { if (bonjourName) {
_registrationService = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), (ARC_BRIDGE CFStringRef)bonjourType, (ARC_BRIDGE CFStringRef)(bonjourName.length ? bonjourName : _serverName), (SInt32)_port); _registrationService = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), (__bridge CFStringRef)bonjourType, (__bridge CFStringRef)(bonjourName.length ? bonjourName : _serverName), (SInt32)_port);
if (_registrationService) { if (_registrationService) {
CFNetServiceClientContext context = {0, (ARC_BRIDGE void*)self, NULL, NULL, NULL}; CFNetServiceClientContext context = {0, (__bridge void*)self, NULL, NULL, NULL};
CFNetServiceSetClient(_registrationService, _NetServiceRegisterCallBack, &context); CFNetServiceSetClient(_registrationService, _NetServiceRegisterCallBack, &context);
CFNetServiceScheduleWithRunLoop(_registrationService, CFRunLoopGetMain(), kCFRunLoopCommonModes); CFNetServiceScheduleWithRunLoop(_registrationService, CFRunLoopGetMain(), kCFRunLoopCommonModes);
@@ -620,19 +610,19 @@ static inline NSString* _EncodeBase64(NSString* string) {
dispatch_source_cancel(_source6); dispatch_source_cancel(_source6);
dispatch_source_cancel(_source4); dispatch_source_cancel(_source4);
dispatch_group_wait(_sourceGroup, DISPATCH_TIME_FOREVER); // Wait until the cancellation handlers have been called which guarantees the listening sockets are closed dispatch_group_wait(_sourceGroup, DISPATCH_TIME_FOREVER); // Wait until the cancellation handlers have been called which guarantees the listening sockets are closed
ARC_DISPATCH_RELEASE(_source6); #if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
dispatch_release(_source6);
#endif
_source6 = NULL; _source6 = NULL;
ARC_DISPATCH_RELEASE(_source4); #if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
dispatch_release(_source4);
#endif
_source4 = NULL; _source4 = NULL;
_port = 0; _port = 0;
ARC_RELEASE(_serverName);
_serverName = nil; _serverName = nil;
ARC_RELEASE(_authenticationRealm);
_authenticationRealm = nil; _authenticationRealm = nil;
ARC_RELEASE(_authenticationBasicAccounts);
_authenticationBasicAccounts = nil; _authenticationBasicAccounts = nil;
ARC_RELEASE(_authenticationDigestAccounts);
_authenticationDigestAccounts = nil; _authenticationDigestAccounts = nil;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
@@ -682,7 +672,6 @@ static inline NSString* _EncodeBase64(NSString* string) {
if (![self _start:error]) if (![self _start:error])
#endif #endif
{ {
ARC_RELEASE(_options);
_options = nil; _options = nil;
return NO; return NO;
} }
@@ -714,7 +703,6 @@ static inline NSString* _EncodeBase64(NSString* string) {
if (_source4) { if (_source4) {
[self _stop]; [self _stop];
} }
ARC_RELEASE(_options);
_options = nil; _options = nil;
} else { } else {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
@@ -741,7 +729,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
- (NSURL*)bonjourServerURL { - (NSURL*)bonjourServerURL {
if (_source4 && _resolutionService) { if (_source4 && _resolutionService) {
NSString* name = (ARC_BRIDGE NSString*)CFNetServiceGetTargetHost(_resolutionService); NSString* name = (__bridge NSString*)CFNetServiceGetTargetHost(_resolutionService);
if (name.length) { if (name.length) {
name = [name substringToIndex:(name.length - 1)]; // Strip trailing period at end of domain name = [name substringToIndex:(name.length - 1)]; // Strip trailing period at end of domain
if (_port != 80) { if (_port != 80) {
@@ -813,7 +801,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
if (![requestMethod isEqualToString:method]) { if (![requestMethod isEqualToString:method]) {
return nil; return nil;
} }
return ARC_AUTORELEASE([[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]); return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
} asyncProcessBlock:block]; } asyncProcessBlock:block];
} }
@@ -834,7 +822,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
if ([urlPath caseInsensitiveCompare:path] != NSOrderedSame) { if ([urlPath caseInsensitiveCompare:path] != NSOrderedSame) {
return nil; return nil;
} }
return ARC_AUTORELEASE([[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]); return [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
} asyncProcessBlock:block]; } asyncProcessBlock:block];
} else { } else {
@@ -872,7 +860,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
GCDWebServerRequest* request = [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]; GCDWebServerRequest* request = [[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
[request setAttribute:captures forKey:GCDWebServerRequestAttribute_RegexCaptures]; [request setAttribute:captures forKey:GCDWebServerRequestAttribute_RegexCaptures];
return ARC_AUTORELEASE(request); return request;
} asyncProcessBlock:block]; } asyncProcessBlock:block];
} else { } else {
@@ -939,11 +927,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
- (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)directoryPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests { - (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)directoryPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests {
if ([basePath hasPrefix:@"/"] && [basePath hasSuffix:@"/"]) { if ([basePath hasPrefix:@"/"] && [basePath hasSuffix:@"/"]) {
#if __has_feature(objc_arc)
GCDWebServer* __unsafe_unretained server = self; GCDWebServer* __unsafe_unretained server = self;
#else
__block GCDWebServer* server = self;
#endif
[self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { [self addHandlerWithMatchBlock:^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
if (![requestMethod isEqualToString:@"GET"]) { if (![requestMethod isEqualToString:@"GET"]) {
@@ -952,7 +936,7 @@ static inline NSString* _EncodeBase64(NSString* string) {
if (![urlPath hasPrefix:basePath]) { if (![urlPath hasPrefix:basePath]) {
return nil; return nil;
} }
return ARC_AUTORELEASE([[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]); return [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
} processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { } processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
@@ -1008,28 +992,28 @@ static inline NSString* _EncodeBase64(NSString* string) {
- (void)logVerbose:(NSString*)format, ... { - (void)logVerbose:(NSString*)format, ... {
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
GWS_LOG_VERBOSE(@"%@", ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments])); GWS_LOG_VERBOSE(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]);
va_end(arguments); va_end(arguments);
} }
- (void)logInfo:(NSString*)format, ... { - (void)logInfo:(NSString*)format, ... {
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
GWS_LOG_INFO(@"%@", ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments])); GWS_LOG_INFO(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]);
va_end(arguments); va_end(arguments);
} }
- (void)logWarning:(NSString*)format, ... { - (void)logWarning:(NSString*)format, ... {
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
GWS_LOG_WARNING(@"%@", ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments])); GWS_LOG_WARNING(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]);
va_end(arguments); va_end(arguments);
} }
- (void)logError:(NSString*)format, ... { - (void)logError:(NSString*)format, ... {
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
GWS_LOG_ERROR(@"%@", ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments])); GWS_LOG_ERROR(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]);
va_end(arguments); va_end(arguments);
} }
@@ -1093,7 +1077,6 @@ static CFHTTPMessageRef _CreateHTTPMessageFromPerformingRequest(NSData* inData,
} else { } else {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
} }
ARC_RELEASE(outData);
} }
} }
close(httpSocket); close(httpSocket);
@@ -1107,7 +1090,6 @@ static void _LogResult(NSString* format, ...) {
NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments]; NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
va_end(arguments); va_end(arguments);
fprintf(stdout, "%s\n", [message UTF8String]); fprintf(stdout, "%s\n", [message UTF8String]);
ARC_RELEASE(message);
} }
- (NSInteger)runTestsWithOptions:(NSDictionary*)options inDirectory:(NSString*)path { - (NSInteger)runTestsWithOptions:(NSDictionary*)options inDirectory:(NSString*)path {
@@ -1130,8 +1112,8 @@ static void _LogResult(NSString* format, ...) {
if (requestData) { if (requestData) {
CFHTTPMessageRef request = _CreateHTTPMessageFromData(requestData, YES); CFHTTPMessageRef request = _CreateHTTPMessageFromData(requestData, YES);
if (request) { if (request) {
NSString* requestMethod = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestMethod(request)); NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(request));
NSURL* requestURL = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestURL(request)); NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(request));
_LogResult(@"[%i] %@ %@", (int)[index integerValue], requestMethod, requestURL.path); _LogResult(@"[%i] %@ %@", (int)[index integerValue], requestMethod, requestURL.path);
NSString* prefix = [index stringByAppendingString:@"-"]; NSString* prefix = [index stringByAppendingString:@"-"];
for (NSString* responseFile in files) { for (NSString* responseFile in files) {
@@ -1151,8 +1133,8 @@ static void _LogResult(NSString* format, ...) {
success = NO; success = NO;
} }
NSDictionary* expectedHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(expectedResponse)); NSDictionary* expectedHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(expectedResponse));
NSDictionary* actualHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(actualResponse)); NSDictionary* actualHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(actualResponse));
for (NSString* expectedHeader in expectedHeaders) { for (NSString* expectedHeader in expectedHeaders) {
if ([ignoredHeaders containsObject:expectedHeader]) { if ([ignoredHeaders containsObject:expectedHeader]) {
continue; continue;
@@ -1171,10 +1153,10 @@ static void _LogResult(NSString* format, ...) {
} }
} }
NSString* expectedContentLength = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyHeaderFieldValue(expectedResponse, CFSTR("Content-Length"))); NSString* expectedContentLength = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(expectedResponse, CFSTR("Content-Length")));
NSData* expectedBody = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyBody(expectedResponse)); NSData* expectedBody = CFBridgingRelease(CFHTTPMessageCopyBody(expectedResponse));
NSString* actualContentLength = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyHeaderFieldValue(actualResponse, CFSTR("Content-Length"))); NSString* actualContentLength = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(actualResponse, CFSTR("Content-Length")));
NSData* actualBody = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyBody(actualResponse)); NSData* actualBody = CFBridgingRelease(CFHTTPMessageCopyBody(actualResponse));
if ([actualContentLength isEqualToString:expectedContentLength] && (actualBody.length > expectedBody.length)) { // Handle web browser closing connection before retrieving entire body (e.g. when playing a video file) if ([actualContentLength isEqualToString:expectedContentLength] && (actualBody.length > expectedBody.length)) { // Handle web browser closing connection before retrieving entire body (e.g. when playing a video file)
actualBody = [actualBody subdataWithRange:NSMakeRange(0, expectedBody.length)]; actualBody = [actualBody subdataWithRange:NSMakeRange(0, expectedBody.length)];
} }
@@ -1191,7 +1173,6 @@ static void _LogResult(NSString* format, ...) {
[task setLaunchPath:@"/usr/bin/opendiff"]; [task setLaunchPath:@"/usr/bin/opendiff"];
[task setArguments:@[expectedPath, actualPath]]; [task setArguments:@[expectedPath, actualPath]];
[task launch]; [task launch];
ARC_RELEASE(task);
} }
} }
#endif #endif

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import <TargetConditionals.h> #import <TargetConditionals.h>
#import <netdb.h> #import <netdb.h>
#ifdef __GCDWEBSERVER_ENABLE_TESTING__ #ifdef __GCDWEBSERVER_ENABLE_TESTING__
@@ -172,7 +176,6 @@ static int32_t _connectionCounter = 0;
} }
}]; }];
ARC_RELEASE(bodyData);
} }
static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) { static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
@@ -244,15 +247,8 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
@implementation GCDWebServerConnection (Write) @implementation GCDWebServerConnection (Write)
- (void)_writeData:(NSData*)data withCompletionBlock:(WriteDataCompletionBlock)block { - (void)_writeData:(NSData*)data withCompletionBlock:(WriteDataCompletionBlock)block {
#if !__has_feature(objc_arc)
[data retain];
#endif
dispatch_data_t buffer = dispatch_data_create(data.bytes, data.length, kGCDWebServerGCDQueue, ^{ dispatch_data_t buffer = dispatch_data_create(data.bytes, data.length, kGCDWebServerGCDQueue, ^{
#if __has_feature(objc_arc)
[data self]; // Keeps ARC from releasing data too early [data self]; // Keeps ARC from releasing data too early
#else
[data release];
#endif
}); });
dispatch_write(_socket, buffer, kGCDWebServerGCDQueue, ^(dispatch_data_t remainingData, int error) { dispatch_write(_socket, buffer, kGCDWebServerGCDQueue, ^(dispatch_data_t remainingData, int error) {
@@ -268,13 +264,15 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
}); });
ARC_DISPATCH_RELEASE(buffer); #if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE
dispatch_release(buffer);
#endif
} }
- (void)_writeHeadersWithCompletionBlock:(WriteHeadersCompletionBlock)block { - (void)_writeHeadersWithCompletionBlock:(WriteHeadersCompletionBlock)block {
GWS_DCHECK(_responseMessage); GWS_DCHECK(_responseMessage);
CFDataRef data = CFHTTPMessageCopySerializedMessage(_responseMessage); CFDataRef data = CFHTTPMessageCopySerializedMessage(_responseMessage);
[self _writeData:(ARC_BRIDGE NSData*)data withCompletionBlock:block]; [self _writeData:(__bridge NSData*)data withCompletionBlock:block];
CFRelease(data); CFRelease(data);
} }
@@ -349,11 +347,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
if (_continueData == nil) { if (_continueData == nil) {
CFHTTPMessageRef message = CFHTTPMessageCreateResponse(kCFAllocatorDefault, 100, NULL, kCFHTTPVersion1_1); CFHTTPMessageRef message = CFHTTPMessageCreateResponse(kCFAllocatorDefault, 100, NULL, kCFHTTPVersion1_1);
#if __has_feature(objc_arc)
_continueData = CFBridgingRelease(CFHTTPMessageCopySerializedMessage(message)); _continueData = CFBridgingRelease(CFHTTPMessageCopySerializedMessage(message));
#else
_continueData = (NSData*)CFHTTPMessageCopySerializedMessage(message);
#endif
CFRelease(message); CFRelease(message);
GWS_DCHECK(_continueData); GWS_DCHECK(_continueData);
} }
@@ -362,7 +356,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
if (_digestAuthenticationNonce == nil) { if (_digestAuthenticationNonce == nil) {
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
_digestAuthenticationNonce = ARC_RETAIN(GCDWebServerComputeMD5Digest(@"%@", ARC_BRIDGE_RELEASE(CFUUIDCreateString(kCFAllocatorDefault, uuid)))); _digestAuthenticationNonce = GCDWebServerComputeMD5Digest(@"%@", CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid)));
CFRelease(uuid); CFRelease(uuid);
} }
} }
@@ -376,8 +370,8 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
_statusCode = statusCode; _statusCode = statusCode;
_responseMessage = CFHTTPMessageCreateResponse(kCFAllocatorDefault, statusCode, NULL, kCFHTTPVersion1_1); _responseMessage = CFHTTPMessageCreateResponse(kCFAllocatorDefault, statusCode, NULL, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Connection"), CFSTR("Close")); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Connection"), CFSTR("Close"));
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (ARC_BRIDGE CFStringRef)_server.serverName); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (__bridge CFStringRef)_server.serverName);
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatRFC822([NSDate date])); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (__bridge CFStringRef)GCDWebServerFormatRFC822([NSDate date]));
} }
- (void)_startProcessingRequest { - (void)_startProcessingRequest {
@@ -410,36 +404,36 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
if (hasBody && ![response performOpen:&error]) { if (hasBody && ![response performOpen:&error]) {
GWS_LOG_ERROR(@"Failed opening response body for socket %i: %@", _socket, error); GWS_LOG_ERROR(@"Failed opening response body for socket %i: %@", _socket, error);
} else { } else {
_response = ARC_RETAIN(response); _response = response;
} }
} }
if (_response) { if (_response) {
[self _initializeResponseHeadersWithStatusCode:_response.statusCode]; [self _initializeResponseHeadersWithStatusCode:_response.statusCode];
if (_response.lastModifiedDate) { if (_response.lastModifiedDate) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatRFC822(_response.lastModifiedDate)); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (__bridge CFStringRef)GCDWebServerFormatRFC822(_response.lastModifiedDate));
} }
if (_response.eTag) { if (_response.eTag) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("ETag"), (ARC_BRIDGE CFStringRef)_response.eTag); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("ETag"), (__bridge CFStringRef)_response.eTag);
} }
if ((_response.statusCode >= 200) && (_response.statusCode < 300)) { if ((_response.statusCode >= 200) && (_response.statusCode < 300)) {
if (_response.cacheControlMaxAge > 0) { if (_response.cacheControlMaxAge > 0) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)_response.cacheControlMaxAge]); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (__bridge CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)_response.cacheControlMaxAge]);
} else { } else {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), CFSTR("no-cache")); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), CFSTR("no-cache"));
} }
} }
if (_response.contentType != nil) { if (_response.contentType != nil) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Type"), (ARC_BRIDGE CFStringRef)GCDWebServerNormalizeHeaderValue(_response.contentType)); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Type"), (__bridge CFStringRef)GCDWebServerNormalizeHeaderValue(_response.contentType));
} }
if (_response.contentLength != NSUIntegerMax) { if (_response.contentLength != NSUIntegerMax) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Length"), (ARC_BRIDGE CFStringRef)[NSString stringWithFormat:@"%lu", (unsigned long)_response.contentLength]); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Length"), (__bridge CFStringRef)[NSString stringWithFormat:@"%lu", (unsigned long)_response.contentLength]);
} }
if (_response.usesChunkedTransferEncoding) { if (_response.usesChunkedTransferEncoding) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Transfer-Encoding"), CFSTR("chunked")); CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Transfer-Encoding"), CFSTR("chunked"));
} }
[_response.additionalHeaders enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL* stop) { [_response.additionalHeaders enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL* stop) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, (ARC_BRIDGE CFStringRef)key, (ARC_BRIDGE CFStringRef)obj); CFHTTPMessageSetHeaderFieldValue(_responseMessage, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);
}]; }];
[self _writeHeadersWithCompletionBlock:^(BOOL success) { [self _writeHeadersWithCompletionBlock:^(BOOL success) {
@@ -524,7 +518,6 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
}]; }];
ARC_RELEASE(chunkData);
} }
- (void)_readRequestHeaders { - (void)_readRequestHeaders {
@@ -533,23 +526,23 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
[self _readHeaders:headersData withCompletionBlock:^(NSData* extraData) { [self _readHeaders:headersData withCompletionBlock:^(NSData* extraData) {
if (extraData) { if (extraData) {
NSString* requestMethod = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestMethod(_requestMessage)); // Method verbs are case-sensitive and uppercase NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(_requestMessage)); // Method verbs are case-sensitive and uppercase
if (_server.shouldAutomaticallyMapHEADToGET && [requestMethod isEqualToString:@"HEAD"]) { if (_server.shouldAutomaticallyMapHEADToGET && [requestMethod isEqualToString:@"HEAD"]) {
requestMethod = @"GET"; requestMethod = @"GET";
_virtualHEAD = YES; _virtualHEAD = YES;
} }
NSDictionary* requestHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones NSDictionary* requestHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones
NSURL* requestURL = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestURL(_requestMessage)); NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(_requestMessage));
if (requestURL) { if (requestURL) {
requestURL = [self rewriteRequestURL:requestURL withMethod:requestMethod headers:requestHeaders]; requestURL = [self rewriteRequestURL:requestURL withMethod:requestMethod headers:requestHeaders];
GWS_DCHECK(requestURL); GWS_DCHECK(requestURL);
} }
NSString* requestPath = requestURL ? GCDWebServerUnescapeURLString(ARC_BRIDGE_RELEASE(CFURLCopyPath((CFURLRef)requestURL))) : nil; // Don't use -[NSURL path] which strips the ending slash NSString* requestPath = requestURL ? GCDWebServerUnescapeURLString(CFBridgingRelease(CFURLCopyPath((CFURLRef)requestURL))) : nil; // Don't use -[NSURL path] which strips the ending slash
NSString* queryString = requestURL ? ARC_BRIDGE_RELEASE(CFURLCopyQueryString((CFURLRef)requestURL, NULL)) : nil; // Don't use -[NSURL query] to make sure query is not unescaped; NSString* queryString = requestURL ? CFBridgingRelease(CFURLCopyQueryString((CFURLRef)requestURL, NULL)) : nil; // Don't use -[NSURL query] to make sure query is not unescaped;
NSDictionary* requestQuery = queryString ? GCDWebServerParseURLEncodedForm(queryString) : @{}; NSDictionary* requestQuery = queryString ? GCDWebServerParseURLEncodedForm(queryString) : @{};
if (requestMethod && requestURL && requestHeaders && requestPath && requestQuery) { if (requestMethod && requestURL && requestHeaders && requestPath && requestQuery) {
for (_handler in _server.handlers) { for (_handler in _server.handlers) {
_request = ARC_RETAIN(_handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery)); _request = _handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery);
if (_request) { if (_request) {
break; break;
} }
@@ -604,14 +597,13 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
}]; }];
ARC_RELEASE(headersData);
} }
- (id)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket { - (id)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket {
if ((self = [super init])) { if ((self = [super init])) {
_server = ARC_RETAIN(server); _server = server;
_localAddress = ARC_RETAIN(localAddress); _localAddress = localAddress;
_remoteAddress = ARC_RETAIN(remoteAddress); _remoteAddress = remoteAddress;
_socket = socket; _socket = socket;
GWS_LOG_DEBUG(@"Did open connection on socket %i", _socket); GWS_LOG_DEBUG(@"Did open connection on socket %i", _socket);
@@ -619,7 +611,6 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
if (![self open]) { if (![self open]) {
close(_socket); close(_socket);
ARC_RELEASE(self);
return nil; return nil;
} }
_opened = YES; _opened = YES;
@@ -650,26 +641,14 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
} }
[_server didEndConnection:self]; [_server didEndConnection:self];
ARC_RELEASE(_server);
ARC_RELEASE(_localAddress);
ARC_RELEASE(_remoteAddress);
if (_requestMessage) { if (_requestMessage) {
CFRelease(_requestMessage); CFRelease(_requestMessage);
} }
ARC_RELEASE(_request);
if (_responseMessage) { if (_responseMessage) {
CFRelease(_responseMessage); CFRelease(_responseMessage);
} }
ARC_RELEASE(_response);
#ifdef __GCDWEBSERVER_ENABLE_TESTING__
ARC_RELEASE(_requestPath);
ARC_RELEASE(_responsePath);
#endif
ARC_DEALLOC(super);
} }
@end @end
@@ -681,11 +660,11 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) {
if (_server.recordingEnabled) { if (_server.recordingEnabled) {
_connectionIndex = OSAtomicIncrement32(&_connectionCounter); _connectionIndex = OSAtomicIncrement32(&_connectionCounter);
_requestPath = ARC_RETAIN([NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]); _requestPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
_requestFD = open([_requestPath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); _requestFD = open([_requestPath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
GWS_DCHECK(_requestFD > 0); GWS_DCHECK(_requestFD > 0);
_responsePath = ARC_RETAIN([NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]); _responsePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
_responseFD = open([_responsePath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); _responseFD = open([_responsePath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
GWS_DCHECK(_responseFD > 0); GWS_DCHECK(_responseFD > 0);
} }

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import <TargetConditionals.h> #import <TargetConditionals.h>
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
#import <MobileCoreServices/MobileCoreServices.h> #import <MobileCoreServices/MobileCoreServices.h>
@@ -50,14 +54,14 @@ void GCDWebServerInitializeFunctions() {
_dateFormatterRFC822 = [[NSDateFormatter alloc] init]; _dateFormatterRFC822 = [[NSDateFormatter alloc] init];
_dateFormatterRFC822.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; _dateFormatterRFC822.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
_dateFormatterRFC822.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'"; _dateFormatterRFC822.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'";
_dateFormatterRFC822.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]); _dateFormatterRFC822.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
GWS_DCHECK(_dateFormatterRFC822); GWS_DCHECK(_dateFormatterRFC822);
} }
if (_dateFormatterISO8601 == nil) { if (_dateFormatterISO8601 == nil) {
_dateFormatterISO8601 = [[NSDateFormatter alloc] init]; _dateFormatterISO8601 = [[NSDateFormatter alloc] init];
_dateFormatterISO8601.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; _dateFormatterISO8601.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
_dateFormatterISO8601.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'+00:00'"; _dateFormatterISO8601.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'+00:00'";
_dateFormatterISO8601.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]); _dateFormatterISO8601.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
GWS_DCHECK(_dateFormatterISO8601); GWS_DCHECK(_dateFormatterISO8601);
} }
if (_dateFormatterQueue == NULL) { if (_dateFormatterQueue == NULL) {
@@ -96,7 +100,6 @@ NSString* GCDWebServerExtractHeaderValueParameter(NSString* value, NSString* nam
[scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:&parameter]; [scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:&parameter];
} }
} }
ARC_RELEASE(scanner);
return parameter; return parameter;
} }
@@ -150,7 +153,7 @@ NSString* GCDWebServerDescribeData(NSData* data, NSString* type) {
NSString* charset = GCDWebServerExtractHeaderValueParameter(type, @"charset"); NSString* charset = GCDWebServerExtractHeaderValueParameter(type, @"charset");
NSString* string = [[NSString alloc] initWithData:data encoding:GCDWebServerStringEncodingFromCharset(charset)]; NSString* string = [[NSString alloc] initWithData:data encoding:GCDWebServerStringEncodingFromCharset(charset)];
if (string) { if (string) {
return ARC_AUTORELEASE(string); return string;
} }
} }
return [NSString stringWithFormat:@"<%lu bytes>", (unsigned long)data.length]; return [NSString stringWithFormat:@"<%lu bytes>", (unsigned long)data.length];
@@ -168,9 +171,9 @@ NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension) {
if (extension.length) { if (extension.length) {
mimeType = [_overrides objectForKey:extension]; mimeType = [_overrides objectForKey:extension];
if (mimeType == nil) { if (mimeType == nil) {
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (ARC_BRIDGE CFStringRef)extension, NULL); CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL);
if (uti) { if (uti) {
mimeType = ARC_BRIDGE_RELEASE(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)); mimeType = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType));
CFRelease(uti); CFRelease(uti);
} }
} }
@@ -179,11 +182,11 @@ NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension) {
} }
NSString* GCDWebServerEscapeURLString(NSString* string) { NSString* GCDWebServerEscapeURLString(NSString* string) {
return ARC_BRIDGE_RELEASE(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":@/?&=+"), kCFStringEncodingUTF8)); return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":@/?&=+"), kCFStringEncodingUTF8));
} }
NSString* GCDWebServerUnescapeURLString(NSString* string) { NSString* GCDWebServerUnescapeURLString(NSString* string) {
return ARC_BRIDGE_RELEASE(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (CFStringRef)string, CFSTR(""), kCFStringEncodingUTF8)); return CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (CFStringRef)string, CFSTR(""), kCFStringEncodingUTF8));
} }
NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form) { NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form) {
@@ -219,7 +222,6 @@ NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form) {
} }
[scanner setScanLocation:([scanner scanLocation] + 1)]; [scanner setScanLocation:([scanner scanLocation] + 1)];
} }
ARC_RELEASE(scanner);
return parameters; return parameters;
} }
@@ -247,7 +249,7 @@ NSString* GCDWebServerGetPrimaryIPAddress(BOOL useIPv6) {
if (store) { if (store) {
CFPropertyListRef info = SCDynamicStoreCopyValue(store, CFSTR("State:/Network/Global/IPv4")); // There is no equivalent for IPv6 but the primary interface should be the same CFPropertyListRef info = SCDynamicStoreCopyValue(store, CFSTR("State:/Network/Global/IPv4")); // There is no equivalent for IPv6 but the primary interface should be the same
if (info) { if (info) {
primaryInterface = [[NSString stringWithString:[(ARC_BRIDGE NSDictionary*)info objectForKey:@"PrimaryInterface"]] UTF8String]; primaryInterface = [[NSString stringWithString:[(__bridge NSDictionary*)info objectForKey:@"PrimaryInterface"]] UTF8String];
CFRelease(info); CFRelease(info);
} }
CFRelease(store); CFRelease(store);
@@ -280,7 +282,7 @@ NSString* GCDWebServerGetPrimaryIPAddress(BOOL useIPv6) {
NSString* GCDWebServerComputeMD5Digest(NSString* format, ...) { NSString* GCDWebServerComputeMD5Digest(NSString* format, ...) {
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
const char* string = [ARC_AUTORELEASE([[NSString alloc] initWithFormat:format arguments:arguments]) UTF8String]; const char* string = [[[NSString alloc] initWithFormat:format arguments:arguments] UTF8String];
va_end(arguments); va_end(arguments);
unsigned char md5[CC_MD5_DIGEST_LENGTH]; unsigned char md5[CC_MD5_DIGEST_LENGTH];
CC_MD5(string, (CC_LONG)strlen(string), md5); CC_MD5(string, (CC_LONG)strlen(string), md5);

View File

@@ -28,35 +28,6 @@
#import <os/object.h> #import <os/object.h>
#import <sys/socket.h> #import <sys/socket.h>
/**
* ARC <-> MRC compatibility macros.
*/
#if __has_feature(objc_arc)
#define ARC_BRIDGE __bridge
#define ARC_BRIDGE_RELEASE(__OBJECT__) CFBridgingRelease(__OBJECT__)
#define ARC_RETAIN(__OBJECT__) __OBJECT__
#define ARC_RELEASE(__OBJECT__)
#define ARC_AUTORELEASE(__OBJECT__) __OBJECT__
#define ARC_DEALLOC(__OBJECT__)
#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
#define ARC_DISPATCH_RETAIN(__OBJECT__)
#define ARC_DISPATCH_RELEASE(__OBJECT__)
#else
#define ARC_DISPATCH_RETAIN(__OBJECT__) dispatch_retain(__OBJECT__)
#define ARC_DISPATCH_RELEASE(__OBJECT__) dispatch_release(__OBJECT__)
#endif
#else
#define ARC_BRIDGE
#define ARC_BRIDGE_RELEASE(__OBJECT__) [(id)__OBJECT__ autorelease]
#define ARC_RETAIN(__OBJECT__) [__OBJECT__ retain]
#define ARC_RELEASE(__OBJECT__) [__OBJECT__ release]
#define ARC_AUTORELEASE(__OBJECT__) [__OBJECT__ autorelease]
#define ARC_DEALLOC(__OBJECT__) [__OBJECT__ dealloc]
#define ARC_DISPATCH_RETAIN(__OBJECT__) dispatch_retain(__OBJECT__)
#define ARC_DISPATCH_RELEASE(__OBJECT__) dispatch_release(__OBJECT__)
#endif
/** /**
* All GCDWebServer headers. * All GCDWebServer headers.
*/ */
@@ -86,6 +57,9 @@
#define __GCDWEBSERVER_LOGGING_FACILITY_XLFACILITY__ #define __GCDWEBSERVER_LOGGING_FACILITY_XLFACILITY__
#undef XLOG_TAG
#define XLOG_TAG @"gcdwebserver.internal"
#import "XLFacilityMacros.h" #import "XLFacilityMacros.h"
#define GWS_LOG_DEBUG(...) XLOG_DEBUG(__VA_ARGS__) #define GWS_LOG_DEBUG(...) XLOG_DEBUG(__VA_ARGS__)

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import <zlib.h> #import <zlib.h>
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@@ -110,7 +114,6 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
_stream.avail_out = (uInt)maxLength; _stream.avail_out = (uInt)maxLength;
int result = inflate(&_stream, Z_NO_FLUSH); int result = inflate(&_stream, Z_NO_FLUSH);
if ((result != Z_OK) && (result != Z_STREAM_END)) { if ((result != Z_OK) && (result != Z_STREAM_END)) {
ARC_RELEASE(decodedData);
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil]; *error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
return NO; return NO;
} }
@@ -125,7 +128,6 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
} }
decodedData.length = length; decodedData.length = length;
BOOL success = length ? [super writeData:decodedData error:error] : YES; // No need to call writer if we have no data yet BOOL success = length ? [super writeData:decodedData error:error] : YES; // No need to call writer if we have no data yet
ARC_RELEASE(decodedData);
return success; return success;
} }
@@ -167,19 +169,18 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query { - (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
if ((self = [super init])) { if ((self = [super init])) {
_method = [method copy]; _method = [method copy];
_url = ARC_RETAIN(url); _url = url;
_headers = ARC_RETAIN(headers); _headers = headers;
_path = [path copy]; _path = [path copy];
_query = ARC_RETAIN(query); _query = query;
_type = ARC_RETAIN(GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Content-Type"])); _type = GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Content-Type"]);
_chunked = [GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Transfer-Encoding"]) isEqualToString:@"chunked"]; _chunked = [GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Transfer-Encoding"]) isEqualToString:@"chunked"];
NSString* lengthHeader = [_headers objectForKey:@"Content-Length"]; NSString* lengthHeader = [_headers objectForKey:@"Content-Length"];
if (lengthHeader) { if (lengthHeader) {
NSInteger length = [lengthHeader integerValue]; NSInteger length = [lengthHeader integerValue];
if (_chunked || (length < 0)) { if (_chunked || (length < 0)) {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
ARC_RELEASE(self);
return nil; return nil;
} }
_length = length; _length = length;
@@ -194,7 +195,6 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
} else { } else {
if (_type) { if (_type) {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
ARC_RELEASE(self);
return nil; return nil;
} }
_length = NSUIntegerMax; _length = NSUIntegerMax;
@@ -204,7 +204,7 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
if (modifiedHeader) { if (modifiedHeader) {
_modifiedSince = [GCDWebServerParseRFC822(modifiedHeader) copy]; _modifiedSince = [GCDWebServerParseRFC822(modifiedHeader) copy];
} }
_noneMatch = ARC_RETAIN([_headers objectForKey:@"If-None-Match"]); _noneMatch = [_headers objectForKey:@"If-None-Match"];
_range = NSMakeRange(NSUIntegerMax, 0); _range = NSMakeRange(NSUIntegerMax, 0);
NSString* rangeHeader = GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Range"]); NSString* rangeHeader = GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Range"]);
@@ -246,21 +246,6 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_method);
ARC_RELEASE(_url);
ARC_RELEASE(_headers);
ARC_RELEASE(_path);
ARC_RELEASE(_query);
ARC_RELEASE(_type);
ARC_RELEASE(_modifiedSince);
ARC_RELEASE(_noneMatch);
ARC_RELEASE(_decoders);
ARC_RELEASE(_attributes);
ARC_DEALLOC(super);
}
- (BOOL)hasBody { - (BOOL)hasBody {
return _type ? YES : NO; return _type ? YES : NO;
} }
@@ -290,7 +275,6 @@ NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerReque
if ([GCDWebServerNormalizeHeaderValue([self.headers objectForKey:@"Content-Encoding"]) isEqualToString:@"gzip"]) { if ([GCDWebServerNormalizeHeaderValue([self.headers objectForKey:@"Content-Encoding"]) isEqualToString:@"gzip"]) {
GCDWebServerGZipDecoder* decoder = [[GCDWebServerGZipDecoder alloc] initWithRequest:self writer:_writer]; GCDWebServerGZipDecoder* decoder = [[GCDWebServerGZipDecoder alloc] initWithRequest:self writer:_writer];
[_decoders addObject:decoder]; [_decoders addObject:decoder];
ARC_RELEASE(decoder);
_writer = decoder; _writer = decoder;
} }
} }

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import <zlib.h> #import <zlib.h>
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@@ -126,7 +130,6 @@
if (result == Z_STREAM_END) { if (result == Z_STREAM_END) {
_finished = YES; _finished = YES;
} else if (result != Z_OK) { } else if (result != Z_OK) {
ARC_RELEASE(encodedData);
*error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil]; *error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil];
return nil; return nil;
} }
@@ -140,7 +143,7 @@
} while (length == 0); // Make sure we don't return an empty NSData if not in finished state } while (length == 0); // Make sure we don't return an empty NSData if not in finished state
encodedData.length = length; encodedData.length = length;
} }
return ARC_AUTORELEASE(encodedData); return encodedData;
} }
- (void)close { - (void)close {
@@ -174,7 +177,7 @@
gzipContentEncodingEnabled=_gzipped, additionalHeaders=_headers; gzipContentEncodingEnabled=_gzipped, additionalHeaders=_headers;
+ (instancetype)response { + (instancetype)response {
return ARC_AUTORELEASE([[[self class] alloc] init]); return [[[self class] alloc] init];
} }
- (instancetype)init { - (instancetype)init {
@@ -189,16 +192,6 @@
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_type);
ARC_RELEASE(_lastModified);
ARC_RELEASE(_eTag);
ARC_RELEASE(_headers);
ARC_RELEASE(_encoders);
ARC_DEALLOC(super);
}
- (void)setValue:(NSString*)value forAdditionalHeader:(NSString*)header { - (void)setValue:(NSString*)value forAdditionalHeader:(NSString*)header {
[_headers setValue:value forKey:header]; [_headers setValue:value forKey:header];
} }
@@ -228,7 +221,6 @@
if (_gzipped) { if (_gzipped) {
GCDWebServerGZipEncoder* encoder = [[GCDWebServerGZipEncoder alloc] initWithResponse:self reader:_reader]; GCDWebServerGZipEncoder* encoder = [[GCDWebServerGZipEncoder alloc] initWithResponse:self reader:_reader];
[_encoders addObject:encoder]; [_encoders addObject:encoder];
ARC_RELEASE(encoder);
_reader = encoder; _reader = encoder;
} }
} }
@@ -288,11 +280,11 @@
@implementation GCDWebServerResponse (Extensions) @implementation GCDWebServerResponse (Extensions)
+ (instancetype)responseWithStatusCode:(NSInteger)statusCode { + (instancetype)responseWithStatusCode:(NSInteger)statusCode {
return ARC_AUTORELEASE([[self alloc] initWithStatusCode:statusCode]); return [[self alloc] initWithStatusCode:statusCode];
} }
+ (instancetype)responseWithRedirect:(NSURL*)location permanent:(BOOL)permanent { + (instancetype)responseWithRedirect:(NSURL*)location permanent:(BOOL)permanent {
return ARC_AUTORELEASE([[self alloc] initWithRedirect:location permanent:permanent]); return [[self alloc] initWithRedirect:location permanent:permanent];
} }
- (instancetype)initWithStatusCode:(NSInteger)statusCode { - (instancetype)initWithStatusCode:(NSInteger)statusCode {

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@interface GCDWebServerDataRequest () { @interface GCDWebServerDataRequest () {
@@ -40,14 +44,6 @@
@synthesize data=_data; @synthesize data=_data;
- (void)dealloc {
ARC_RELEASE(_data);
ARC_RELEASE(_text);
ARC_RELEASE(_jsonObject);
ARC_DEALLOC(super);
}
- (BOOL)open:(NSError**)error { - (BOOL)open:(NSError**)error {
if (self.contentLength != NSUIntegerMax) { if (self.contentLength != NSUIntegerMax) {
_data = [[NSMutableData alloc] initWithCapacity:self.contentLength]; _data = [[NSMutableData alloc] initWithCapacity:self.contentLength];
@@ -99,7 +95,7 @@
if (_jsonObject == nil) { if (_jsonObject == nil) {
NSString* mimeType = GCDWebServerTruncateHeaderValue(self.contentType); NSString* mimeType = GCDWebServerTruncateHeaderValue(self.contentType);
if ([mimeType isEqualToString:@"application/json"] || [mimeType isEqualToString:@"text/json"] || [mimeType isEqualToString:@"text/javascript"]) { if ([mimeType isEqualToString:@"application/json"] || [mimeType isEqualToString:@"text/json"] || [mimeType isEqualToString:@"text/javascript"]) {
_jsonObject = ARC_RETAIN([NSJSONSerialization JSONObjectWithData:_data options:0 error:NULL]); _jsonObject = [NSJSONSerialization JSONObjectWithData:_data options:0 error:NULL];
} else { } else {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
} }

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@interface GCDWebServerFileRequest () { @interface GCDWebServerFileRequest () {
@@ -40,16 +44,13 @@
- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query { - (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query {
if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) { if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) {
_temporaryPath = ARC_RETAIN([NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]); _temporaryPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]];
} }
return self; return self;
} }
- (void)dealloc { - (void)dealloc {
unlink([_temporaryPath fileSystemRepresentation]); unlink([_temporaryPath fileSystemRepresentation]);
ARC_RELEASE(_temporaryPath);
ARC_DEALLOC(super);
} }
- (BOOL)open:(NSError**)error { - (BOOL)open:(NSError**)error {

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
#define kMultiPartBufferSize (256 * 1024) #define kMultiPartBufferSize (256 * 1024)
@@ -63,19 +67,11 @@ static NSData* _dashNewlineData = nil;
if ((self = [super init])) { if ((self = [super init])) {
_controlName = [name copy]; _controlName = [name copy];
_contentType = [type copy]; _contentType = [type copy];
_mimeType = ARC_RETAIN(GCDWebServerTruncateHeaderValue(_contentType)); _mimeType = GCDWebServerTruncateHeaderValue(_contentType);
} }
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_controlName);
ARC_RELEASE(_contentType);
ARC_RELEASE(_mimeType);
ARC_DEALLOC(super);
}
@end @end
@interface GCDWebServerMultiPartArgument () { @interface GCDWebServerMultiPartArgument () {
@@ -91,7 +87,7 @@ static NSData* _dashNewlineData = nil;
- (id)initWithControlName:(NSString*)name contentType:(NSString*)type data:(NSData*)data { - (id)initWithControlName:(NSString*)name contentType:(NSString*)type data:(NSData*)data {
if ((self = [super initWithControlName:name contentType:type])) { if ((self = [super initWithControlName:name contentType:type])) {
_data = ARC_RETAIN(data); _data = data;
if ([self.contentType hasPrefix:@"text/"]) { if ([self.contentType hasPrefix:@"text/"]) {
NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset"); NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset");
@@ -101,13 +97,6 @@ static NSData* _dashNewlineData = nil;
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_data);
ARC_RELEASE(_string);
ARC_DEALLOC(super);
}
- (NSString*)description { - (NSString*)description {
return [NSString stringWithFormat:@"<%@ | '%@' | %lu bytes>", [self class], self.mimeType, (unsigned long)_data.length]; return [NSString stringWithFormat:@"<%@ | '%@' | %lu bytes>", [self class], self.mimeType, (unsigned long)_data.length];
} }
@@ -135,11 +124,6 @@ static NSData* _dashNewlineData = nil;
- (void)dealloc { - (void)dealloc {
unlink([_temporaryPath fileSystemRepresentation]); unlink([_temporaryPath fileSystemRepresentation]);
ARC_RELEASE(_fileName);
ARC_RELEASE(_temporaryPath);
ARC_DEALLOC(super);
} }
- (NSString*)description { - (NSString*)description {
@@ -187,14 +171,13 @@ static NSData* _dashNewlineData = nil;
NSData* data = boundary.length ? [[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSASCIIStringEncoding] : nil; NSData* data = boundary.length ? [[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSASCIIStringEncoding] : nil;
if (data == nil) { if (data == nil) {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
ARC_RELEASE(self);
return nil; return nil;
} }
if ((self = [super init])) { if ((self = [super init])) {
_boundary = ARC_RETAIN(data); _boundary = data;
_defaultcontrolName = ARC_RETAIN(name); _defaultcontrolName = name;
_arguments = ARC_RETAIN(arguments); _arguments = arguments;
_files = ARC_RETAIN(files); _files = files;
_data = [[NSMutableData alloc] initWithCapacity:kMultiPartBufferSize]; _data = [[NSMutableData alloc] initWithCapacity:kMultiPartBufferSize];
_state = kParserState_Start; _state = kParserState_Start;
} }
@@ -202,23 +185,10 @@ static NSData* _dashNewlineData = nil;
} }
- (void)dealloc { - (void)dealloc {
ARC_RELEASE(_boundary);
ARC_RELEASE(_defaultcontrolName);
ARC_RELEASE(_data);
ARC_RELEASE(_arguments);
ARC_RELEASE(_files);
ARC_RELEASE(_controlName);
ARC_RELEASE(_fileName);
ARC_RELEASE(_contentType);
if (_tmpFile > 0) { if (_tmpFile > 0) {
close(_tmpFile); close(_tmpFile);
unlink([_tmpPath fileSystemRepresentation]); unlink([_tmpPath fileSystemRepresentation]);
} }
ARC_RELEASE(_tmpPath);
ARC_RELEASE(_subParser);
ARC_DEALLOC(super);
} }
// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 // http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2
@@ -229,15 +199,10 @@ static NSData* _dashNewlineData = nil;
NSRange range = [_data rangeOfData:_newlinesData options:0 range:NSMakeRange(0, _data.length)]; NSRange range = [_data rangeOfData:_newlinesData options:0 range:NSMakeRange(0, _data.length)];
if (range.location != NSNotFound) { if (range.location != NSNotFound) {
ARC_RELEASE(_controlName);
_controlName = nil; _controlName = nil;
ARC_RELEASE(_fileName);
_fileName = nil; _fileName = nil;
ARC_RELEASE(_contentType);
_contentType = nil; _contentType = nil;
ARC_RELEASE(_tmpPath);
_tmpPath = nil; _tmpPath = nil;
ARC_RELEASE(_subParser);
_subParser = nil; _subParser = nil;
NSString* headers = [[NSString alloc] initWithData:[_data subdataWithRange:NSMakeRange(0, range.location)] encoding:NSUTF8StringEncoding]; NSString* headers = [[NSString alloc] initWithData:[_data subdataWithRange:NSMakeRange(0, range.location)] encoding:NSUTF8StringEncoding];
if (headers) { if (headers) {
@@ -247,15 +212,15 @@ static NSData* _dashNewlineData = nil;
NSString* name = [header substringToIndex:subRange.location]; NSString* name = [header substringToIndex:subRange.location];
NSString* value = [[header substringFromIndex:(subRange.location + subRange.length)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSString* value = [[header substringFromIndex:(subRange.location + subRange.length)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([name caseInsensitiveCompare:@"Content-Type"] == NSOrderedSame) { if ([name caseInsensitiveCompare:@"Content-Type"] == NSOrderedSame) {
_contentType = ARC_RETAIN(GCDWebServerNormalizeHeaderValue(value)); _contentType = GCDWebServerNormalizeHeaderValue(value);
} else if ([name caseInsensitiveCompare:@"Content-Disposition"] == NSOrderedSame) { } else if ([name caseInsensitiveCompare:@"Content-Disposition"] == NSOrderedSame) {
NSString* contentDisposition = GCDWebServerNormalizeHeaderValue(value); NSString* contentDisposition = GCDWebServerNormalizeHeaderValue(value);
if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"form-data"]) { if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"form-data"]) {
_controlName = ARC_RETAIN(GCDWebServerExtractHeaderValueParameter(contentDisposition, @"name")); _controlName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"name");
_fileName = ARC_RETAIN(GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename")); _fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename");
} else if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"file"]) { } else if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"file"]) {
_controlName = ARC_RETAIN(_defaultcontrolName); _controlName = _defaultcontrolName;
_fileName = ARC_RETAIN(GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename")); _fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename");
} }
} }
} else { } else {
@@ -265,7 +230,6 @@ static NSData* _dashNewlineData = nil;
if (_contentType == nil) { if (_contentType == nil) {
_contentType = @"text/plain"; _contentType = @"text/plain";
} }
ARC_RELEASE(headers);
} else { } else {
GWS_LOG_ERROR(@"Failed decoding headers in part of 'multipart/form-data'"); GWS_LOG_ERROR(@"Failed decoding headers in part of 'multipart/form-data'");
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
@@ -314,7 +278,6 @@ static NSData* _dashNewlineData = nil;
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
success = NO; success = NO;
} }
ARC_RELEASE(_subParser);
_subParser = nil; _subParser = nil;
} else if (_tmpPath) { } else if (_tmpPath) {
ssize_t result = write(_tmpFile, dataBytes, dataLength); ssize_t result = write(_tmpFile, dataBytes, dataLength);
@@ -323,7 +286,6 @@ static NSData* _dashNewlineData = nil;
_tmpFile = 0; _tmpFile = 0;
GCDWebServerMultiPartFile* file = [[GCDWebServerMultiPartFile alloc] initWithControlName:_controlName contentType:_contentType fileName:_fileName temporaryPath:_tmpPath]; GCDWebServerMultiPartFile* file = [[GCDWebServerMultiPartFile alloc] initWithControlName:_controlName contentType:_contentType fileName:_fileName temporaryPath:_tmpPath];
[_files addObject:file]; [_files addObject:file];
ARC_RELEASE(file);
} else { } else {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
success = NO; success = NO;
@@ -332,14 +294,11 @@ static NSData* _dashNewlineData = nil;
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
success = NO; success = NO;
} }
ARC_RELEASE(_tmpPath);
_tmpPath = nil; _tmpPath = nil;
} else { } else {
NSData* data = [[NSData alloc] initWithBytes:(void*)dataBytes length:dataLength]; NSData* data = [[NSData alloc] initWithBytes:(void*)dataBytes length:dataLength];
GCDWebServerMultiPartArgument* argument = [[GCDWebServerMultiPartArgument alloc] initWithControlName:_controlName contentType:_contentType data:data]; GCDWebServerMultiPartArgument* argument = [[GCDWebServerMultiPartArgument alloc] initWithControlName:_controlName contentType:_contentType data:data];
[_arguments addObject:argument]; [_arguments addObject:argument];
ARC_RELEASE(argument);
ARC_RELEASE(data);
} }
} }
@@ -413,13 +372,6 @@ static NSData* _dashNewlineData = nil;
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_arguments);
ARC_RELEASE(_files);
ARC_DEALLOC(super);
}
- (BOOL)open:(NSError**)error { - (BOOL)open:(NSError**)error {
NSString* boundary = GCDWebServerExtractHeaderValueParameter(self.contentType, @"boundary"); NSString* boundary = GCDWebServerExtractHeaderValueParameter(self.contentType, @"boundary");
_parser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:nil arguments:_arguments files:_files]; _parser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:nil arguments:_arguments files:_files];
@@ -440,7 +392,6 @@ static NSData* _dashNewlineData = nil;
- (BOOL)close:(NSError**)error { - (BOOL)close:(NSError**)error {
BOOL atEnd = [_parser isAtEnd]; BOOL atEnd = [_parser isAtEnd];
ARC_RELEASE(_parser);
_parser = nil; _parser = nil;
if (!atEnd) { if (!atEnd) {
*error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed finishing to parse multipart form data"}]; *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Failed finishing to parse multipart form data"}];

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@interface GCDWebServerURLEncodedFormRequest () { @interface GCDWebServerURLEncodedFormRequest () {
@@ -41,12 +45,6 @@
return @"application/x-www-form-urlencoded"; return @"application/x-www-form-urlencoded";
} }
- (void)dealloc {
ARC_RELEASE(_arguments);
ARC_DEALLOC(super);
}
- (BOOL)close:(NSError**)error { - (BOOL)close:(NSError**)error {
if (![super close:error]) { if (![super close:error]) {
return NO; return NO;
@@ -54,9 +52,8 @@
NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset"); NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset");
NSString* string = [[NSString alloc] initWithData:self.data encoding:GCDWebServerStringEncodingFromCharset(charset)]; NSString* string = [[NSString alloc] initWithData:self.data encoding:GCDWebServerStringEncodingFromCharset(charset)];
_arguments = ARC_RETAIN(GCDWebServerParseURLEncodedForm(string)); _arguments = GCDWebServerParseURLEncodedForm(string);
GWS_DCHECK(_arguments); GWS_DCHECK(_arguments);
ARC_RELEASE(string);
return YES; return YES;
} }

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@interface GCDWebServerDataResponse () { @interface GCDWebServerDataResponse () {
@@ -37,18 +41,17 @@
@implementation GCDWebServerDataResponse @implementation GCDWebServerDataResponse
+ (instancetype)responseWithData:(NSData*)data contentType:(NSString*)type { + (instancetype)responseWithData:(NSData*)data contentType:(NSString*)type {
return ARC_AUTORELEASE([[[self class] alloc] initWithData:data contentType:type]); return [[[self class] alloc] initWithData:data contentType:type];
} }
- (instancetype)initWithData:(NSData*)data contentType:(NSString*)type { - (instancetype)initWithData:(NSData*)data contentType:(NSString*)type {
if (data == nil) { if (data == nil) {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
ARC_RELEASE(self);
return nil; return nil;
} }
if ((self = [super init])) { if ((self = [super init])) {
_data = ARC_RETAIN(data); _data = data;
self.contentType = type; self.contentType = type;
self.contentLength = data.length; self.contentLength = data.length;
@@ -56,12 +59,6 @@
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_data);
ARC_DEALLOC(super);
}
- (NSData*)readData:(NSError**)error { - (NSData*)readData:(NSError**)error {
NSData* data; NSData* data;
if (_done) { if (_done) {
@@ -85,30 +82,29 @@
@implementation GCDWebServerDataResponse (Extensions) @implementation GCDWebServerDataResponse (Extensions)
+ (instancetype)responseWithText:(NSString*)text { + (instancetype)responseWithText:(NSString*)text {
return ARC_AUTORELEASE([[self alloc] initWithText:text]); return [[self alloc] initWithText:text];
} }
+ (instancetype)responseWithHTML:(NSString*)html { + (instancetype)responseWithHTML:(NSString*)html {
return ARC_AUTORELEASE([[self alloc] initWithHTML:html]); return [[self alloc] initWithHTML:html];
} }
+ (instancetype)responseWithHTMLTemplate:(NSString*)path variables:(NSDictionary*)variables { + (instancetype)responseWithHTMLTemplate:(NSString*)path variables:(NSDictionary*)variables {
return ARC_AUTORELEASE([[self alloc] initWithHTMLTemplate:path variables:variables]); return [[self alloc] initWithHTMLTemplate:path variables:variables];
} }
+ (instancetype)responseWithJSONObject:(id)object { + (instancetype)responseWithJSONObject:(id)object {
return ARC_AUTORELEASE([[self alloc] initWithJSONObject:object]); return [[self alloc] initWithJSONObject:object];
} }
+ (instancetype)responseWithJSONObject:(id)object contentType:(NSString*)type { + (instancetype)responseWithJSONObject:(id)object contentType:(NSString*)type {
return ARC_AUTORELEASE([[self alloc] initWithJSONObject:object contentType:type]); return [[self alloc] initWithJSONObject:object contentType:type];
} }
- (instancetype)initWithText:(NSString*)text { - (instancetype)initWithText:(NSString*)text {
NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]; NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding];
if (data == nil) { if (data == nil) {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
ARC_RELEASE(self);
return nil; return nil;
} }
return [self initWithData:data contentType:@"text/plain; charset=utf-8"]; return [self initWithData:data contentType:@"text/plain; charset=utf-8"];
@@ -118,7 +114,6 @@
NSData* data = [html dataUsingEncoding:NSUTF8StringEncoding]; NSData* data = [html dataUsingEncoding:NSUTF8StringEncoding];
if (data == nil) { if (data == nil) {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
ARC_RELEASE(self);
return nil; return nil;
} }
return [self initWithData:data contentType:@"text/html; charset=utf-8"]; return [self initWithData:data contentType:@"text/html; charset=utf-8"];
@@ -130,7 +125,6 @@
[html replaceOccurrencesOfString:[NSString stringWithFormat:@"%%%@%%", key] withString:value options:0 range:NSMakeRange(0, html.length)]; [html replaceOccurrencesOfString:[NSString stringWithFormat:@"%%%@%%", key] withString:value options:0 range:NSMakeRange(0, html.length)];
}]; }];
id response = [self initWithHTML:html]; id response = [self initWithHTML:html];
ARC_RELEASE(html);
return response; return response;
} }
@@ -141,7 +135,6 @@
- (instancetype)initWithJSONObject:(id)object contentType:(NSString*)type { - (instancetype)initWithJSONObject:(id)object contentType:(NSString*)type {
NSData* data = [NSJSONSerialization dataWithJSONObject:object options:0 error:NULL]; NSData* data = [NSJSONSerialization dataWithJSONObject:object options:0 error:NULL];
if (data == nil) { if (data == nil) {
ARC_RELEASE(self);
return nil; return nil;
} }
return [self initWithData:data contentType:type]; return [self initWithData:data contentType:type];

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@interface GCDWebServerErrorResponse () @interface GCDWebServerErrorResponse ()
@@ -37,7 +41,7 @@
GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500)); GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500));
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
GCDWebServerErrorResponse* response = ARC_AUTORELEASE([[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments]); GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments];
va_end(arguments); va_end(arguments);
return response; return response;
} }
@@ -46,7 +50,7 @@
GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600)); GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600));
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
GCDWebServerErrorResponse* response = ARC_AUTORELEASE([[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments]); GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments];
va_end(arguments); va_end(arguments);
return response; return response;
} }
@@ -55,7 +59,7 @@
GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500)); GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500));
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
GCDWebServerErrorResponse* response = ARC_AUTORELEASE([[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments]); GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments];
va_end(arguments); va_end(arguments);
return response; return response;
} }
@@ -64,7 +68,7 @@
GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600)); GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600));
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
GCDWebServerErrorResponse* response = ARC_AUTORELEASE([[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments]); GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments];
va_end(arguments); va_end(arguments);
return response; return response;
} }
@@ -82,7 +86,6 @@ static inline NSString* _EscapeHTMLString(NSString* string) {
if ((self = [self initWithHTML:html])) { if ((self = [self initWithHTML:html])) {
self.statusCode = statusCode; self.statusCode = statusCode;
} }
ARC_RELEASE(message);
return self; return self;
} }

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import <sys/stat.h> #import <sys/stat.h>
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@@ -43,19 +47,19 @@
@implementation GCDWebServerFileResponse @implementation GCDWebServerFileResponse
+ (instancetype)responseWithFile:(NSString*)path { + (instancetype)responseWithFile:(NSString*)path {
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path]); return [[[self class] alloc] initWithFile:path];
} }
+ (instancetype)responseWithFile:(NSString*)path isAttachment:(BOOL)attachment { + (instancetype)responseWithFile:(NSString*)path isAttachment:(BOOL)attachment {
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path isAttachment:attachment]); return [[[self class] alloc] initWithFile:path isAttachment:attachment];
} }
+ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range { + (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range {
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path byteRange:range]); return [[[self class] alloc] initWithFile:path byteRange:range];
} }
+ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment { + (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment {
return ARC_AUTORELEASE([[[self class] alloc] initWithFile:path byteRange:range isAttachment:attachment]); return [[[self class] alloc] initWithFile:path byteRange:range isAttachment:attachment];
} }
- (instancetype)initWithFile:(NSString*)path { - (instancetype)initWithFile:(NSString*)path {
@@ -78,13 +82,11 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
struct stat info; struct stat info;
if (lstat([path fileSystemRepresentation], &info) || !(info.st_mode & S_IFREG)) { if (lstat([path fileSystemRepresentation], &info) || !(info.st_mode & S_IFREG)) {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
ARC_RELEASE(self);
return nil; return nil;
} }
#ifndef __LP64__ #ifndef __LP64__
if (info.st_size >= (off_t)4294967295) { // In 32 bit mode, we can't handle files greater than 4 GiBs (don't use "NSUIntegerMax" here to avoid potential unsigned to signed conversion issues) if (info.st_size >= (off_t)4294967295) { // In 32 bit mode, we can't handle files greater than 4 GiBs (don't use "NSUIntegerMax" here to avoid potential unsigned to signed conversion issues)
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
ARC_RELEASE(self);
return nil; return nil;
} }
#endif #endif
@@ -100,7 +102,6 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
range.location = fileSize - range.length; range.location = fileSize - range.length;
} }
if (range.length == 0) { if (range.length == 0) {
ARC_RELEASE(self);
return nil; // TODO: Return 416 status code and "Content-Range: bytes */{file length}" header return nil; // TODO: Return 416 status code and "Content-Range: bytes */{file length}" header
} }
} else { } else {
@@ -125,7 +126,6 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
if (lossyFileName) { if (lossyFileName) {
NSString* value = [NSString stringWithFormat:@"attachment; filename=\"%@\"; filename*=UTF-8''%@", lossyFileName, GCDWebServerEscapeURLString(fileName)]; NSString* value = [NSString stringWithFormat:@"attachment; filename=\"%@\"; filename*=UTF-8''%@", lossyFileName, GCDWebServerEscapeURLString(fileName)];
[self setValue:value forAdditionalHeader:@"Content-Disposition"]; [self setValue:value forAdditionalHeader:@"Content-Disposition"];
ARC_RELEASE(lossyFileName);
} else { } else {
GWS_DNOT_REACHED(); GWS_DNOT_REACHED();
} }
@@ -139,12 +139,6 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_path);
ARC_DEALLOC(super);
}
- (BOOL)open:(NSError**)error { - (BOOL)open:(NSError**)error {
_file = open([_path fileSystemRepresentation], O_NOFOLLOW | O_RDONLY); _file = open([_path fileSystemRepresentation], O_NOFOLLOW | O_RDONLY);
if (_file <= 0) { if (_file <= 0) {
@@ -171,7 +165,7 @@ static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
[data setLength:result]; [data setLength:result];
_size -= result; _size -= result;
} }
return ARC_AUTORELEASE(data); return data;
} }
- (void)close { - (void)close {

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebServer requires ARC
#endif
#import "GCDWebServerPrivate.h" #import "GCDWebServerPrivate.h"
@interface GCDWebServerStreamedResponse () { @interface GCDWebServerStreamedResponse () {
@@ -36,11 +40,11 @@
@implementation GCDWebServerStreamedResponse @implementation GCDWebServerStreamedResponse
+ (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block { + (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type streamBlock:block]); return [[[self class] alloc] initWithContentType:type streamBlock:block];
} }
+ (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block { + (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block {
return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type asyncStreamBlock:block]); return [[[self class] alloc] initWithContentType:type asyncStreamBlock:block];
} }
- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block { - (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
@@ -62,12 +66,6 @@
return self; return self;
} }
- (void)dealloc {
ARC_RELEASE(_block);
ARC_DEALLOC(super);
}
- (void)asyncReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block { - (void)asyncReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block {
_block(block); _block(block);
} }

View File

@@ -65,7 +65,7 @@
<div id="alerts"></div> <div id="alerts"></div>
<div class="btn-toolbar"> <div class="btn-toolbar">
<button type="button" class="btn btn-primary fileinput-button"> <button type="button" class="btn btn-primary fileinput-button" id="upload-file">
<span class="glyphicon glyphicon-upload"></span> Upload Files&hellip; <span class="glyphicon glyphicon-upload"></span> Upload Files&hellip;
<input id="fileupload" type="file" name="files[]" multiple> <input id="fileupload" type="file" name="files[]" multiple>
</button> </button>

View File

@@ -178,6 +178,17 @@ function _reload(path) {
$(document).ready(function() { $(document).ready(function() {
// Workaround Firefox and IE not showing file selection dialog when clicking on "upload-file" <button>
// Making it a <div> instead also works but then it the button doesn't work anymore with tab selection or accessibility
$("#upload-file").click(function(event) {
$("#fileupload").click();
});
// Prevent event bubbling when using workaround above
$("#fileupload").click(function(event) {
event.stopPropagation();
});
$("#fileupload").fileupload({ $("#fileupload").fileupload({
dropZone: $(document), dropZone: $(document),
pasteZone: null, pasteZone: null,

View File

@@ -25,6 +25,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if !__has_feature(objc_arc)
#error GCDWebUploader requires ARC
#endif
#import <TargetConditionals.h> #import <TargetConditionals.h>
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@@ -292,17 +296,10 @@
if ((self = [super init])) { if ((self = [super init])) {
NSBundle* siteBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"GCDWebUploader" ofType:@"bundle"]]; NSBundle* siteBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"GCDWebUploader" ofType:@"bundle"]];
if (siteBundle == nil) { if (siteBundle == nil) {
#if !__has_feature(objc_arc)
[self release];
#endif
return nil; return nil;
} }
_uploadDirectory = [[path stringByStandardizingPath] copy]; _uploadDirectory = [[path stringByStandardizingPath] copy];
#if __has_feature(objc_arc)
GCDWebUploader* __unsafe_unretained server = self; GCDWebUploader* __unsafe_unretained server = self;
#else
__block GCDWebUploader* server = self;
#endif
// Resource files // Resource files
[self addGETHandlerForBasePath:@"/" directoryPath:[siteBundle resourcePath] indexFilename:nil cacheAge:3600 allowRangeRequests:NO]; [self addGETHandlerForBasePath:@"/" directoryPath:[siteBundle resourcePath] indexFilename:nil cacheAge:3600 allowRangeRequests:NO];
@@ -313,11 +310,7 @@
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
NSString* device = [[UIDevice currentDevice] name]; NSString* device = [[UIDevice currentDevice] name];
#else #else
#if __has_feature(objc_arc)
NSString* device = CFBridgingRelease(SCDynamicStoreCopyComputerName(NULL, NULL)); NSString* device = CFBridgingRelease(SCDynamicStoreCopyComputerName(NULL, NULL));
#else
NSString* device = [(id)SCDynamicStoreCopyComputerName(NULL, NULL) autorelease];
#endif
#endif #endif
NSString* title = server.title; NSString* title = server.title;
if (title == nil) { if (title == nil) {
@@ -401,22 +394,6 @@
return self; return self;
} }
#if !__has_feature(objc_arc)
- (void)dealloc {
[_uploadDirectory release];
[_allowedExtensions release];
[_title release];
[_header release];
[_prologue release];
[_epilogue release];
[_footer release];
[super dealloc];
}
#endif
@end @end
@implementation GCDWebUploader (Subclassing) @implementation GCDWebUploader (Subclassing)

View File

@@ -368,11 +368,6 @@ int main(int argc, const char* argv[]) {
} }
} }
#if __has_feature(objc_arc)
fprintf(stdout, " (ARC is ON)\n");
#else
fprintf(stdout, " (ARC is OFF)\n");
#endif
if (webServer) { if (webServer) {
Delegate* delegate = [[Delegate alloc] init]; Delegate* delegate = [[Delegate alloc] init];
@@ -406,10 +401,6 @@ int main(int argc, const char* argv[]) {
} }
} }
webServer.delegate = nil; webServer.delegate = nil;
#if !__has_feature(objc_arc)
[delegate release];
[webServer release];
#endif
} }
} }
return result; return result;

View File

@@ -38,6 +38,7 @@ What's not supported (but not really required from an embedded HTTP server):
Requirements: Requirements:
* OS X 10.7 or later (x86_64) * OS X 10.7 or later (x86_64)
* iOS 5.0 or later (armv7, armv7s or arm64) * iOS 5.0 or later (armv7, armv7s or arm64)
* ARC memory management only (if you need MRC support use GCDWebServer 3.1 and earlier)
Getting Started Getting Started
=============== ===============

View File

@@ -11,13 +11,11 @@ OSX_TARGET="GCDWebServer (Mac)"
IOS_TARGET="GCDWebServer (iOS)" IOS_TARGET="GCDWebServer (iOS)"
CONFIGURATION="Release" CONFIGURATION="Release"
MRC_BUILD_DIR="/tmp/GCDWebServer-MRC" BUILD_DIR="/tmp/GCDWebServer-Build"
MRC_PRODUCT="$MRC_BUILD_DIR/$CONFIGURATION/GCDWebServer" PRODUCT="$BUILD_DIR/$CONFIGURATION/GCDWebServer"
ARC_BUILD_DIR="/tmp/GCDWebServer-ARC"
ARC_PRODUCT="$ARC_BUILD_DIR/$CONFIGURATION/GCDWebServer"
PAYLOAD_ZIP="Tests/Payload.zip" PAYLOAD_ZIP="Tests/Payload.zip"
PAYLOAD_DIR="/tmp/GCDWebServer" PAYLOAD_DIR="/tmp/GCDWebServer-Payload"
function runTests { function runTests {
rm -rf "$PAYLOAD_DIR" rm -rf "$PAYLOAD_DIR"
@@ -32,55 +30,31 @@ function runTests {
logLevel=2 $1 -mode "$2" -root "$PAYLOAD_DIR/Payload" -tests "$3" logLevel=2 $1 -mode "$2" -root "$PAYLOAD_DIR/Payload" -tests "$3"
} }
# Build for iOS in manual memory management mode and for oldest deployment target (TODO: run tests on iOS) # Build for iOS for oldest deployment target (TODO: run tests on iOS)
rm -rf "$MRC_BUILD_DIR" rm -rf "$BUILD_DIR"
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$MRC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=NO" "IPHONEOS_DEPLOYMENT_TARGET=5.1.1" > /dev/null xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$BUILD_DIR" "IPHONEOS_DEPLOYMENT_TARGET=5.1.1" > /dev/null
# Build for iOS in manual memory management mode and for default deployment target (TODO: run tests on iOS) # Build for iOS for default deployment target (TODO: run tests on iOS)
rm -rf "$MRC_BUILD_DIR" rm -rf "$BUILD_DIR"
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$MRC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=NO" > /dev/null xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$BUILD_DIR" > /dev/null
# Build for iOS in ARC mode and for oldest deployment target (TODO: run tests on iOS) # Build for OS X for oldest deployment target
rm -rf "$ARC_BUILD_DIR" rm -rf "$BUILD_DIR"
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" "IPHONEOS_DEPLOYMENT_TARGET=5.1.1" > /dev/null xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$BUILD_DIR" "MACOSX_DEPLOYMENT_TARGET=10.7" > /dev/null
# Build for iOS in ARC mode and for default deployment target (TODO: run tests on iOS) # Build for OS X for default deployment target
rm -rf "$ARC_BUILD_DIR" rm -rf "$BUILD_DIR"
xcodebuild -sdk "$IOS_SDK" -target "$IOS_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" > /dev/null xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$BUILD_DIR" > /dev/null
# Build for OS X in manual memory management mode and for oldest deployment target
rm -rf "$MRC_BUILD_DIR"
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$MRC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=NO" "MACOSX_DEPLOYMENT_TARGET=10.7" > /dev/null
# Build for OS X in manual memory management mode and for default deployment target
rm -rf "$MRC_BUILD_DIR"
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$MRC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=NO" > /dev/null
# Build for OS X in ARC mode and for oldest deployment target
rm -rf "$ARC_BUILD_DIR"
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" "MACOSX_DEPLOYMENT_TARGET=10.7" > /dev/null
# Build for OS X in ARC mode and for default deployment target
rm -rf "$ARC_BUILD_DIR"
xcodebuild -sdk "$OSX_SDK" -target "$OSX_TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" > /dev/null
# Run tests # Run tests
runTests $MRC_PRODUCT "htmlForm" "Tests/HTMLForm" runTests $PRODUCT "htmlForm" "Tests/HTMLForm"
runTests $ARC_PRODUCT "htmlForm" "Tests/HTMLForm" runTests $PRODUCT "htmlFileUpload" "Tests/HTMLFileUpload"
runTests $MRC_PRODUCT "htmlFileUpload" "Tests/HTMLFileUpload" runTests $PRODUCT "webServer" "Tests/WebServer"
runTests $ARC_PRODUCT "htmlFileUpload" "Tests/HTMLFileUpload" runTests $PRODUCT "webDAV" "Tests/WebDAV-Transmit"
runTests $MRC_PRODUCT "webServer" "Tests/WebServer" runTests $PRODUCT "webDAV" "Tests/WebDAV-Cyberduck"
runTests $ARC_PRODUCT "webServer" "Tests/WebServer" runTests $PRODUCT "webDAV" "Tests/WebDAV-Finder"
runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Transmit" runTests $PRODUCT "webUploader" "Tests/WebUploader"
runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Transmit" runTests $PRODUCT "webServer" "Tests/WebServer-Sample-Movie" "Tests/Sample-Movie.mp4"
runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Cyberduck"
runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Cyberduck"
runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Finder"
runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Finder"
runTests $MRC_PRODUCT "webUploader" "Tests/WebUploader"
runTests $ARC_PRODUCT "webUploader" "Tests/WebUploader"
runTests $MRC_PRODUCT "webServer" "Tests/WebServer-Sample-Movie" "Tests/Sample-Movie.mp4"
runTests $ARC_PRODUCT "webServer" "Tests/WebServer-Sample-Movie" "Tests/Sample-Movie.mp4"
# Done # Done
echo "\nAll tests completed successfully!" echo "\nAll tests completed successfully!"

View File

@@ -36,16 +36,6 @@
@implementation AppDelegate @implementation AppDelegate
#if !__has_feature(objc_arc)
- (void)dealloc {
[_window release];
[super dealloc];
}
#endif
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
CGRect bounds = ([UIScreen instancesRespondToSelector:@selector(nativeBounds)] ? [[UIScreen mainScreen] nativeBounds] : [[UIScreen mainScreen] bounds]); CGRect bounds = ([UIScreen instancesRespondToSelector:@selector(nativeBounds)] ? [[UIScreen mainScreen] nativeBounds] : [[UIScreen mainScreen] bounds]);
_window = [[UIWindow alloc] initWithFrame:bounds]; _window = [[UIWindow alloc] initWithFrame:bounds];