diff --git a/GCDWebServer.xcodeproj/project.pbxproj b/GCDWebServer.xcodeproj/project.pbxproj index 08531ed..e957831 100644 --- a/GCDWebServer.xcodeproj/project.pbxproj +++ b/GCDWebServer.xcodeproj/project.pbxproj @@ -1228,7 +1228,6 @@ "-Wno-explicit-ownership-type", "-Wno-gnu-statement-expression", "-Wno-direct-ivar-access", - "-Wno-implicit-retain-self", "-Wno-assign-enum", "-Wno-format-nonliteral", "-Wno-cast-align", diff --git a/GCDWebServer/Core/GCDWebServer.m b/GCDWebServer/Core/GCDWebServer.m index 8c24542..8185a0b 100644 --- a/GCDWebServer/Core/GCDWebServer.m +++ b/GCDWebServer/Core/GCDWebServer.m @@ -236,20 +236,20 @@ static void _ExecuteMainThreadRunLoopSources() { - (void)willStartConnection:(GCDWebServerConnection*)connection { dispatch_sync(_syncQueue, ^{ - GWS_DCHECK(_activeConnections >= 0); - if (_activeConnections == 0) { + GWS_DCHECK(self->_activeConnections >= 0); + if (self->_activeConnections == 0) { dispatch_async(dispatch_get_main_queue(), ^{ - if (_disconnectTimer) { - CFRunLoopTimerInvalidate(_disconnectTimer); - CFRelease(_disconnectTimer); - _disconnectTimer = NULL; + if (self->_disconnectTimer) { + CFRunLoopTimerInvalidate(self->_disconnectTimer); + CFRelease(self->_disconnectTimer); + self->_disconnectTimer = NULL; } - if (_connected == NO) { + if (self->_connected == NO) { [self _didConnect]; } }); } - _activeConnections += 1; + self->_activeConnections += 1; }); } @@ -288,22 +288,22 @@ static void _ExecuteMainThreadRunLoopSources() { - (void)didEndConnection:(GCDWebServerConnection*)connection { dispatch_sync(_syncQueue, ^{ - GWS_DCHECK(_activeConnections > 0); - _activeConnections -= 1; - if (_activeConnections == 0) { + GWS_DCHECK(self->_activeConnections > 0); + self->_activeConnections -= 1; + if (self->_activeConnections == 0) { dispatch_async(dispatch_get_main_queue(), ^{ - if ((_disconnectDelay > 0.0) && (_source4 != NULL)) { - if (_disconnectTimer) { - CFRunLoopTimerInvalidate(_disconnectTimer); - CFRelease(_disconnectTimer); + if ((self->_disconnectDelay > 0.0) && (self->_source4 != NULL)) { + if (self->_disconnectTimer) { + CFRunLoopTimerInvalidate(self->_disconnectTimer); + CFRelease(self->_disconnectTimer); } - _disconnectTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + _disconnectDelay, 0.0, 0, 0, ^(CFRunLoopTimerRef timer) { + self->_disconnectTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + self->_disconnectDelay, 0.0, 0, 0, ^(CFRunLoopTimerRef timer) { GWS_DCHECK([NSThread isMainThread]); [self _didDisconnect]; - CFRelease(_disconnectTimer); - _disconnectTimer = NULL; + CFRelease(self->_disconnectTimer); + self->_disconnectTimer = NULL; }); - CFRunLoopAddTimer(CFRunLoopGetMain(), _disconnectTimer, kCFRunLoopCommonModes); + CFRunLoopAddTimer(CFRunLoopGetMain(), self->_disconnectTimer, kCFRunLoopCommonModes); } else { [self _didDisconnect]; } @@ -473,7 +473,7 @@ static inline NSString* _EncodeBase64(NSString* string) { GWS_LOG_DEBUG(@"Did close %s listening socket %i", isIPv6 ? "IPv6" : "IPv4", listeningSocket); } } - dispatch_group_leave(_sourceGroup); + dispatch_group_leave(self->_sourceGroup); }); dispatch_source_set_event_handler(source, ^{ @autoreleasepool { @@ -496,7 +496,7 @@ static inline NSString* _EncodeBase64(NSString* string) { int noSigPipe = 1; setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &noSigPipe, sizeof(noSigPipe)); // Make sure this socket cannot generate SIG_PIPE - GCDWebServerConnection* connection = [(GCDWebServerConnection*)[_connectionClass alloc] initWithServer:self localAddress:localAddress remoteAddress:remoteAddress socket:socket]; // Connection will automatically retain itself while opened + GCDWebServerConnection* connection = [(GCDWebServerConnection*)[self->_connectionClass alloc] initWithServer:self localAddress:localAddress remoteAddress:remoteAddress socket:socket]; // Connection will automatically retain itself while opened [connection self]; // Prevent compiler from complaining about unused variable / useless statement } else { GWS_LOG_ERROR(@"Failed accepting %s socket: %s (%i)", isIPv6 ? "IPv6" : "IPv4", strerror(errno), errno); @@ -552,14 +552,14 @@ static inline NSString* _EncodeBase64(NSString* string) { _authenticationBasicAccounts = [[NSMutableDictionary alloc] init]; NSDictionary* accounts = _GetOption(_options, GCDWebServerOption_AuthenticationAccounts, @{}); [accounts enumerateKeysAndObjectsUsingBlock:^(NSString* username, NSString* password, BOOL* stop) { - [_authenticationBasicAccounts setObject:_EncodeBase64([NSString stringWithFormat:@"%@:%@", username, password]) forKey:username]; + [self->_authenticationBasicAccounts setObject:_EncodeBase64([NSString stringWithFormat:@"%@:%@", username, password]) forKey:username]; }]; } else if ([authenticationMethod isEqualToString:GCDWebServerAuthenticationMethod_DigestAccess]) { _authenticationRealm = [(NSString*)_GetOption(_options, GCDWebServerOption_AuthenticationRealm, _serverName) copy]; _authenticationDigestAccounts = [[NSMutableDictionary alloc] init]; NSDictionary* accounts = _GetOption(_options, GCDWebServerOption_AuthenticationAccounts, @{}); [accounts enumerateKeysAndObjectsUsingBlock:^(NSString* username, NSString* password, BOOL* stop) { - [_authenticationDigestAccounts setObject:GCDWebServerComputeMD5Digest(@"%@:%@:%@", username, _authenticationRealm, password) forKey:username]; + [self->_authenticationDigestAccounts setObject:GCDWebServerComputeMD5Digest(@"%@:%@:%@", username, self->_authenticationRealm, password) forKey:username]; }]; } _connectionClass = _GetOption(_options, GCDWebServerOption_ConnectionClass, [GCDWebServerConnection class]); @@ -624,7 +624,7 @@ static inline NSString* _EncodeBase64(NSString* string) { GWS_LOG_INFO(@"%@ started on port %i and reachable at %@", [self class], (int)_port, self.serverURL); if ([_delegate respondsToSelector:@selector(webServerDidStart:)]) { dispatch_async(dispatch_get_main_queue(), ^{ - [_delegate webServerDidStart:self]; + [self->_delegate webServerDidStart:self]; }); } @@ -685,10 +685,10 @@ static inline NSString* _EncodeBase64(NSString* string) { _authenticationDigestAccounts = nil; dispatch_async(dispatch_get_main_queue(), ^{ - if (_disconnectTimer) { - CFRunLoopTimerInvalidate(_disconnectTimer); - CFRelease(_disconnectTimer); - _disconnectTimer = NULL; + if (self->_disconnectTimer) { + CFRunLoopTimerInvalidate(self->_disconnectTimer); + CFRelease(self->_disconnectTimer); + self->_disconnectTimer = NULL; [self _didDisconnect]; } }); @@ -696,7 +696,7 @@ static inline NSString* _EncodeBase64(NSString* string) { GWS_LOG_INFO(@"%@ stopped", [self class]); if ([_delegate respondsToSelector:@selector(webServerDidStop:)]) { dispatch_async(dispatch_get_main_queue(), ^{ - [_delegate webServerDidStop:self]; + [self->_delegate webServerDidStop:self]; }); } } diff --git a/GCDWebServer/Core/GCDWebServerConnection.m b/GCDWebServer/Core/GCDWebServerConnection.m index ea5df23..ed34789 100644 --- a/GCDWebServer/Core/GCDWebServerConnection.m +++ b/GCDWebServer/Core/GCDWebServerConnection.m @@ -193,17 +193,17 @@ NS_ASSUME_NONNULL_END CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Transfer-Encoding"), CFSTR("chunked")); } [_response.additionalHeaders enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL* stop) { - CFHTTPMessageSetHeaderFieldValue(_responseMessage, (__bridge CFStringRef)key, (__bridge CFStringRef)obj); + CFHTTPMessageSetHeaderFieldValue(self->_responseMessage, (__bridge CFStringRef)key, (__bridge CFStringRef)obj); }]; [self writeHeadersWithCompletionBlock:^(BOOL success) { if (success) { if (hasBody) { [self writeBodyWithCompletionBlock:^(BOOL successInner) { - [_response performClose]; // TODO: There's nothing we can do on failure as headers have already been sent + [self->_response performClose]; // TODO: There's nothing we can do on failure as headers have already been sent }]; } } else if (hasBody) { - [_response performClose]; + [self->_response performClose]; } }]; } else { @@ -235,11 +235,11 @@ NS_ASSUME_NONNULL_END [self readBodyWithRemainingLength:length completionBlock:^(BOOL success) { NSError* localError = nil; - if ([_request performClose:&localError]) { + if ([self->_request performClose:&localError]) { [self _startProcessingRequest]; } else { - GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error); - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; + GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", self->_socket, error); + [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; } }]; } else { @@ -264,11 +264,11 @@ NS_ASSUME_NONNULL_END [self readNextBodyChunk:chunkData completionBlock:^(BOOL success) { NSError* localError = nil; - if ([_request performClose:&localError]) { + if ([self->_request performClose:&localError]) { [self _startProcessingRequest]; } else { - GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error); - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; + GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", self->_socket, error); + [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; } }]; } @@ -279,13 +279,13 @@ NS_ASSUME_NONNULL_END [self readHeaders:headersData withCompletionBlock:^(NSData* extraData) { if (extraData) { - NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(_requestMessage)); // Method verbs are case-sensitive and uppercase - if (_server.shouldAutomaticallyMapHEADToGET && [requestMethod isEqualToString:@"HEAD"]) { + NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(self->_requestMessage)); // Method verbs are case-sensitive and uppercase + if (self->_server.shouldAutomaticallyMapHEADToGET && [requestMethod isEqualToString:@"HEAD"]) { requestMethod = @"GET"; - _virtualHEAD = YES; + self->_virtualHEAD = YES; } - NSDictionary* requestHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones - NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(_requestMessage)); + NSDictionary* requestHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(self->_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones + NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(self->_requestMessage)); if (requestURL) { requestURL = [self rewriteRequestURL:requestURL withMethod:requestMethod headers:requestHeaders]; GWS_DCHECK(requestURL); @@ -298,53 +298,53 @@ NS_ASSUME_NONNULL_END NSString* queryString = requestURL ? CFBridgingRelease(CFURLCopyQueryString((CFURLRef)requestURL, NULL)) : nil; // Don't use -[NSURL query] to make sure query is not unescaped; NSDictionary* requestQuery = queryString ? GCDWebServerParseURLEncodedForm(queryString) : @{}; if (requestMethod && requestURL && requestHeaders && requestPath && requestQuery) { - for (_handler in _server.handlers) { - _request = _handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery); - if (_request) { + for (self->_handler in self->_server.handlers) { + self->_request = self->_handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery); + if (self->_request) { break; } } - if (_request) { - _request.localAddressData = self.localAddressData; - _request.remoteAddressData = self.remoteAddressData; - if ([_request hasBody]) { - [_request prepareForWriting]; - if (_request.usesChunkedTransferEncoding || (extraData.length <= _request.contentLength)) { + if (self->_request) { + self->_request.localAddressData = self.localAddressData; + self->_request.remoteAddressData = self.remoteAddressData; + if ([self->_request hasBody]) { + [self->_request prepareForWriting]; + if (self->_request.usesChunkedTransferEncoding || (extraData.length <= self->_request.contentLength)) { NSString* expectHeader = [requestHeaders objectForKey:@"Expect"]; if (expectHeader) { if ([expectHeader caseInsensitiveCompare:@"100-continue"] == NSOrderedSame) { // TODO: Actually validate request before continuing [self writeData:_continueData withCompletionBlock:^(BOOL success) { if (success) { - if (_request.usesChunkedTransferEncoding) { + if (self->_request.usesChunkedTransferEncoding) { [self _readChunkedBodyWithInitialData:extraData]; } else { - [self _readBodyWithLength:_request.contentLength initialData:extraData]; + [self _readBodyWithLength:self->_request.contentLength initialData:extraData]; } } }]; } else { - GWS_LOG_ERROR(@"Unsupported 'Expect' / 'Content-Length' header combination on socket %i", _socket); - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_ExpectationFailed]; + GWS_LOG_ERROR(@"Unsupported 'Expect' / 'Content-Length' header combination on socket %i", self->_socket); + [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_ExpectationFailed]; } } else { - if (_request.usesChunkedTransferEncoding) { + if (self->_request.usesChunkedTransferEncoding) { [self _readChunkedBodyWithInitialData:extraData]; } else { - [self _readBodyWithLength:_request.contentLength initialData:extraData]; + [self _readBodyWithLength:self->_request.contentLength initialData:extraData]; } } } else { - GWS_LOG_ERROR(@"Unexpected 'Content-Length' header value on socket %i", _socket); - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_BadRequest]; + GWS_LOG_ERROR(@"Unexpected 'Content-Length' header value on socket %i", self->_socket); + [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_BadRequest]; } } else { [self _startProcessingRequest]; } } else { - _request = [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:requestPath query:requestQuery]; - GWS_DCHECK(_request); - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_NotImplemented]; + self->_request = [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:requestPath query:requestQuery]; + GWS_DCHECK(self->_request); + [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_NotImplemented]; } } else { [self abortRequest:nil withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; @@ -426,15 +426,15 @@ NS_ASSUME_NONNULL_END [self didReadBytes:((char*)data.bytes + originalLength) length:(data.length - originalLength)]; block(YES); } else { - if (_totalBytesRead > 0) { - GWS_LOG_ERROR(@"No more data available on socket %i", _socket); + if (self->_totalBytesRead > 0) { + GWS_LOG_ERROR(@"No more data available on socket %i", self->_socket); } else { - GWS_LOG_WARNING(@"No data received from socket %i", _socket); + GWS_LOG_WARNING(@"No data received from socket %i", self->_socket); } block(NO); } } else { - GWS_LOG_ERROR(@"Error while reading from socket %i: %s (%i)", _socket, strerror(error), error); + GWS_LOG_ERROR(@"Error while reading from socket %i: %s (%i)", self->_socket, strerror(error), error); block(NO); } } @@ -452,15 +452,15 @@ NS_ASSUME_NONNULL_END [self readHeaders:headersData withCompletionBlock:block]; } else { NSUInteger length = range.location + range.length; - if (CFHTTPMessageAppendBytes(_requestMessage, headersData.bytes, length)) { - if (CFHTTPMessageIsHeaderComplete(_requestMessage)) { + if (CFHTTPMessageAppendBytes(self->_requestMessage, headersData.bytes, length)) { + if (CFHTTPMessageIsHeaderComplete(self->_requestMessage)) { block([headersData subdataWithRange:NSMakeRange(length, headersData.length - length)]); } else { - GWS_LOG_ERROR(@"Failed parsing request headers from socket %i", _socket); + GWS_LOG_ERROR(@"Failed parsing request headers from socket %i", self->_socket); block(nil); } } else { - GWS_LOG_ERROR(@"Failed appending request headers data from socket %i", _socket); + GWS_LOG_ERROR(@"Failed appending request headers data from socket %i", self->_socket); block(nil); } } @@ -479,7 +479,7 @@ NS_ASSUME_NONNULL_END if (success) { if (bodyData.length <= length) { NSError* error = nil; - if ([_request performWriteData:bodyData error:&error]) { + if ([self->_request performWriteData:bodyData error:&error]) { NSUInteger remainingLength = length - bodyData.length; if (remainingLength) { [self readBodyWithRemainingLength:remainingLength completionBlock:block]; @@ -487,11 +487,11 @@ NS_ASSUME_NONNULL_END block(YES); } } else { - GWS_LOG_ERROR(@"Failed writing request body on socket %i: %@", _socket, error); + GWS_LOG_ERROR(@"Failed writing request body on socket %i: %@", self->_socket, error); block(NO); } } else { - GWS_LOG_ERROR(@"Unexpected extra content reading request body on socket %i", _socket); + GWS_LOG_ERROR(@"Unexpected extra content reading request body on socket %i", self->_socket); block(NO); GWS_DNOT_REACHED(); } @@ -580,7 +580,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) { [self didWriteBytes:data.bytes length:data.length]; block(YES); } else { - GWS_LOG_ERROR(@"Error while writing to socket %i: %s (%i)", _socket, strerror(error), error); + GWS_LOG_ERROR(@"Error while writing to socket %i: %s (%i)", self->_socket, strerror(error), error); block(NO); } } @@ -602,12 +602,12 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) { [_response performReadDataWithCompletion:^(NSData* data, NSError* error) { if (data) { if (data.length) { - if (_response.usesChunkedTransferEncoding) { + if (self->_response.usesChunkedTransferEncoding) { const char* hexString = [[NSString stringWithFormat:@"%lx", (unsigned long)data.length] UTF8String]; size_t hexLength = strlen(hexString); NSData* chunk = [NSMutableData dataWithLength:(hexLength + 2 + data.length + 2)]; if (chunk == nil) { - GWS_LOG_ERROR(@"Failed allocating memory for response body chunk for socket %i: %@", _socket, error); + GWS_LOG_ERROR(@"Failed allocating memory for response body chunk for socket %i: %@", self->_socket, error); block(NO); return; } @@ -631,7 +631,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) { } }]; } else { - if (_response.usesChunkedTransferEncoding) { + if (self->_response.usesChunkedTransferEncoding) { [self writeData:_lastChunkData withCompletionBlock:^(BOOL success) { block(success); @@ -641,7 +641,7 @@ static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) { } } } else { - GWS_LOG_ERROR(@"Failed reading response body for socket %i: %@", _socket, error); + GWS_LOG_ERROR(@"Failed reading response body for socket %i: %@", self->_socket, error); block(NO); } }];