diff --git a/CGDWebServer/GCDWebServer.m b/CGDWebServer/GCDWebServer.m index 650d30b..aed884e 100644 --- a/CGDWebServer/GCDWebServer.m +++ b/CGDWebServer/GCDWebServer.m @@ -264,16 +264,26 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er dispatch_source_set_event_handler(_source, ^{ @autoreleasepool { - struct sockaddr addr; - socklen_t addrlen = sizeof(addr); - int socket = accept(listeningSocket, &addr, &addrlen); + struct sockaddr remoteSockAddr; + socklen_t remoteAddrLen = sizeof(remoteSockAddr); + int socket = accept(listeningSocket, &remoteSockAddr, &remoteAddrLen); if (socket > 0) { + NSData* remoteAddress = [NSData dataWithBytes:&remoteSockAddr length:remoteAddrLen]; + + struct sockaddr localSockAddr; + socklen_t localAddrLen = sizeof(localSockAddr); + NSData* localAddress = nil; + if (getsockname(socket, &localSockAddr, &localAddrLen) == 0) { + localAddress = [NSData dataWithBytes:&localSockAddr length:localAddrLen]; + } else { + DNOT_REACHED(); + } + int yes = 1; setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &yes, sizeof(yes)); // Make sure this socket cannot generate SIG_PIPE - NSData* data = [NSData dataWithBytes:&addr length:addrlen]; Class connectionClass = [[self class] connectionClass]; - GCDWebServerConnection* connection = [[connectionClass alloc] initWithServer:self address:data 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 #else diff --git a/CGDWebServer/GCDWebServerConnection.h b/CGDWebServer/GCDWebServerConnection.h index b0b95e2..2f5f1aa 100644 --- a/CGDWebServer/GCDWebServerConnection.h +++ b/CGDWebServer/GCDWebServerConnection.h @@ -31,7 +31,10 @@ @interface GCDWebServerConnection : NSObject @property(nonatomic, readonly) GCDWebServer* server; -@property(nonatomic, readonly) NSData* address; // struct sockaddr +@property(nonatomic, readonly) NSData* localAddressData; // struct sockaddr +@property(nonatomic, readonly) NSString* localAddressString; +@property(nonatomic, readonly) NSData* remoteAddressData; // struct sockaddr +@property(nonatomic, readonly) NSString* remoteAddressString; @property(nonatomic, readonly) NSUInteger totalBytesRead; @property(nonatomic, readonly) NSUInteger totalBytesWritten; @end diff --git a/CGDWebServer/GCDWebServerConnection.m b/CGDWebServer/GCDWebServerConnection.m index f04f367..f54a318 100644 --- a/CGDWebServer/GCDWebServerConnection.m +++ b/CGDWebServer/GCDWebServerConnection.m @@ -25,6 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#import + #import "GCDWebServerPrivate.h" #define kHeadersReadBuffer 1024 @@ -48,7 +50,8 @@ static dispatch_queue_t _formatterQueue = NULL; @interface GCDWebServerConnection () { @private GCDWebServer* _server; - NSData* _address; + NSData* _localAddress; + NSData* _remoteAddress; CFSocketNativeHandle _socket; NSUInteger _bytesRead; NSUInteger _bytesWritten; @@ -259,7 +262,7 @@ static dispatch_queue_t _formatterQueue = NULL; @implementation GCDWebServerConnection -@synthesize server=_server, address=_address, totalBytesRead=_bytesRead, totalBytesWritten=_bytesWritten; +@synthesize server=_server, localAddressData=_localAddress, remoteAddressData=_remoteAddress, totalBytesRead=_bytesRead, totalBytesWritten=_bytesWritten; + (void)initialize { if (_separatorData == nil) { @@ -458,10 +461,11 @@ static dispatch_queue_t _formatterQueue = NULL; }]; } -- (id)initWithServer:(GCDWebServer*)server address:(NSData*)address socket:(CFSocketNativeHandle)socket { +- (id)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket { if ((self = [super init])) { _server = ARC_RETAIN(server); - _address = ARC_RETAIN(address); + _localAddress = ARC_RETAIN(localAddress); + _remoteAddress = ARC_RETAIN(remoteAddress); _socket = socket; [self open]; @@ -469,11 +473,33 @@ static dispatch_queue_t _formatterQueue = NULL; return self; } +static NSString* _StringFromAddressData(NSData* data) { + NSString* string = nil; + const struct sockaddr* addr = data.bytes; + char hostBuffer[NI_MAXHOST]; + char serviceBuffer[NI_MAXSERV]; + if (getnameinfo(addr, addr->sa_len, hostBuffer, sizeof(hostBuffer), serviceBuffer, sizeof(serviceBuffer), NI_NUMERICHOST | NI_NUMERICSERV | NI_NOFQDN) >= 0) { + string = [NSString stringWithFormat:@"%s:%s", hostBuffer, serviceBuffer]; + } else { + DNOT_REACHED(); + } + return string; +} + +- (NSString*)localAddressString { + return _StringFromAddressData(_localAddress); +} + +- (NSString*)remoteAddressString { + return _StringFromAddressData(_remoteAddress); +} + - (void)dealloc { [self close]; ARC_RELEASE(_server); - ARC_RELEASE(_address); + ARC_RELEASE(_localAddress); + ARC_RELEASE(_remoteAddress); if (_requestMessage) { CFRelease(_requestMessage); @@ -510,6 +536,7 @@ static dispatch_queue_t _formatterQueue = NULL; 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); } @catch (NSException* exception) { LOG_EXCEPTION(exception); diff --git a/CGDWebServer/GCDWebServerPrivate.h b/CGDWebServer/GCDWebServerPrivate.h index 6fe4c61..dad7adc 100644 --- a/CGDWebServer/GCDWebServerPrivate.h +++ b/CGDWebServer/GCDWebServerPrivate.h @@ -92,7 +92,7 @@ extern void GCDLogMessage(long level, NSString* format, ...) NS_FORMAT_FUNCTION( #define kGCDWebServerGCDQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) @interface GCDWebServerConnection () -- (id)initWithServer:(GCDWebServer*)server address:(NSData*)address socket:(CFSocketNativeHandle)socket; +- (id)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket; @end @interface GCDWebServer ()