Skip to content

Commit 9d087d0

Browse files
committed
Update NSURLResponse / NSHTTPURLResponse
from daniel/httpurlresponse
1 parent 46d9ed2 commit 9d087d0

File tree

2 files changed

+58
-43
lines changed

2 files changed

+58
-43
lines changed

Foundation/NSURLResponse.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public class NSURLResponse : NSObject, NSSecureCoding, NSCopying {
5757
self.MIMEType = MIMEType
5858
self.expectedContentLength = Int64(length)
5959
self.textEncodingName = name
60-
self.suggestedFilename = nil
60+
let c = URL.lastPathComponent
61+
self.suggestedFilename = (c?.isEmpty ?? true) ? "Unknown" : c
6162
}
6263

6364
/*!
@@ -149,10 +150,10 @@ public class NSHTTPURLResponse : NSURLResponse {
149150
self.allHeaderFields = headerFields ?? [:]
150151
super.init(URL: url, MIMEType: nil, expectedContentLength: 0, textEncodingName: nil)
151152
expectedContentLength = expectedContentLengthFromHeaderFields(headerFields) ?? -1
152-
suggestedFilename = suggestedFilenameFromHeaderFields(headerFields)
153+
suggestedFilename = suggestedFilenameFromHeaderFields(headerFields) ?? "Unknown"
153154
if let type = ContentTypeComponents(headerFields: headerFields) {
154-
MIMEType = type.MIMEType
155-
textEncodingName = type.textEncoding
155+
MIMEType = type.MIMEType.lowercased()
156+
textEncodingName = type.textEncoding?.lowercased()
156157
}
157158
}
158159

@@ -211,10 +212,6 @@ private func expectedContentLengthFromHeaderFields(headerFields: [String : Strin
211212
let contentLengthS = valueForCaseInsensitiveKey("content-length", fields: f),
212213
let contentLength = Int64(contentLengthS)
213214
else { return nil }
214-
let contentEncoding = valueForCaseInsensitiveKey("content-encoding", fields: f)
215-
let transferEncoding = valueForCaseInsensitiveKey("transfer-encoding", fields: f)
216-
guard (contentEncoding == nil) || (contentEncoding == "identity") else { return nil }
217-
guard (transferEncoding == nil) || (transferEncoding == "identity") else { return nil }
218215
return contentLength
219216
}
220217
/// Parses the suggested filename from the `Content-Disposition` header.
@@ -229,7 +226,7 @@ private func suggestedFilenameFromHeaderFields(headerFields: [String : String]?)
229226
let field = contentDisposition.httpHeaderParts
230227
else { return nil }
231228
for part in field.parameters where part.attribute == "filename" {
232-
return part.value?.lastPathComponent
229+
return part.value?.pathComponents.map{ $0 == "/" ? "" : $0}.joined(separator: "_")
233230
}
234231
return nil
235232
}

TestFoundation/TestNSURLResponse.swift

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ class TestNSURLResponse : XCTestCase {
2121
static var allTests: [(String, TestNSURLResponse -> () throws -> Void)] {
2222
return [
2323
("test_URL", test_URL),
24-
("test_MIMEType", test_MIMEType),
24+
("test_MIMEType_1", test_MIMEType_1),
25+
("test_MIMEType_2", test_MIMEType_2),
2526
("test_ExpectedContentLength", test_ExpectedContentLength),
2627
("test_TextEncodingName", test_TextEncodingName),
2728
("test_suggestedFilename", test_suggestedFilename),
29+
("test_suggestedFilename_2", test_suggestedFilename_2),
30+
("test_suggestedFilename_3", test_suggestedFilename_3),
2831
]
2932
}
3033

@@ -34,15 +37,18 @@ class TestNSURLResponse : XCTestCase {
3437
XCTAssertEqual(res.URL, url, "should be the expected url")
3538
}
3639

37-
func test_MIMEType() {
38-
let mimetype1 = "text/plain"
39-
let mimetype2 = "application/wordperfect"
40-
let res1 = NSURLResponse(URL: NSURL(string: "test")!, MIMEType: mimetype1, expectedContentLength: 0, textEncodingName: nil)
41-
XCTAssertEqual(res1.MIMEType, mimetype1, "should be the passed in mimetype")
42-
let res2 = NSURLResponse(URL: NSURL(string: "test")!, MIMEType: mimetype2, expectedContentLength: 0, textEncodingName: nil)
43-
XCTAssertEqual(res2.MIMEType, mimetype2, "should be the other mimetype")
40+
func test_MIMEType_1() {
41+
let mimetype = "text/plain"
42+
let res = NSURLResponse(URL: NSURL(string: "test")!, MIMEType: mimetype, expectedContentLength: 0, textEncodingName: nil)
43+
XCTAssertEqual(res.MIMEType, mimetype, "should be the passed in mimetype")
4444
}
4545

46+
func test_MIMEType_2() {
47+
let mimetype = "APPlication/wordperFECT"
48+
let res = NSURLResponse(URL: NSURL(string: "test")!, MIMEType: mimetype, expectedContentLength: 0, textEncodingName: nil)
49+
XCTAssertEqual(res.MIMEType, mimetype, "should be the other mimetype")
50+
}
51+
4652
func test_ExpectedContentLength() {
4753
let zeroContentLength = 0
4854
let positiveContentLength = 100
@@ -63,9 +69,21 @@ class TestNSURLResponse : XCTestCase {
6369
}
6470

6571
func test_suggestedFilename() {
66-
let url = NSURL(string: "a/test/path")!
72+
let url = NSURL(string: "a/test/name.extension")!
73+
let res = NSURLResponse(URL: url, MIMEType: "txt", expectedContentLength: 0, textEncodingName: nil)
74+
XCTAssertEqual(res.suggestedFilename, "name.extension")
75+
}
76+
77+
func test_suggestedFilename_2() {
78+
let url = NSURL(string: "a/test/name.extension?foo=bar")!
6779
let res = NSURLResponse(URL: url, MIMEType: "txt", expectedContentLength: 0, textEncodingName: nil)
68-
XCTAssertNil(res.suggestedFilename)
80+
XCTAssertEqual(res.suggestedFilename, "name.extension")
81+
}
82+
83+
func test_suggestedFilename_3() {
84+
let url = NSURL(string: "a://bar")!
85+
let res = NSURLResponse(URL: url, MIMEType: "txt", expectedContentLength: 0, textEncodingName: nil)
86+
XCTAssertEqual(res.suggestedFilename, "Unknown")
6987
}
7088
}
7189

@@ -84,20 +102,20 @@ class TestNSHTTPURLResponse : XCTestCase {
84102
("test_contentLength_available_2", test_contentLength_available_2),
85103
("test_contentLength_available_3", test_contentLength_available_3),
86104
("test_contentLength_available_4", test_contentLength_available_4),
87-
("test_contentLength_notAvailable_1", test_contentLength_notAvailable_1),
88-
("test_contentLength_notAvailable_2", test_contentLength_notAvailable_2),
89-
("test_contentLength_notAvailable_3", test_contentLength_notAvailable_3),
90-
("test_contentLength_notAvailable_4", test_contentLength_notAvailable_4),
91-
("test_contentLength_notAvailable_5", test_contentLength_notAvailable_5),
105+
("test_contentLength_notAvailable", test_contentLength_notAvailable),
106+
("test_contentLength_withTransferEncoding", test_contentLength_withTransferEncoding),
107+
("test_contentLength_withContentEncoding", test_contentLength_withContentEncoding),
108+
("test_contentLength_withContentEncodingAndTransferEncoding", test_contentLength_withContentEncodingAndTransferEncoding),
109+
("test_contentLength_withContentEncodingAndTransferEncoding_2", test_contentLength_withContentEncodingAndTransferEncoding_2),
92110

93111
("test_suggestedFilename_notAvailable_1", test_suggestedFilename_notAvailable_1),
94112
("test_suggestedFilename_notAvailable_2", test_suggestedFilename_notAvailable_2),
95113
("test_suggestedFilename_1", test_suggestedFilename_1),
96114
("test_suggestedFilename_2", test_suggestedFilename_2),
97115
("test_suggestedFilename_3", test_suggestedFilename_3),
98116
("test_suggestedFilename_4", test_suggestedFilename_4),
99-
("test_suggestedFilename_onlyTheLastPathComponent_1", test_suggestedFilename_onlyTheLastPathComponent_1),
100-
("test_suggestedFilename_onlyTheLastPathComponent_2", test_suggestedFilename_onlyTheLastPathComponent_2),
117+
("test_suggestedFilename_removeSlashes_1", test_suggestedFilename_removeSlashes_1),
118+
("test_suggestedFilename_removeSlashes_2", test_suggestedFilename_removeSlashes_2),
101119

102120
("test_MIMETypeAndCharacterEncoding_1", test_MIMETypeAndCharacterEncoding_1),
103121
("test_MIMETypeAndCharacterEncoding_2", test_MIMETypeAndCharacterEncoding_2),
@@ -164,30 +182,30 @@ class TestNSHTTPURLResponse : XCTestCase {
164182
XCTAssertEqual(sut?.expectedContentLength, 997)
165183
}
166184

167-
func test_contentLength_notAvailable_1() {
185+
func test_contentLength_notAvailable() {
168186
let f = ["Server": "Apache"]
169187
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
170188
XCTAssertEqual(sut?.expectedContentLength, -1)
171189
}
172-
func test_contentLength_notAvailable_2() {
190+
func test_contentLength_withTransferEncoding() {
173191
let f = ["Content-Length": "997", "Transfer-Encoding": "chunked"]
174192
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
175-
XCTAssertEqual(sut?.expectedContentLength, -1)
193+
XCTAssertEqual(sut?.expectedContentLength, 997)
176194
}
177-
func test_contentLength_notAvailable_3() {
195+
func test_contentLength_withContentEncoding() {
178196
let f = ["Content-Length": "997", "Content-Encoding": "deflate"]
179197
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
180-
XCTAssertEqual(sut?.expectedContentLength, -1)
198+
XCTAssertEqual(sut?.expectedContentLength, 997)
181199
}
182-
func test_contentLength_notAvailable_4() {
200+
func test_contentLength_withContentEncodingAndTransferEncoding() {
183201
let f = ["Content-Length": "997", "Content-Encoding": "deflate", "Transfer-Encoding": "identity"]
184202
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
185-
XCTAssertEqual(sut?.expectedContentLength, -1)
203+
XCTAssertEqual(sut?.expectedContentLength, 997)
186204
}
187-
func test_contentLength_notAvailable_5() {
205+
func test_contentLength_withContentEncodingAndTransferEncoding_2() {
188206
let f = ["Content-Length": "997", "Content-Encoding": "identity", "Transfer-Encoding": "chunked"]
189207
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
190-
XCTAssertEqual(sut?.expectedContentLength, -1)
208+
XCTAssertEqual(sut?.expectedContentLength, 997)
191209
}
192210

193211
// The `suggestedFilename` can be derived from the "Content-Disposition"
@@ -206,12 +224,12 @@ class TestNSHTTPURLResponse : XCTestCase {
206224
func test_suggestedFilename_notAvailable_1() {
207225
let f: [String: String] = [:]
208226
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
209-
XCTAssertNil(sut?.suggestedFilename)
227+
XCTAssertEqual(sut?.suggestedFilename, "Unknown")
210228
}
211229
func test_suggestedFilename_notAvailable_2() {
212230
let f = ["Content-Disposition": "inline"]
213231
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
214-
XCTAssertNil(sut?.suggestedFilename)
232+
XCTAssertEqual(sut?.suggestedFilename, "Unknown")
215233
}
216234

217235
func test_suggestedFilename_1() {
@@ -234,15 +252,15 @@ class TestNSHTTPURLResponse : XCTestCase {
234252
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
235253
XCTAssertEqual(sut?.suggestedFilename, "fname.ext")
236254
}
237-
func test_suggestedFilename_onlyTheLastPathComponent_1() {
255+
func test_suggestedFilename_removeSlashes_1() {
238256
let f = ["Content-Disposition": "attachment; filename=\"/a/b/name\""]
239257
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
240-
XCTAssertEqual(sut?.suggestedFilename, "name")
258+
XCTAssertEqual(sut?.suggestedFilename, "_a_b_name")
241259
}
242-
func test_suggestedFilename_onlyTheLastPathComponent_2() {
260+
func test_suggestedFilename_removeSlashes_2() {
243261
let f = ["Content-Disposition": "attachment; filename=\"a/../b/name\""]
244262
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
245-
XCTAssertEqual(sut?.suggestedFilename, "name")
263+
XCTAssertEqual(sut?.suggestedFilename, "a_.._b_name")
246264
}
247265

248266
// The MIME type / character encoding
@@ -260,9 +278,9 @@ class TestNSHTTPURLResponse : XCTestCase {
260278
XCTAssertNil(sut?.textEncodingName)
261279
}
262280
func test_MIMETypeAndCharacterEncoding_3() {
263-
let f = ["Content-Type": "text/html; charset=ISO-8859-4"]
281+
let f = ["Content-Type": "text/HTML; charset=ISO-8859-4"]
264282
let sut = NSHTTPURLResponse(URL: url, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: f)
265283
XCTAssertEqual(sut?.MIMEType, "text/html")
266-
XCTAssertEqual(sut?.textEncodingName, "ISO-8859-4")
284+
XCTAssertEqual(sut?.textEncodingName, "iso-8859-4")
267285
}
268286
}

0 commit comments

Comments
 (0)