-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathTestURLProtectionSpace.swift
224 lines (199 loc) · 13.1 KB
/
TestURLProtectionSpace.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
#if NS_FOUNDATION_ALLOWS_TESTABLE_IMPORT
#if canImport(SwiftFoundationNetworking) && !DEPLOYMENT_RUNTIME_OBJC
@testable import SwiftFoundationNetworking
#else
#if canImport(FoundationNetworking)
@testable import FoundationNetworking
#endif
#endif
#endif
class TestURLProtectionSpace : XCTestCase {
func test_description() {
var space = URLProtectionSpace(
host: "apple.com",
port: 80,
protocol: "http",
realm: nil,
authenticationMethod: "basic"
)
XCTAssert(space.description.hasPrefix("<\(type(of: space))"))
XCTAssert(space.description.hasSuffix(": Host:apple.com, Server:http, Auth-Scheme:NSURLAuthenticationMethodDefault, Realm:(null), Port:80, Proxy:NO, Proxy-Type:(null)"))
space = URLProtectionSpace(
host: "apple.com",
port: 80,
protocol: "http",
realm: nil,
authenticationMethod: "NSURLAuthenticationMethodHTMLForm"
)
XCTAssert(space.description.hasPrefix("<\(type(of: space))"))
XCTAssert(space.description.hasSuffix(": Host:apple.com, Server:http, Auth-Scheme:NSURLAuthenticationMethodHTMLForm, Realm:(null), Port:80, Proxy:NO, Proxy-Type:(null)"))
}
#if NS_FOUNDATION_ALLOWS_TESTABLE_IMPORT
func test_createWithHTTPURLresponse() throws {
// Real response from outlook.office365.com
let headerFields1 = [
"Server": "Microsoft-IIS/10.0",
"request-id": "c71c2202-4013-4d64-9319-d40aba6bbe5c",
"WWW-Authenticate": "Basic Realm=\"\"",
"X-Powered-By": "ASP.NET",
"X-FEServer": "AM6PR0502CA0062",
"Date": "Sat, 04 Apr 2020 16:19:39 GMT",
"Content-Length": "0",
]
let response1 = try XCTUnwrap(HTTPURLResponse(url: URL(string: "https://outlook.office365.com/Microsoft-Server-ActiveSync")!,
statusCode: 401,
httpVersion: "HTTP/1.1",
headerFields: headerFields1))
let space1 = try XCTUnwrap(URLProtectionSpace.create(with: response1), "Failed to create protection space from valid response")
XCTAssertEqual(space1.authenticationMethod, NSURLAuthenticationMethodHTTPBasic)
XCTAssertEqual(space1.protocol, "https")
XCTAssertEqual(space1.host, "outlook.office365.com")
XCTAssertEqual(space1.port, 443)
XCTAssertEqual(space1.realm, "")
// Real response from jigsaw.w3.org
let headerFields2 = [
"date": "Sat, 04 Apr 2020 17:24:23 GMT",
"content-length": "261",
"content-type": "text/html;charset=ISO-8859-1",
"server": "Jigsaw/2.3.0-beta3",
"www-authenticate": "Basic realm=\"test\"",
"strict-transport-security": "max-age=15552015; includeSubDomains; preload",
"public-key-pins": "pin-sha256=\"cN0QSpPIkuwpT6iP2YjEo1bEwGpH/yiUn6yhdy+HNto=\"; pin-sha256=\"WGJkyYjx1QMdMe0UqlyOKXtydPDVrk7sl2fV+nNm1r4=\"; pin-sha256=\"LrKdTxZLRTvyHM4/atX2nquX9BeHRZMCxg3cf4rhc2I=\"; max-age=864000",
"x-frame-options": "deny",
"x-xss-protection": "1; mode=block",
]
let response2 = try XCTUnwrap(HTTPURLResponse(url: URL(string: "https://jigsaw.w3.org/HTTP/Basic/")!,
statusCode: 401,
httpVersion: "HTTP/2",
headerFields: headerFields2))
let space2 = try XCTUnwrap(URLProtectionSpace.create(with: response2), "Failed to create protection space from valid response")
XCTAssertEqual(space2.authenticationMethod, NSURLAuthenticationMethodHTTPBasic)
XCTAssertEqual(space2.protocol, "https")
XCTAssertEqual(space2.host, "jigsaw.w3.org")
XCTAssertEqual(space2.port, 443)
XCTAssertEqual(space2.realm, "test")
// Digest is not supported
let authenticate3 = "Digest realm=\"Test\", domain=\"/HTTP/Digest\", nonce=\"be2e96ad8ab8acb7ccfb49bc7e162914\""
let response3 = try XCTUnwrap(HTTPURLResponse(url: URL(string: "http://jigsaw.w3.org/HTTP/Basic/")!,
statusCode: 401,
httpVersion: "HTTP/1.1",
headerFields: ["www-authenticate" : authenticate3]))
XCTAssertNil(URLProtectionSpace.create(with: response3), "Digest scheme is not supported, should not create protection space")
// NTLM is not supported
let response4 = try XCTUnwrap(HTTPURLResponse(url: URL(string: "http://apple.com:333")!,
statusCode: 401,
httpVersion: "HTTP/1.1",
headerFields: ["www-authenTicate" : "NTLM realm=\"\""]))
XCTAssertNil(URLProtectionSpace.create(with: response4), "NTLM scheme is not supported, should not create protection space")
// Some broken headers
let response5 = try XCTUnwrap(HTTPURLResponse(url: URL(string: "http://apple.com")!,
statusCode: 401,
httpVersion: "HTTP/1.1",
headerFields: ["www-authenicate" : "Basic"]))
XCTAssertNil(URLProtectionSpace.create(with: response5), "Should not create protection space from invalid header")
let response6 = try XCTUnwrap(HTTPURLResponse(url: URL(string: "http://apple.com")!,
statusCode: 401,
httpVersion: "HTTP/1.1",
headerFields: ["www-authenticate" : "NT LM realm="]))
XCTAssertNil(URLProtectionSpace.create(with: response6), "Should not create protection space from invalid header")
}
func test_challenge() throws {
XCTAssertEqual(_HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "").count, 0, "No challenges should be parsed from empty string")
// This is valid challenges list as per RFC-7235, but it doesn't contain any known auth scheme
XCTAssertEqual(_HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "maybe challenge, maybe not").count, 0, "String doesn't contain any of supported schemes")
let challenges1 = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "Basic Realm=\"Test\",charset=\"utf-8\", other=\"be2e96ad8ab8acb7ccfb49bc7e162914\"")
XCTAssertEqual(challenges1.count, 1, "String contains valid challenge")
let challenge1_1 = try XCTUnwrap(challenges1.first)
XCTAssertEqual(challenge1_1.authScheme, "Basic")
XCTAssertEqual(challenge1_1.authParameters.count, 3, "Wrong number of parameters in challenge")
let param1_1_1 = try XCTUnwrap(challenge1_1.parameter(withName: "realm"))
XCTAssertEqual(param1_1_1.name, "Realm")
XCTAssertEqual(param1_1_1.value, "Test")
let param1_1_2 = try XCTUnwrap(challenge1_1.parameter(withName: "chaRSet"))
XCTAssertEqual(param1_1_2.name, "charset")
XCTAssertEqual(param1_1_2.value, "utf-8")
let param1_1_3 = try XCTUnwrap(challenge1_1.parameter(withName: "OTHER"))
XCTAssertEqual(param1_1_3.name, "other")
XCTAssertEqual(param1_1_3.value, "be2e96ad8ab8acb7ccfb49bc7e162914")
// Several challenges, but only two of them should be valid
let challenges2 = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "Digest realm=\"Unsupported\", Basic, basic realm = \"First \\\" realm\", Basic realm=\"Second realm\"")
XCTAssertEqual(challenges2.count, 2, "String contains 2 valid challenges")
let challenge2_1 = try XCTUnwrap(challenges2.first)
XCTAssertEqual(challenge2_1.authScheme, "basic")
XCTAssertEqual(challenge2_1.authParameters.count, 1, "Wrong number of parameters in challenge")
let param2_1_1 = try XCTUnwrap(challenge2_1.parameter(withName: "realm"))
XCTAssertEqual(param2_1_1.name, "realm")
XCTAssertEqual(param2_1_1.value, "First \" realm") // contains escaped quote
let challenge2_2 = try XCTUnwrap(challenges2.last)
XCTAssertEqual(challenge2_2.authScheme, "Basic")
XCTAssertEqual(challenge2_2.authParameters.count, 1, "Wrong number of parameters in challenge")
let param2_2_1 = try XCTUnwrap(challenge2_2.parameter(withName: "realm"))
XCTAssertEqual(param2_2_1.name, "realm")
XCTAssertEqual(param2_2_1.value, "Second realm")
// Some tricky and broken strings to test edge cases in parse process
let challenges3 = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "not real, Basic realm=\"Second realm\"")
XCTAssertEqual(challenges3.count, 1, "String contains 1 valid challenge")
let challenges4 = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "Basic realm=\"Second realm\"charset=")
XCTAssertEqual(challenges4.count, 1, "String contains 1 valid challenge")
let challenge4_1 = try XCTUnwrap(challenges4.first)
XCTAssertEqual(challenge4_1.authScheme, "Basic")
XCTAssertEqual(challenge4_1.authParameters.count, 1, "Wrong number of parameters in challenge")
let param4_1_1 = try XCTUnwrap(challenge4_1.parameter(withName: "realm"))
XCTAssertEqual(param4_1_1.name, "realm")
XCTAssertEqual(param4_1_1.value, "Second realm")
let challenges5 = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "Basic reALm = \"Second realm\",charset=")
XCTAssertEqual(challenges5.count, 1, "String contains 1 valid challenge")
let challenge5_1 = try XCTUnwrap(challenges5.first)
XCTAssertEqual(challenge5_1.authScheme, "Basic")
XCTAssertEqual(challenge5_1.authParameters.count, 1, "Wrong number of parameters in challenge")
let param5_1_1 = try XCTUnwrap(challenge5_1.parameter(withName: "realm"))
XCTAssertEqual(param5_1_1.name, "reALm")
XCTAssertEqual(param5_1_1.value, "Second realm")
let challenges6 = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "Basic realm=\"Broken realm")
XCTAssertTrue(challenges6.isEmpty, "String doesn't contains a valid challenge")
let challenges7 = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "Basic charset=\"utf-8\"")
XCTAssertTrue(challenges7.isEmpty, "String doesn't contains a valid challenge")
let challenges8 = _HTTPURLProtocol._HTTPMessage._Challenge.challenges(from: "Basic realm=\"Oh no,basic REALM=\"World's okayest realm\", param=\"\"")
XCTAssertEqual(challenges8.count, 2, "String contains 2 valid challenge")
let challenge8_1 = try XCTUnwrap(challenges8.first)
XCTAssertEqual(challenge8_1.authScheme, "Basic")
XCTAssertEqual(challenge8_1.authParameters.count, 1, "Wrong number of parameters in challenge")
let param8_1_1 = try XCTUnwrap(challenge8_1.parameter(withName: "realm"))
XCTAssertEqual(param8_1_1.name, "realm")
XCTAssertEqual(param8_1_1.value, "Oh no,basic REALM=")
let challenge8_2 = try XCTUnwrap(challenges8.last)
XCTAssertEqual(challenge8_2.authScheme, "basic")
XCTAssertEqual(challenge8_2.authParameters.count, 2, "Wrong number of parameters in challenge")
let param8_2_1 = try XCTUnwrap(challenge8_2.parameter(withName: "realm"))
XCTAssertEqual(param8_2_1.name, "REALM")
XCTAssertEqual(param8_2_1.value, "World's okayest realm")
let param8_2_2 = try XCTUnwrap(challenge8_2.parameter(withName: "param"))
XCTAssertEqual(param8_2_2.name, "param")
XCTAssertEqual(param8_2_2.value, "")
}
func test_createWithInvalidAuth() throws {
let headerFields1 = [
"Server": "Microsoft-IIS/10.0",
"request-id": "c71c2202-4013-4d64-9319-d40aba6bbe5c",
"WWW-Authenticate": "fdsfds",
"X-Powered-By": "ASP.NET",
"X-FEServer": "AM6PR0502CA0062",
"Date": "Sat, 04 Apr 2020 16:19:39 GMT",
"Content-Length": "0",
]
let response1 = try XCTUnwrap(HTTPURLResponse(url: URL(string: "https://outlook.office365.com/Microsoft-Server-ActiveSync")!,
statusCode: 401,
httpVersion: "HTTP/1.1",
headerFields: headerFields1))
XCTAssertNil(URLProtectionSpace.create(with: response1))
}
#endif
}