diff --git a/GCDWebServer/Core/GCDWebServer.h b/GCDWebServer/Core/GCDWebServer.h index ff414c9..b40b58f 100644 --- a/GCDWebServer/Core/GCDWebServer.h +++ b/GCDWebServer/Core/GCDWebServer.h @@ -90,6 +90,17 @@ extern NSString* const GCDWebServerOption_BonjourName; */ extern NSString* const GCDWebServerOption_BonjourType; +/** + * Only accept HTTP requests coming from localhost i.e. not from the outside + * network (NSNumber / BOOL). + * + * The default value is NO. + * + * @warning Bonjour should be disabled if using this option since the server + * will not be reachable from the outside network anyway. + */ +extern NSString* const GCDWebServerOption_BindToLocalhost; + /** * The maximum number of incoming HTTP requests that can be queued waiting to * be handled before new ones are dropped (NSNumber / NSUInteger). diff --git a/GCDWebServer/Core/GCDWebServer.m b/GCDWebServer/Core/GCDWebServer.m index a69493a..b207b3c 100644 --- a/GCDWebServer/Core/GCDWebServer.m +++ b/GCDWebServer/Core/GCDWebServer.m @@ -50,6 +50,7 @@ NSString* const GCDWebServerOption_Port = @"Port"; NSString* const GCDWebServerOption_BonjourName = @"BonjourName"; NSString* const GCDWebServerOption_BonjourType = @"BonjourType"; +NSString* const GCDWebServerOption_BindToLocalhost = @"BindToLocalhost"; NSString* const GCDWebServerOption_MaxPendingConnections = @"MaxPendingConnections"; NSString* const GCDWebServerOption_ServerName = @"ServerName"; NSString* const GCDWebServerOption_AuthenticationMethod = @"AuthenticationMethod"; @@ -495,6 +496,7 @@ static inline NSString* _EncodeBase64(NSString* string) { GWS_DCHECK(_source4 == NULL); NSUInteger port = [_GetOption(_options, GCDWebServerOption_Port, @0) unsignedIntegerValue]; + BOOL bindToLocalhost = [_GetOption(_options, GCDWebServerOption_BindToLocalhost, @NO) boolValue]; NSUInteger maxPendingConnections = [_GetOption(_options, GCDWebServerOption_MaxPendingConnections, @16) unsignedIntegerValue]; struct sockaddr_in addr4; @@ -502,7 +504,7 @@ static inline NSString* _EncodeBase64(NSString* string) { addr4.sin_len = sizeof(addr4); addr4.sin_family = AF_INET; addr4.sin_port = htons(port); - addr4.sin_addr.s_addr = htonl(INADDR_ANY); + addr4.sin_addr.s_addr = bindToLocalhost ? htonl(INADDR_LOOPBACK) : htonl(INADDR_ANY); int listeningSocket4 = [self _createListeningSocket:NO localAddress:&addr4 length:sizeof(addr4) maxPendingConnections:maxPendingConnections error:error]; if (listeningSocket4 <= 0) { return NO; @@ -523,7 +525,7 @@ static inline NSString* _EncodeBase64(NSString* string) { addr6.sin6_len = sizeof(addr6); addr6.sin6_family = AF_INET6; addr6.sin6_port = htons(port); - addr6.sin6_addr = in6addr_any; + addr6.sin6_addr = bindToLocalhost ? in6addr_loopback : in6addr_any; int listeningSocket6 = [self _createListeningSocket:YES localAddress:&addr6 length:sizeof(addr6) maxPendingConnections:maxPendingConnections error:error]; if (listeningSocket6 <= 0) { close(listeningSocket4); diff --git a/Mac/main.m b/Mac/main.m index f446ce0..96648bd 100644 --- a/Mac/main.m +++ b/Mac/main.m @@ -141,9 +141,10 @@ int main(int argc, const char* argv[]) { NSString* authenticationRealm = nil; NSString* authenticationUser = nil; NSString* authenticationPassword = nil; + BOOL bindToLocalhost = NO; if (argc == 1) { - fprintf(stdout, "Usage: %s [-mode webServer | htmlPage | htmlForm | htmlFileUpload | webDAV | webUploader | streamingResponse | asyncResponse] [-record] [-root directory] [-tests directory] [-authenticationMethod Basic | Digest] [-authenticationRealm realm] [-authenticationUser user] [-authenticationPassword password]\n\n", basename((char*)argv[0])); + fprintf(stdout, "Usage: %s [-mode webServer | htmlPage | htmlForm | htmlFileUpload | webDAV | webUploader | streamingResponse | asyncResponse] [-record] [-root directory] [-tests directory] [-authenticationMethod Basic | Digest] [-authenticationRealm realm] [-authenticationUser user] [-authenticationPassword password] [--localhost]\n\n", basename((char*)argv[0])); } else { for (int i = 1; i < argc; ++i) { if (argv[i][0] != '-') { @@ -188,6 +189,8 @@ int main(int argc, const char* argv[]) { } else if (!strcmp(argv[i], "-authenticationPassword") && (i + 1 < argc)) { ++i; authenticationPassword = [NSString stringWithUTF8String:argv[i]]; + } else if (!strcmp(argv[i], "--localhost")) { + bindToLocalhost = YES; } } } @@ -386,6 +389,7 @@ int main(int argc, const char* argv[]) { fprintf(stdout, "\n"); NSMutableDictionary* options = [NSMutableDictionary dictionary]; [options setObject:@8080 forKey:GCDWebServerOption_Port]; + [options setObject:@(bindToLocalhost) forKey:GCDWebServerOption_BindToLocalhost]; [options setObject:@"" forKey:GCDWebServerOption_BonjourName]; if (authenticationUser && authenticationPassword) { [options setValue:authenticationRealm forKey:GCDWebServerOption_AuthenticationRealm];