Explorar o código

Expose local and remote address on GCDWebServerConnection

Pierre-Olivier Latour %!s(int64=11) %!d(string=hai) anos
pai
achega
d32ea02b97

+ 15 - 5
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

+ 4 - 1
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

+ 32 - 5
CGDWebServer/GCDWebServerConnection.m

@@ -25,6 +25,8 @@
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#import <netdb.h>
+
 #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);

+ 1 - 1
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 ()