Skip to content

Commit

Permalink
Allow Kitura-Net to only listen on one network address (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
TaborKelly authored and djones6 committed May 24, 2019
1 parent fa808b1 commit 5fc06b2
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 27 deletions.
29 changes: 19 additions & 10 deletions Sources/KituraNet/FastCGI/FastCGIServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public class FastCGIServer: Server {
*/
public private(set) var port: Int?

/// The address of the network interface to listen on. Defaults to nil, which means this server will listen on all
/// interfaces.
public private(set) var address: String?

/**
A server state.
Expand Down Expand Up @@ -108,14 +112,17 @@ public class FastCGIServer: Server {
Listens for connections on a socket
- Parameter on: port number for new connections
- Parameter address: The address of a network interface to listen on, for example "localhost". The default is nil,
which listens for connections on all interfaces.
### Usage Example: ###
````swift
try server.listen(on: port)
try server.listen(on: port, address: "localhost")
````
*/
public func listen(on port: Int) throws {
public func listen(on port: Int, address: String? = nil) throws {
self.port = port
self.address = address
do {
let socket = try Socket.create()
self.listenSocket = socket
Expand Down Expand Up @@ -144,24 +151,26 @@ public class FastCGIServer: Server {

/**
Static method to create a new `FastCGIServer` and have it listen for conenctions
- Parameter on: port number for accepting new connections
- Parameter address: The address of a network interface to listen on, for example "localhost". The default is nil,
which listens for connections on all interfaces.
- Parameter delegate: the delegate handler for FastCGI/HTTP connections
- Returns: a new `FastCGIServer` instance
### Usage Example: ###
````swift
let server = try FastCGIServer.listen(on: port, delegate: delegate)
let server = try FastCGIServer.listen(on: port, address: "localhost", delegate: delegate)
````
*/
public static func listen(on port: Int, delegate: ServerDelegate?) throws -> FastCGIServer {
public static func listen(on port: Int, address: String? = nil, delegate: ServerDelegate?) throws -> FastCGIServer {
let server = FastCGI.createServer()
server.delegate = delegate
try server.listen(on: port)
try server.listen(on: port, address: address)
return server
}

/**
Listens for connections on a socket
Expand Down
28 changes: 19 additions & 9 deletions Sources/KituraNet/HTTP/HTTPServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,16 @@ public class HTTPServer: Server {
/// The TCP port on which this server listens for new connections. If `nil`, this server does not listen on a TCP socket.
public private(set) var port: Int?

/// The address of the network interface to listen on. Defaults to nil, which means this server will listen on all
/// interfaces.
public private(set) var address: String?

/// The Unix domain socket path on which this server listens for new connections. If `nil`, this server does not listen on a Unix socket.
public private(set) var unixDomainSocketPath: String?

/// The types of listeners we currently support.
private enum ListenerType {
case inet(Int)
case inet(Int, String?) // port, node
case unix(String)
}

Expand Down Expand Up @@ -151,14 +155,17 @@ public class HTTPServer: Server {
### Usage Example: ###
````swift
try server.listen(on: 8080)
try server.listen(on: 8080, address: "localhost")
````
- Parameter port: Port number for new connections, e.g. 8080
- Parameter address: The address of a network interface to listen on, for example "localhost". The default is nil,
which listens for connections on all interfaces.
*/
public func listen(on port: Int) throws {
public func listen(on port: Int, address: String? = nil) throws {
self.port = port
try listen(.inet(port))
self.address = address
try listen(.inet(port, address))
}

/**
Expand Down Expand Up @@ -195,8 +202,9 @@ public class HTTPServer: Server {

let listenerDescription: String
switch listener {
case .inet(let port):
try socket.listen(on: port, maxBacklogSize: maxPendingConnections, allowPortReuse: self.allowPortReuse)
case .inet(let port, let node):
try socket.listen(on: port, maxBacklogSize: maxPendingConnections, allowPortReuse: self.allowPortReuse,
node: node)
// If a random (ephemeral) port number was requested, get the listening port
let listeningPort = Int(socket.listeningPort)
if listeningPort != port {
Expand Down Expand Up @@ -253,18 +261,20 @@ public class HTTPServer: Server {
### Usage Example: ###
````swift
let server = HTTPServer.listen(on: 8080, delegate: self)
let server = HTTPServer.listen(on: 8080, address: "localhost", delegate: self)
````
- Parameter on: Port number for accepting new connections.
- Parameter address: The address of a network interface to listen on, for example "localhost". The default is nil,
which listens for connections on all interfaces.
- Parameter delegate: The delegate handler for HTTP connections.
- Returns: A new instance of a `HTTPServer`.
*/
public static func listen(on port: Int, delegate: ServerDelegate?) throws -> HTTPServer {
public static func listen(on port: Int, address: String? = nil, delegate: ServerDelegate?) throws -> HTTPServer {
let server = HTTP.createServer()
server.delegate = delegate
try server.listen(on: port)
try server.listen(on: port, address: address)
return server
}

Expand Down
30 changes: 30 additions & 0 deletions Sources/KituraNet/Server/Server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,35 @@ public protocol Server {
/// Port number for listening for new connections.
var port: Int? { get }

/// The address of the network interface to listen on. Defaults to nil, which means this server will listen on all
/// interfaces.
var address: String? { get }

/// A server state.
var state: ServerState { get }

/// Listen for connections on a socket.
///
/// - Parameter on: port number for new connections (eg. 8080)
/// - Parameter address: The address of a network interface to listen on, for example "localhost". The default is
/// nil, which listens for connections on all interfaces.
func listen(on port: Int, address: String?) throws

/// Listen for connections on a socket.
///
/// - Parameter on: port number for new connections (eg. 8080)
func listen(on port: Int) throws

/// Static method to create a new Server and have it listen for connections.
///
/// - Parameter on: port number for accepting new connections
/// - Parameter address: The address of a network interface to listen on, for example "localhost". The default is
/// nil, which listens for connections on all interfaces.
/// - Parameter delegate: the delegate handler for HTTP connections
///
/// - Returns: a new Server instance
static func listen(on port: Int, address: String?, delegate: ServerDelegate?) throws -> ServerType

/// Static method to create a new Server and have it listen for connections.
///
/// - Parameter on: port number for accepting new connections
Expand Down Expand Up @@ -94,3 +115,12 @@ public protocol Server {
@discardableResult
func clientConnectionFailed(callback: @escaping (Swift.Error) -> Void) -> Self
}

extension Server {
public func listen(on port: Int) throws {
try listen(on: port, address: nil)
}
public static func listen(on port: Int, delegate: ServerDelegate?) throws -> ServerType {
return try Self.listen(on: port, address: nil, delegate: delegate)
}
}
2 changes: 1 addition & 1 deletion Tests/KituraNetTests/ClientE2ETests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class ClientE2ETests: KituraNetTest {

func testEphemeralListeningPort() {
do {
let server = try HTTPServer.listen(on: 0, delegate: delegate)
let server = try HTTPServer.listen(on: 0, address: "localhost", delegate: delegate)
_ = HTTP.get("http://localhost:\(server.port!)") { response in
XCTAssertNotNil(response, "ERROR!!! ClientRequest response object was nil")
XCTAssertEqual(response?.statusCode, HTTPStatusCode.OK, "HTTP Status code was \(String(describing: response?.statusCode))")
Expand Down
4 changes: 2 additions & 2 deletions Tests/KituraNetTests/KituraNetTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class KituraNetTest: XCTestCase {
if let unixDomainSocketPath = unixDomainSocketPath {
try server.listen(unixDomainSocketPath: unixDomainSocketPath)
} else {
try server.listen(on: port)
try server.listen(on: port, address: "localhost")
}
return server
}
Expand Down Expand Up @@ -163,7 +163,7 @@ class KituraNetTest: XCTestCase {
do {
self.port = port

let server = try FastCGIServer.listen(on: port, delegate: delegate)
let server = try FastCGIServer.listen(on: port, address: "localhost", delegate: delegate)
server.allowPortReuse = allowPortReuse
defer {
server.stop()
Expand Down
8 changes: 4 additions & 4 deletions Tests/KituraNetTests/LifecycleListenerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class LifecycleListenerTests: KituraNetTest {
}

do {
try server.listen(on: self.port)
try server.listen(on: self.port, address: "localhost")

self.waitForExpectations(timeout: 5) { error in
XCTAssertNil(error)
Expand Down Expand Up @@ -93,7 +93,7 @@ class LifecycleListenerTests: KituraNetTest {
}

do {
try server.listen(on: self.port)
try server.listen(on: self.port, address: "localhost")

self.waitForExpectations(timeout: 5) { error in
XCTAssertNil(error)
Expand Down Expand Up @@ -127,7 +127,7 @@ class LifecycleListenerTests: KituraNetTest {
}

do {
try server.listen(on: self.port)
try server.listen(on: self.port, address: "localhost")

self.waitForExpectations(timeout: 5) { error in
XCTAssertNil(error)
Expand Down Expand Up @@ -155,7 +155,7 @@ class LifecycleListenerTests: KituraNetTest {
})

do {
try server.listen(on: -1)
try server.listen(on: -1, address: nil)
} catch {
// Do NOT fail the test if an error is thrown.
// In this test case an error should be thrown.
Expand Down
2 changes: 1 addition & 1 deletion Tests/KituraNetTests/MonitoringTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class MonitoringTests: KituraNetTest {
}

do {
try server.listen(on: self.port)
try server.listen(on: self.port, address: nil)

self.waitForExpectations(timeout: 10) { error in
server.stop()
Expand Down

0 comments on commit 5fc06b2

Please sign in to comment.