diff --git a/CGDWebServer/GCDWebServerConnection.m b/CGDWebServer/GCDWebServerConnection.m index 8fb85b4..f140271 100644 --- a/CGDWebServer/GCDWebServerConnection.m +++ b/CGDWebServer/GCDWebServerConnection.m @@ -30,7 +30,6 @@ #import "GCDWebServerPrivate.h" #define kHeadersReadBuffer 1024 -#define kBodyWriteBufferSize (32 * 1024) typedef void (^ReadBufferCompletionBlock)(dispatch_data_t buffer); typedef void (^ReadDataCompletionBlock)(NSData* data); @@ -234,27 +233,25 @@ static dispatch_queue_t _formatterQueue = NULL; - (void)_writeBodyWithCompletionBlock:(WriteBodyCompletionBlock)block { DCHECK([_response hasBody]); - void* buffer = malloc(kBodyWriteBufferSize); - NSInteger result = [_response read:buffer maxLength:kBodyWriteBufferSize]; - if (result > 0) { - dispatch_data_t wrapper = dispatch_data_create(buffer, result, NULL, DISPATCH_DATA_DESTRUCTOR_FREE); - [self _writeBuffer:wrapper withCompletionBlock:^(BOOL success) { - - if (success) { - [self _writeBodyWithCompletionBlock:block]; - } else { - block(NO); - } - - }]; - ARC_DISPATCH_RELEASE(wrapper); - } else if (result < 0) { - LOG_ERROR(@"Failed reading response body on socket %i (error %i)", _socket, (int)result); - block(NO); - free(buffer); + NSError* error = nil; + NSData* data = [_response performReadData:&error]; + if (data) { + if (data.length) { + [self _writeData:data withCompletionBlock:^(BOOL success) { + + if (success) { + [self _writeBodyWithCompletionBlock:block]; + } else { + block(NO); + } + + }]; + } else { + block(YES); + } } else { - block(YES); - free(buffer); + LOG_ERROR(@"Failed reading response body for socket %i: %@", _socket, error); + block(NO); } } @@ -318,8 +315,13 @@ static dispatch_queue_t _formatterQueue = NULL; DCHECK(_responseMessage == NULL); GCDWebServerResponse* response = [self processRequest:_request withBlock:_handler.processBlock]; - if (![response hasBody] || [response open]) { - _response = ARC_RETAIN(response); + if (response) { + NSError* error = nil; + if ([response hasBody] && ![response performOpen:&error]) { + LOG_WARNING(@"Failed opening response body for socket %i: %@", _socket, error); + } else { + _response = ARC_RETAIN(response); + } } if (_response) { @@ -344,12 +346,13 @@ static dispatch_queue_t _formatterQueue = NULL; if ([_response hasBody]) { [self _writeBodyWithCompletionBlock:^(BOOL successInner) { - [_response close]; // Can't do anything with result anyway + [_response performClose]; + LOG_VERBOSE(@"%@ | %@ \"%@ %@\" %i %lu", self.localAddressString, self.remoteAddressString, _request.method, _request.path, (int)_response.statusCode, (unsigned long)_bytesWritten); }]; } } else if ([_response hasBody]) { - [_response close]; // Can't do anything with result anyway + [_response performClose]; } }]; @@ -537,7 +540,6 @@ static NSString* _StringFromAddressData(NSData* data) { GCDWebServerResponse* response = nil; @try { response = block(request); - LOG_VERBOSE(@"%@ | %@ \"%@ %@\" %i %lu", self.localAddressString, self.remoteAddressString, _request.method, _request.path, (int)response.statusCode, (unsigned long)(response.contentLength != NSNotFound ? response.contentLength : 0)); } @catch (NSException* exception) { LOG_EXCEPTION(exception); diff --git a/CGDWebServer/GCDWebServerPrivate.h b/CGDWebServer/GCDWebServerPrivate.h index dad7adc..ec8d823 100644 --- a/CGDWebServer/GCDWebServerPrivate.h +++ b/CGDWebServer/GCDWebServerPrivate.h @@ -104,3 +104,10 @@ extern void GCDLogMessage(long level, NSString* format, ...) NS_FORMAT_FUNCTION( @property(nonatomic, readonly) GCDWebServerProcessBlock processBlock; - (id)initWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock; @end + +@interface GCDWebServerResponse () +@property(nonatomic, readonly) NSDictionary* additionalHeaders; +- (BOOL)performOpen:(NSError**)error; +- (NSData*)performReadData:(NSError**)error; +- (void)performClose; +@end diff --git a/CGDWebServer/GCDWebServerResponse.h b/CGDWebServer/GCDWebServerResponse.h index 432619d..0d89e43 100644 --- a/CGDWebServer/GCDWebServerResponse.h +++ b/CGDWebServer/GCDWebServerResponse.h @@ -27,26 +27,27 @@ #import -typedef NSData* (^GCDWebServerChunkBlock)(); +typedef NSData* (^GCDWebServerStreamBlock)(NSError** error); -@interface GCDWebServerResponse : NSObject +@protocol GCDWebServerBodyReader +- (BOOL)open:(NSError**)error; +- (NSData*)readData:(NSError**)error; // Return nil on error or empty NSData if at end +- (void)close; +@end + +@interface GCDWebServerResponse : NSObject @property(nonatomic, copy) NSString* contentType; // Default is nil i.e. no body @property(nonatomic) NSUInteger contentLength; // Default is NSNotFound i.e. undefined @property(nonatomic) NSInteger statusCode; // Default is 200 @property(nonatomic) NSUInteger cacheControlMaxAge; // Default is 0 seconds i.e. "no-cache" -@property(nonatomic, readonly) NSDictionary* additionalHeaders; +@property(nonatomic) BOOL gzipContentEncoding; +@property(nonatomic) BOOL chunkedTransferEncoding; + (GCDWebServerResponse*) response; - (id)init; - (void)setValue:(NSString*)value forAdditionalHeader:(NSString*)header; - (BOOL)hasBody; // Convenience method @end -@interface GCDWebServerResponse (Subclassing) -- (BOOL)open; // Implementation required -- (NSInteger)read:(void*)buffer maxLength:(NSUInteger)length; // Implementation required -- (BOOL)close; // Implementation required -@end - @interface GCDWebServerResponse (Extensions) + (GCDWebServerResponse*)responseWithStatusCode:(NSInteger)statusCode; + (GCDWebServerResponse*)responseWithRedirect:(NSURL*)location permanent:(BOOL)permanent; @@ -83,7 +84,7 @@ typedef NSData* (^GCDWebServerChunkBlock)(); - (id)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment; @end -@interface GCDWebServerChunkedResponse : GCDWebServerResponse // Use chunked transfer encoding -+ (GCDWebServerChunkedResponse*)responseWithContentType:(NSString*)type chunkBlock:(GCDWebServerChunkBlock)block; -- (id)initWithContentType:(NSString*)type chunkBlock:(GCDWebServerChunkBlock)block; // Return nil when done +@interface GCDWebServerStreamResponse : GCDWebServerResponse // Forces chunked transfer encoding ++ (GCDWebServerStreamResponse*)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block; +- (id)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block; // Block must return empty NSData when done or nil on error @end diff --git a/CGDWebServer/GCDWebServerResponse.m b/CGDWebServer/GCDWebServerResponse.m index bb777b1..a78e17a 100644 --- a/CGDWebServer/GCDWebServerResponse.m +++ b/CGDWebServer/GCDWebServerResponse.m @@ -26,9 +26,188 @@ */ #import +#import #import "GCDWebServerPrivate.h" +#define kZlibErrorDomain @"ZlibErrorDomain" +#define kGZipInitialBufferSize (256 * 1024) +#define kFileReadBufferSize (32 * 1024) + +@interface GCDWebServerBodyEncoder : NSObject +- (id)initWithResponse:(GCDWebServerResponse*)response reader:(id)reader; +@end + +@interface GCDWebServerChunkEncoder : GCDWebServerBodyEncoder +@end + +@interface GCDWebServerGZipEncoder : GCDWebServerBodyEncoder +@end + +@interface GCDWebServerBodyEncoder () { +@private + GCDWebServerResponse* __unsafe_unretained _response; + id __unsafe_unretained _reader; +} +@end + +@implementation GCDWebServerBodyEncoder + +- (id)initWithResponse:(GCDWebServerResponse*)response reader:(id)reader { + if ((self = [super init])) { + _response = response; + _reader = reader; + } + return self; +} + +- (BOOL)open:(NSError**)error { + return [_reader open:error]; +} + +- (NSData*)readData:(NSError**)error { + return [_reader readData:error]; +} + +- (void)close { + [_reader close]; +} + +@end + +@interface GCDWebServerChunkEncoder () { +@private + BOOL _finished; +} +@end + +@implementation GCDWebServerChunkEncoder + +- (id)initWithResponse:(GCDWebServerResponse*)response reader:(id)reader { + if ((self = [super initWithResponse:response reader:reader])) { + response.contentLength = NSNotFound; // Make sure "Content-Length" header is not set + [response setValue:@"chunked" forAdditionalHeader:@"Transfer-Encoding"]; + } + return self; +} + +- (NSData*)readData:(NSError**)error { + NSData* chunk; + if (_finished) { + chunk = [[NSData alloc] init]; + } else { + NSData* data = [super readData:error]; + if (data == nil) { + return nil; + } + if (data.length) { + const char* hexString = [[NSString stringWithFormat:@"%lx", (unsigned long)data.length] UTF8String]; + size_t hexLength = strlen(hexString); + chunk = [[NSMutableData alloc] initWithLength:(hexLength + 2 + data.length + 2)]; + if (chunk == nil) { + DNOT_REACHED(); + return nil; + } + char* ptr = (char*)[(NSMutableData*)chunk mutableBytes]; + bcopy(hexString, ptr, hexLength); + ptr += hexLength; + *ptr++ = '\r'; + *ptr++ = '\n'; + bcopy(data.bytes, ptr, data.length); + ptr += data.length; + *ptr++ = '\r'; + *ptr = '\n'; + } else { + chunk = [[NSData alloc] initWithBytes:"0\r\n\r\n" length:5]; + DCHECK(chunk); + _finished = YES; + } + } + return ARC_AUTORELEASE(chunk); +} + +@end + +@interface GCDWebServerGZipEncoder () { +@private + z_stream _stream; + BOOL _finished; +} +@end + +@implementation GCDWebServerGZipEncoder + +- (id)initWithResponse:(GCDWebServerResponse*)response reader:(id)reader { + if ((self = [super initWithResponse:response reader:reader])) { + response.contentLength = NSNotFound; // Make sure "Content-Length" header is not set + [response setValue:@"gzip" forAdditionalHeader:@"Content-Encoding"]; + } + return self; +} + +- (BOOL)open:(NSError**)error { + int result = deflateInit2(&_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); + if (result != Z_OK) { + *error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil]; + return NO; + } + if (![super open:error]) { + deflateEnd(&_stream); + return NO; + } + return YES; +} + +- (NSData*)readData:(NSError**)error { + NSMutableData* gzipData; + if (_finished) { + gzipData = [[NSMutableData alloc] init]; + } else { + gzipData = [[NSMutableData alloc] initWithLength:kGZipInitialBufferSize]; + if (gzipData == nil) { + DNOT_REACHED(); + return nil; + } + NSUInteger length = 0; + do { + NSData* data = [super readData:error]; + if (data == nil) { + return nil; + } + _stream.next_in = (Bytef*)data.bytes; + _stream.avail_in = (uInt)data.length; + while (1) { + NSUInteger maxLength = gzipData.length - length; + _stream.next_out = (Bytef*)((char*)gzipData.mutableBytes + length); + _stream.avail_out = (uInt)maxLength; + int result = deflate(&_stream, data.length ? Z_NO_FLUSH : Z_FINISH); + if (result == Z_STREAM_END) { + _finished = YES; + } else if (result != Z_OK) { + ARC_RELEASE(gzipData); + *error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil]; + return nil; + } + length += maxLength - _stream.avail_out; + if (_stream.avail_out > 0) { + break; + } + gzipData.length = 2 * gzipData.length; // zlib has used all the output buffer so resize it and try again in case more data is available + } + DCHECK(_stream.avail_in == 0); + } while (length == 0); // Make sure we don't return an empty NSData if not in finished state + gzipData.length = length; + } + return ARC_AUTORELEASE(gzipData); +} + +- (void)close { + deflateEnd(&_stream); + [super close]; +} + +@end + @interface GCDWebServerResponse () { @private NSString* _type; @@ -36,37 +215,19 @@ NSInteger _status; NSUInteger _maxAge; NSMutableDictionary* _headers; -} -@end - -@interface GCDWebServerDataResponse () { -@private - NSData* _data; - NSInteger _offset; -} -@end - -@interface GCDWebServerFileResponse () { -@private - NSString* _path; - NSUInteger _offset; - NSUInteger _size; - int _file; -} -@end - -@interface GCDWebServerChunkedResponse () { -@private - GCDWebServerChunkBlock _block; - NSData* _chunk; - NSUInteger _offset; - BOOL _terminated; + BOOL _gzipped; + BOOL _chunked; + + BOOL _opened; + NSMutableArray* _encoders; + id __unsafe_unretained _reader; } @end @implementation GCDWebServerResponse -@synthesize contentType=_type, contentLength=_length, statusCode=_status, cacheControlMaxAge=_maxAge, additionalHeaders=_headers; +@synthesize contentType=_type, contentLength=_length, statusCode=_status, cacheControlMaxAge=_maxAge, + gzipContentEncoding=_gzipped, chunkedTransferEncoding=_chunked, additionalHeaders=_headers; + (GCDWebServerResponse*)response { return ARC_AUTORELEASE([[[self class] alloc] init]); @@ -79,6 +240,7 @@ _status = 200; _maxAge = 0; _headers = [[NSMutableDictionary alloc] init]; + _encoders = [[NSMutableArray alloc] init]; } return self; } @@ -86,6 +248,7 @@ - (void)dealloc { ARC_RELEASE(_type); ARC_RELEASE(_headers); + ARC_RELEASE(_encoders); ARC_DEALLOC(super); } @@ -98,23 +261,47 @@ return _type ? YES : NO; } -@end - -@implementation GCDWebServerResponse (Subclassing) - -- (BOOL)open { - [self doesNotRecognizeSelector:_cmd]; - return NO; +- (BOOL)open:(NSError**)error { + return YES; } -- (NSInteger)read:(void*)buffer maxLength:(NSUInteger)length { - [self doesNotRecognizeSelector:_cmd]; - return -1; +- (NSData*)readData:(NSError**)error { + return nil; } -- (BOOL)close { - [self doesNotRecognizeSelector:_cmd]; - return NO; +- (void)close { + ; +} + +- (BOOL)performOpen:(NSError**)error { + if (_opened) { + DNOT_REACHED(); + return NO; + } + _opened = YES; + + _reader = self; + if (_gzipped) { + GCDWebServerGZipEncoder* encoder = [[GCDWebServerGZipEncoder alloc] initWithResponse:self reader:_reader]; + [_encoders addObject:encoder]; + ARC_RELEASE(encoder); + _reader = encoder; + } + if (_chunked) { + GCDWebServerChunkEncoder* encoder = [[GCDWebServerChunkEncoder alloc] initWithResponse:self reader:_reader]; + [_encoders addObject:encoder]; + ARC_RELEASE(encoder); + _reader = encoder; + } + return [_reader open:error]; +} + +- (NSData*)performReadData:(NSError**)error { + return [_reader readData:error]; +} + +- (void)performClose { + [_reader close]; } @end @@ -146,6 +333,13 @@ @end +@interface GCDWebServerDataResponse () { +@private + NSData* _data; + BOOL _done; +} +@end + @implementation GCDWebServerDataResponse + (GCDWebServerDataResponse*)responseWithData:(NSData*)data contentType:(NSString*)type { @@ -161,7 +355,6 @@ if ((self = [super init])) { _data = ARC_RETAIN(data); - _offset = -1; self.contentType = type; self.contentLength = data.length; @@ -170,33 +363,20 @@ } - (void)dealloc { - DCHECK(_offset < 0); ARC_RELEASE(_data); ARC_DEALLOC(super); } -- (BOOL)open { - DCHECK(_offset < 0); - _offset = 0; - return YES; -} - -- (NSInteger)read:(void*)buffer maxLength:(NSUInteger)length { - DCHECK(_offset >= 0); - NSInteger size = 0; - if (_offset < (NSInteger)_data.length) { - size = MIN(_data.length - _offset, length); - bcopy((char*)_data.bytes + _offset, buffer, size); - _offset += size; +- (NSData*)readData:(NSError**)error { + NSData* data; + if (_done) { + data = [NSData data]; + } else { + data = _data; + _done = YES; } - return size; -} - -- (BOOL)close { - DCHECK(_offset >= 0); - _offset = -1; - return YES; + return data; } @end @@ -268,6 +448,15 @@ @end +@interface GCDWebServerFileResponse () { +@private + NSString* _path; + NSUInteger _offset; + NSUInteger _size; + int _file; +} +@end + @implementation GCDWebServerFileResponse + (GCDWebServerFileResponse*)responseWithFile:(NSString*)path { @@ -356,13 +545,19 @@ ARC_DEALLOC(super); } -- (BOOL)open { +static inline NSError* _MakePosixError(int code) { + return [NSError errorWithDomain:NSPOSIXErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"%s", strerror(code)]}]; +} + +- (BOOL)open:(NSError**)error { DCHECK(_file <= 0); _file = open([_path fileSystemRepresentation], O_NOFOLLOW | O_RDONLY); if (_file <= 0) { + *error = _MakePosixError(errno); return NO; } if (lseek(_file, _offset, SEEK_SET) != (off_t)_offset) { + *error = _MakePosixError(errno); close(_file); _file = 0; return NO; @@ -370,91 +565,60 @@ return YES; } -- (NSInteger)read:(void*)buffer maxLength:(NSUInteger)length { +- (NSData*)readData:(NSError**)error { DCHECK(_file > 0); - ssize_t result = read(_file, buffer, MIN(length, _size)); + size_t length = MIN((NSUInteger)kFileReadBufferSize, _size); + NSMutableData* data = [[NSMutableData alloc] initWithLength:length]; + ssize_t result = read(_file, data.mutableBytes, length); + if (result < 0) { + *error = _MakePosixError(errno); + return nil; + } if (result > 0) { + [data setLength:result]; _size -= result; } - return result; + return ARC_AUTORELEASE(data); } -- (BOOL)close { +- (void)close { DCHECK(_file > 0); - int result = close(_file); + close(_file); _file = 0; - return (result == 0 ? YES : NO); } @end -@implementation GCDWebServerChunkedResponse +@interface GCDWebServerStreamResponse () { +@private + GCDWebServerStreamBlock _block; +} +@end -+ (GCDWebServerChunkedResponse*)responseWithContentType:(NSString*)type chunkBlock:(GCDWebServerChunkBlock)block { - return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type chunkBlock:block]); +@implementation GCDWebServerStreamResponse + ++ (GCDWebServerStreamResponse*)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block { + return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type streamBlock:block]); } -- (id)initWithContentType:(NSString*)type chunkBlock:(GCDWebServerChunkBlock)block { +- (id)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block { if ((self = [super init])) { _block = [block copy]; self.contentType = type; - [self setValue:@"chunked" forAdditionalHeader:@"Transfer-Encoding"]; + self.chunkedTransferEncoding = YES; } return self; } -- (BOOL)open { - DCHECK(_chunk == nil); - return YES; -} - -- (NSInteger)read:(void*)buffer maxLength:(NSUInteger)length { - if (_offset >= _chunk.length) { - ARC_RELEASE(_chunk); - _chunk = nil; - } - if (_chunk == nil) { - if (_terminated) { - return 0; - } - NSData* data = _block(); - if (data.length > 0) { - const char* hexString = [[NSString stringWithFormat:@"%lx", (unsigned long)data.length] UTF8String]; - size_t hexLength = strlen(hexString); - _chunk = [[NSMutableData alloc] initWithLength:(hexLength + 2 + data.length + 2)]; - char* ptr = (char*)_chunk.bytes; - bcopy(hexString, ptr, hexLength); - ptr += hexLength; - *ptr++ = '\r'; - *ptr++ = '\n'; - bcopy(data.bytes, ptr, data.length); - ptr += data.length; - *ptr++ = '\r'; - *ptr = '\n'; - } else { - _chunk = [[NSData alloc] initWithBytes:"0\r\n\r\n" length:5]; - _terminated = YES; - } - _offset = 0; - } - NSInteger size = MIN(_chunk.length - _offset, length); - bcopy((char*)_chunk.bytes + _offset, buffer, size); - _offset += size; - return size; -} - -- (BOOL)close { - ARC_RELEASE(_chunk); - _chunk = nil; - return YES; -} - - (void)dealloc { - DCHECK(_chunk == nil); - ARC_RELEASE(_chunk); + ARC_RELEASE(_block); ARC_DEALLOC(super); } +- (NSData*)readData:(NSError**)error { + return _block(error); +} + @end diff --git a/GCDWebServer.xcodeproj/project.pbxproj b/GCDWebServer.xcodeproj/project.pbxproj index 739df1e..b076fcc 100644 --- a/GCDWebServer.xcodeproj/project.pbxproj +++ b/GCDWebServer.xcodeproj/project.pbxproj @@ -38,6 +38,8 @@ E22112991690B7AA0048D2B2 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E22112981690B7AA0048D2B2 /* CFNetwork.framework */; }; E221129B1690B7B10048D2B2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E221129A1690B7B10048D2B2 /* UIKit.framework */; }; E221129D1690B7BA0048D2B2 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E221129C1690B7BA0048D2B2 /* MobileCoreServices.framework */; }; + E2B0D4A718F13495009A7927 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E2B0D4A618F13495009A7927 /* libz.dylib */; }; + E2B0D4A918F134A8009A7927 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E2B0D4A818F134A8009A7927 /* libz.dylib */; }; E2BE850A18E77ECA0061360B /* GCDWebUploader.bundle in Resources */ = {isa = PBXBuildFile; fileRef = E2BE850718E77ECA0061360B /* GCDWebUploader.bundle */; }; E2BE850B18E77ECA0061360B /* GCDWebUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = E2BE850918E77ECA0061360B /* GCDWebUploader.m */; }; E2BE850C18E785940061360B /* GCDWebUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = E2BE850918E77ECA0061360B /* GCDWebUploader.m */; }; @@ -97,6 +99,8 @@ E22112981690B7AA0048D2B2 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; }; E221129A1690B7B10048D2B2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; E221129C1690B7BA0048D2B2 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/MobileCoreServices.framework; sourceTree = DEVELOPER_DIR; }; + E2B0D4A618F13495009A7927 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + E2B0D4A818F134A8009A7927 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; }; E2BE850718E77ECA0061360B /* GCDWebUploader.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = GCDWebUploader.bundle; sourceTree = ""; }; E2BE850818E77ECA0061360B /* GCDWebUploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebUploader.h; sourceTree = ""; }; E2BE850918E77ECA0061360B /* GCDWebUploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebUploader.m; sourceTree = ""; }; @@ -111,6 +115,7 @@ E2BE851118E79DAF0061360B /* SystemConfiguration.framework in Frameworks */, E208D1B3167BB17E00500836 /* CoreServices.framework in Frameworks */, E208D149167B76B700500836 /* CFNetwork.framework in Frameworks */, + E2B0D4A718F13495009A7927 /* libz.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -121,6 +126,7 @@ E221129D1690B7BA0048D2B2 /* MobileCoreServices.framework in Frameworks */, E221129B1690B7B10048D2B2 /* UIKit.framework in Frameworks */, E22112991690B7AA0048D2B2 /* CFNetwork.framework in Frameworks */, + E2B0D4A918F134A8009A7927 /* libz.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -191,6 +197,7 @@ E221129C1690B7BA0048D2B2 /* MobileCoreServices.framework */, E221129A1690B7B10048D2B2 /* UIKit.framework */, E22112981690B7AA0048D2B2 /* CFNetwork.framework */, + E2B0D4A818F134A8009A7927 /* libz.dylib */, ); name = "iOS Frameworks and Libraries"; sourceTree = ""; @@ -201,6 +208,7 @@ E2BE851018E79DAF0061360B /* SystemConfiguration.framework */, E208D1B2167BB17E00500836 /* CoreServices.framework */, E208D148167B76B700500836 /* CFNetwork.framework */, + E2B0D4A618F13495009A7927 /* libz.dylib */, ); name = "Mac Frameworks and Libraries"; sourceTree = ""; @@ -366,9 +374,10 @@ ONLY_ACTIVE_ARCH = YES; WARNING_CFLAGS = ( "-Wall", - "-Wshadow", "-Weverything", + "-Wshadow", "-Wshorten-64-to-32", + "-Wno-explicit-ownership-type", "-Wno-gnu-statement-expression", "-Wno-direct-ivar-access", "-Wno-implicit-retain-self",