@@ -15,7 +15,7 @@ public protocol HttpServerIODelegate: class {
1515public class HttpServerIO {
1616
1717 public weak var delegate : HttpServerIODelegate ?
18-
18+
1919 private var socket = Socket ( socketFileDescriptor: - 1 )
2020 private var sockets = Set < Socket > ( )
2121
@@ -25,9 +25,9 @@ public class HttpServerIO {
2525 case stopping
2626 case stopped
2727 }
28-
28+
2929 private var stateValue : Int32 = HttpServerIOState . stopped. rawValue
30-
30+
3131 public private( set) var state : HttpServerIOState {
3232 get {
3333 return HttpServerIOState ( rawValue: stateValue) !
@@ -41,29 +41,40 @@ public class HttpServerIO {
4141 #endif
4242 }
4343 }
44-
44+
4545 public var operating : Bool { get { return self . state == . running } }
46-
46+
47+ /// String representation of the IPv4 address to receive requests from.
48+ /// It's only used when the server is started with `forceIPv4` option set to true.
49+ /// Otherwise, `listenAddressIPv6` will be used.
50+ public var listenAddressIPv4 : String ?
51+
52+ /// String representation of the IPv6 address to receive requests from.
53+ /// It's only used when the server is started with `forceIPv4` option set to false.
54+ /// Otherwise, `listenAddressIPv4` will be used.
55+ public var listenAddressIPv6 : String ?
56+
4757 private let queue = DispatchQueue ( label: " swifter.httpserverio.clientsockets " )
48-
58+
4959 public func port( ) throws -> Int {
5060 return Int ( try socket. port ( ) )
5161 }
52-
62+
5363 public func isIPv4( ) throws -> Bool {
5464 return try socket. isIPv4 ( )
5565 }
56-
66+
5767 deinit {
5868 stop ( )
5969 }
60-
70+
6171 @available ( macOS 10 . 10 , * )
6272 public func start( _ port: in_port_t = 8080 , forceIPv4: Bool = false , priority: DispatchQoS . QoSClass = DispatchQoS . QoSClass. background) throws {
6373 guard !self . operating else { return }
6474 stop ( )
6575 self . state = . starting
66- self . socket = try Socket . tcpSocketForListen ( port, forceIPv4)
76+ let address = forceIPv4 ? listenAddressIPv4 : listenAddressIPv6
77+ self . socket = try Socket . tcpSocketForListen ( port, forceIPv4, SOMAXCONN, address)
6778 DispatchQueue . global ( qos: priority) . async { [ weak self] in
6879 guard let `self` = self else { return }
6980 guard self . operating else { return }
@@ -84,7 +95,7 @@ public class HttpServerIO {
8495 }
8596 self . state = . running
8697 }
87-
98+
8899 public func stop( ) {
89100 guard self . operating else { return }
90101 self . state = . stopping
@@ -98,11 +109,11 @@ public class HttpServerIO {
98109 socket. close ( )
99110 self . state = . stopped
100111 }
101-
112+
102113 public func dispatch( _ request: HttpRequest ) -> ( [ String : String ] , ( HttpRequest ) -> HttpResponse ) {
103114 return ( [ : ] , { _ in HttpResponse . notFound } )
104115 }
105-
116+
106117 private func handleConnection( _ socket: Socket ) {
107118 let parser = HttpParser ( )
108119 while self . operating, let request = try ? parser. readHttpRequest ( socket) {
@@ -129,7 +140,7 @@ public class HttpServerIO {
129140 }
130141 socket. close ( )
131142 }
132-
143+
133144 private struct InnerWriteContext : HttpResponseBodyWriter {
134145
135146 let socket : Socket
@@ -149,38 +160,38 @@ public class HttpServerIO {
149160 func write( _ data: NSData ) throws {
150161 try socket. writeData ( data)
151162 }
152-
163+
153164 func write( _ data: Data ) throws {
154165 try socket. writeData ( data)
155166 }
156167 }
157-
168+
158169 private func respond( _ socket: Socket , response: HttpResponse , keepAlive: Bool ) throws -> Bool {
159170 guard self . operating else { return false }
160171
161172 try socket. writeUTF8 ( " HTTP/1.1 \( response. statusCode ( ) ) \( response. reasonPhrase ( ) ) \r \n " )
162-
173+
163174 let content = response. content ( )
164-
175+
165176 if content. length >= 0 {
166177 try socket. writeUTF8 ( " Content-Length: \( content. length) \r \n " )
167178 }
168-
179+
169180 if keepAlive && content. length != - 1 {
170181 try socket. writeUTF8 ( " Connection: keep-alive \r \n " )
171182 }
172-
183+
173184 for (name, value) in response. headers ( ) {
174185 try socket. writeUTF8 ( " \( name) : \( value) \r \n " )
175186 }
176-
187+
177188 try socket. writeUTF8 ( " \r \n " )
178-
189+
179190 if let writeClosure = content. write {
180191 let context = InnerWriteContext ( socket: socket)
181192 try writeClosure ( context)
182193 }
183-
194+
184195 return keepAlive && content. length != - 1 ;
185196 }
186197}
0 commit comments