Skip to content

Commit bcff7a2

Browse files
committed
Validate response status codes (Fixes #1)
1 parent 16f1e7d commit bcff7a2

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

FastImage/FastImage.swift

+25
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public struct UnsupportedImageError: Error {
1818
public let data: Data
1919
}
2020

21+
public struct InvalidStatusCodeError: Error {
22+
public let statusCode: Int
23+
}
24+
2125
/// FastImage is an Swift port of the Ruby project by Stephen Sykes. It's directive is too
2226
/// request as little data as possible (usually just the first batch of bytes returned by a request),
2327
/// to determine the size and type of a remote image.
@@ -124,6 +128,21 @@ public final class FastImage: NSObject {
124128
// Not enough data
125129
}
126130
}
131+
132+
private func validate(request: Request) -> Bool {
133+
if let response = request.task.response as? HTTPURLResponse {
134+
if !(200..<300).contains(response.statusCode) {
135+
// Validate that the status code returned is a success code, otherwise fail
136+
request.completion(.failure(InvalidStatusCodeError(statusCode: response.statusCode)))
137+
if let urlString = request.task.originalRequest?.url?.absoluteString {
138+
requests.removeValue(forKey: urlString)
139+
}
140+
request.task.cancel()
141+
return false
142+
}
143+
}
144+
return true
145+
}
127146
}
128147

129148
extension FastImage: URLSessionDataDelegate {
@@ -132,6 +151,9 @@ extension FastImage: URLSessionDataDelegate {
132151
let request = requests[urlString] else {
133152
return
134153
}
154+
if !validate(request: request) {
155+
return
156+
}
135157
request.data.append(data)
136158
if (!request.data.isEmpty) {
137159
parse(request: request)
@@ -145,6 +167,9 @@ extension FastImage: URLSessionDataDelegate {
145167
let request = requests[urlString] else {
146168
return
147169
}
170+
if !validate(request: request) {
171+
return
172+
}
148173
request.completion(.failure(error ?? SizeNotFoundError(data: request.data)))
149174
requests.removeValue(forKey: urlString)
150175
}

FastImageTests/FastImageTests.swift

+17
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,21 @@ class FastImageTests: XCTestCase {
161161
})
162162
waitForExpectations(timeout: fastImage.requestTimeout + 2.0)
163163
}
164+
165+
func testInvalidStatusCode() {
166+
let e = expectation(description: "Invalid Status Code")
167+
let url = URL(string: "https://httpbin.org/status/403")!
168+
fastImage.imageSizeAndType(for: url) { result in
169+
switch result {
170+
case .success(_):
171+
XCTFail()
172+
case .failure(let error as InvalidStatusCodeError):
173+
XCTAssertEqual(error.statusCode, 403)
174+
case .failure(let error):
175+
XCTFail("Expected InvalidStatusCodeError, but received \(error)")
176+
}
177+
e.fulfill()
178+
}
179+
waitForExpectations(timeout: fastImage.requestTimeout + 2.0)
180+
}
164181
}

0 commit comments

Comments
 (0)