Skip to content

Commit

Permalink
Merge pull request #2 from depoon/update-modifier
Browse files Browse the repository at this point in the history
Introduce initializeUsingRandomPortNumber
  • Loading branch information
depoon authored Dec 26, 2018
2 parents f9ba6f0 + 2c9a98e commit 7d560dc
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 4 deletions.
62 changes: 62 additions & 0 deletions Source/Localhost/LocalhostPort.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// LocalhostPort.swift
// SwiftLocalhost
//
// Created by Kenneth Poon on 27/12/18.
// Copyright © 2018 Kenneth Poon. All rights reserved.
//

import Foundation

public class LocalhostPort {

public static func availablePortNumber() -> UInt16 {
for i in 50000..<65000 {
let (isFree, _) = checkTcpPortForListen(port: UInt16(i))
if isFree == true {
return UInt16(i)
}
}
return 0
}

static func checkTcpPortForListen(port: in_port_t) -> (Bool, descr: String) {

let socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0)
if socketFileDescriptor == -1 {
return (false, "SocketCreationFailed, \(descriptionOfLastError())")
}

var addr = sockaddr_in()
let sizeOfSockkAddr = MemoryLayout<sockaddr_in>.size
addr.sin_len = __uint8_t(sizeOfSockkAddr)
addr.sin_family = sa_family_t(AF_INET)
addr.sin_port = Int(OSHostByteOrder()) == OSLittleEndian ? _OSSwapInt16(port) : port
addr.sin_addr = in_addr(s_addr: inet_addr("0.0.0.0"))
addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0)
var bind_addr = sockaddr()
memcpy(&bind_addr, &addr, Int(sizeOfSockkAddr))

if Darwin.bind(socketFileDescriptor, &bind_addr, socklen_t(sizeOfSockkAddr)) == -1 {
let details = descriptionOfLastError()
release(socket: socketFileDescriptor)
return (false, "\(port), BindFailed, \(details)")
}
if listen(socketFileDescriptor, SOMAXCONN ) == -1 {
let details = descriptionOfLastError()
release(socket: socketFileDescriptor)
return (false, "\(port), ListenFailed, \(details)")
}
release(socket: socketFileDescriptor)
return (true, "\(port) is free for use")
}

static func release(socket: Int32) {
Darwin.shutdown(socket, SHUT_RDWR)
close(socket)
}

static func descriptionOfLastError() -> String {
return String.init(cString: (UnsafePointer(strerror(errno))))
}
}
9 changes: 7 additions & 2 deletions Source/Localhost/LocalhostServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ extension LocalhostServer: LocalhostRouter {

public class LocalhostServer {

public let portNumber: UInt
let server: CRHTTPServer
let portNumber: UInt

var recordedRequests: [URLRequest]

Expand All @@ -59,6 +59,11 @@ public class LocalhostServer {
recordedRequests = [URLRequest]()
}

public static func initializeUsingRandomPortNumber() -> LocalhostServer{
let availablePort: UInt = UInt(LocalhostPort.availablePortNumber())
return LocalhostServer(portNumber: availablePort)
}

fileprivate func handleRoute(routeBlock: @escaping ((URLRequest) -> LocalhostServerResponse?),
crRequest: CRRequest,
crResponse: CRResponse) {
Expand All @@ -78,7 +83,7 @@ public class LocalhostServer {
crResponse.setAllHTTPHeaderFields(allHeaderFields)
}
if let data = response.data {
crResponse.bodyData = data
crResponse.send(data)
}
}

Expand Down
7 changes: 6 additions & 1 deletion Source/Localhost/LocalhostServerResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,10 @@ import Foundation

public struct LocalhostServerResponse {
public let httpUrlResponse: HTTPURLResponse
public let data: Data?
public let data: Any?

public init(httpUrlResponse: HTTPURLResponse, data: Any? = nil) {
self.httpUrlResponse = httpUrlResponse
self.data = data
}
}
2 changes: 1 addition & 1 deletion SwiftLocalhost.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Pod::Spec.new do |s|
s.name = "SwiftLocalhost"
s.version = "0.0.1"
s.version = "0.0.2"
s.summary = "Swift Localhost Server for your testing needs"
s.description = <<-DESC
Features
Expand Down
4 changes: 4 additions & 0 deletions SwiftLocalhost.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
1C4BF397216FA095004794CB /* LocalhostServerResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C4BF390216FA095004794CB /* LocalhostServerResponse.swift */; };
1C4BF398216FA095004794CB /* GARequestPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C4BF391216FA095004794CB /* GARequestPayload.swift */; };
1C4BF39F216FA33F004794CB /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 1C4BF39E216FA33E004794CB /* Podfile */; };
1CA2340A21D3DFC7008436A0 /* LocalhostPort.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CA2340921D3DFC7008436A0 /* LocalhostPort.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -34,6 +35,7 @@
1C4BF39B216FA185004794CB /* SwiftLocalhost.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = SwiftLocalhost.podspec; sourceTree = "<group>"; };
1C4BF39C216FA268004794CB /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
1C4BF39E216FA33E004794CB /* Podfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Podfile; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
1CA2340921D3DFC7008436A0 /* LocalhostPort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalhostPort.swift; sourceTree = "<group>"; };
B368B3A45E59E277C654EC8F /* Pods_SwiftLocalhost.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftLocalhost.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B45D040DED76B449E2B215BC /* Pods-SwiftLocalhost.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftLocalhost.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftLocalhost/Pods-SwiftLocalhost.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -106,6 +108,7 @@
children = (
1C4BF38E216FA095004794CB /* LocalhostRouter.swift */,
1C4BF38B216FA095004794CB /* LocalhostServer.swift */,
1CA2340921D3DFC7008436A0 /* LocalhostPort.swift */,
1C4BF390216FA095004794CB /* LocalhostServerResponse.swift */,
);
path = Localhost;
Expand Down Expand Up @@ -234,6 +237,7 @@
1C4BF397216FA095004794CB /* LocalhostServerResponse.swift in Sources */,
1C4BF396216FA095004794CB /* GARequestLoggingServer.swift in Sources */,
1C4BF398216FA095004794CB /* GARequestPayload.swift in Sources */,
1CA2340A21D3DFC7008436A0 /* LocalhostPort.swift in Sources */,
1C4BF393216FA095004794CB /* GARequestLoggingReport.swift in Sources */,
1C4BF395216FA095004794CB /* LocalhostRouter.swift in Sources */,
1C4BF394216FA095004794CB /* GARequestPayloadFactory.swift in Sources */,
Expand Down

0 comments on commit 7d560dc

Please sign in to comment.