Skip to content

Commit

Permalink
Added support for https, closes #2
Browse files Browse the repository at this point in the history
  • Loading branch information
OrkhanAlikhanov committed May 7, 2018
1 parent 7b222cb commit 224c4a4
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Request.swift.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Request.swift'
s.version = '2.1.0'
s.version = '2.2.0'
s.summary = 'A (sync/async) tiny http client written in swift.'
s.homepage = 'https://github.com/BiAtoms/Request.swift'
s.license = { :type => 'MIT', :file => 'LICENSE' }
Expand Down
42 changes: 24 additions & 18 deletions Sources/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,41 @@ open class Client {

public init(baseUrl: String? = nil, usesSystemProxy: Bool = true) {
self.baseUrl = baseUrl
self.usesSystemProxy = usesSystemProxy
#if os(Linux)
try! TLS.initialize()
#endif
}

//https://forums.developer.apple.com/thread/65416
open static func getSystemProxy(for host: String) -> Proxy? {
#if os(Linux) //CFNetworkCopySystemProxySettings hasn't been implemented. (see https://github.com/apple/swift-corelibs-foundation)
#else
if let url = URL(string: host) {
if let proxySettingsUnmanaged = CFNetworkCopySystemProxySettings() {
let proxySettings = proxySettingsUnmanaged.takeRetainedValue()
let proxiesUnmanaged = CFNetworkCopyProxiesForURL(url as CFURL, proxySettings)
let proxies = proxiesUnmanaged.takeRetainedValue() as! [[String:AnyObject]]

for dict in proxies {
if let type = dict[kCFProxyTypeKey as String] {
if type as! CFString == kCFProxyTypeHTTP { //only http for now
let host = dict[kCFProxyHostNameKey as String] as! String
let port = (dict[kCFProxyPortNumberKey as String] as! NSNumber).intValue
return (host, Port(port))
}
}
guard let url = URL(string: host),
let proxySettingsUnmanaged = CFNetworkCopySystemProxySettings()
else { return nil }
let proxySettings = proxySettingsUnmanaged.takeRetainedValue()
let proxiesUnmanaged = CFNetworkCopyProxiesForURL(url as CFURL, proxySettings)
let proxies = proxiesUnmanaged.takeRetainedValue() as! [[String: AnyObject]]

func isValid(type: Any) -> Bool {
let t = type as! CFString
let isHttp = url.scheme == "http" && t == kCFProxyTypeHTTP
let isHttps = url.scheme == "https" && t == kCFProxyTypeHTTPS
return isHttp || isHttps
}
for dict in proxies {
guard let type = dict[kCFProxyTypeKey as String] else { continue }
if isValid(type: type) {
let host = dict[kCFProxyHostNameKey as String] as! String
let port = (dict[kCFProxyPortNumberKey as String] as! NSNumber).intValue
return (host, Port(port))
}

}
}
}
#endif
return nil
}


open func request(_ url: String, method: Request.Method = .get, parameters: Parameters? = nil, encoding: ParameterEncoding = URLEncoding.default, headers: Headers? = nil)
-> Requester
{
Expand Down
8 changes: 8 additions & 0 deletions Sources/Request.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ open class Request {
return (hostname, port)
}

open var defaultPort: Port {
return isSecure ? 443 : 80
}

open var isSecure: Bool {
return url.starts(with: "https")
}

private static func firstMatch(pattern: String, in string: String) -> NSTextCheckingResult {
let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
return regex.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.characters.count))!
Expand Down
8 changes: 6 additions & 2 deletions Sources/Requester.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,24 @@ open class Requester {
let (hostname, portString) = request.hostnameAndPort
if let proxy = self.proxy {
try connect(socket, hostname: proxy.host, port: proxy.port)
let to = hostname + ":" + (portString ?? "80")
let to = hostname + ":" + (portString ?? "\(request.defaultPort)")
try socket.write("CONNECT \(to) HTTP/1.0\r\n\r\n".bytes)
try wait(socket)
let response = try ResponseParser.parse(socket: socket)
if response.statusCode != 200 {
throw Request.Error.proxyConnectionFailed
}
} else {
var port: SocketSwift.Port = 80
var port: SocketSwift.Port = request.defaultPort
if let p = portString {
port = Port(p)!
}
try connect(socket, hostname: hostname, port: port)
}

if request.isSecure {
try socket.startTls(.init(peer: hostname))
}
}

open func reset() {
Expand Down
29 changes: 24 additions & 5 deletions Tests/RequestSwiftTests/RequestSwiftTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class RequestSwiftTests: XCTestCase {
return a.client
}

func testExample() {
let ex = expectation(description: "example")
func testHttp() {
let ex = expectation(description: "http")
client.request("http://example.com/", headers: ["Accept": "text/html"]).response { response, error in

XCTAssertNil(error, "error should be nil")
Expand All @@ -36,6 +36,25 @@ class RequestSwiftTests: XCTestCase {
waitForExpectations()
}

func testHttps() {
let ex = expectation(description: "https")
client.request("https://example.com", headers: ["Accept": "text/html"]).response { response, error in

XCTAssertNil(error, "error should be nil")
XCTAssertNotNil(response, "response should no be nil")
let response = response!
XCTAssertEqual(response.statusCode, 200)
XCTAssertEqual(response.reasonPhrase, "OK")
print(String(cString: response.body))
XCTAssert(String(cString: response.body).contains("<h1>Example Domain</h1>"))

ex.fulfill()
}

waitForExpectations()
}


func testErrorTimeout() {
let ex = expectation(description: "timeout")
client.firesImmediately = false
Expand Down Expand Up @@ -113,16 +132,16 @@ class RequestSwiftTests: XCTestCase {

XCTAssertEqual(writtenStringArray, requestStringArray)
}


static var allTests = [
("testExample", testExample),
("testHttp", testHttp),
("testHttps", testHttps),
("testErrorTimeout", testErrorTimeout),
("testErrorDNS", testErrorDNS),
("testUrlEncoding", testUrlEncoding),
("testRequestPath", testErrorDNS),
("testRequestWriter", testRequestWriter),
]
]
}

extension XCTestCase {
Expand Down

0 comments on commit 224c4a4

Please sign in to comment.