From 1657b925ef11fda52169e9a00236335e0c0988c5 Mon Sep 17 00:00:00 2001 From: km2023 Date: Thu, 4 Jun 2026 10:51:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(sdk):=20=E6=B7=BB=E5=8A=A0=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F=E5=86=99=E4=B8=8D=E6=95=8F=E6=84=9F=E7=9A=84=20HTTP?= =?UTF-8?q?=20=E5=93=8D=E5=BA=94=E5=A4=B4=E8=AF=BB=E5=8F=96=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DuooomiBleSDK+Transfer.swift | 6 +++--- .../Utils/BeijingTimeProvider.swift | 2 +- .../Utils/HTTPURLResponse+Header.swift | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 Sources/DuooomiBleSDK/Utils/HTTPURLResponse+Header.swift diff --git a/Sources/DuooomiBleSDK/DuooomiBleSDK+Transfer.swift b/Sources/DuooomiBleSDK/DuooomiBleSDK+Transfer.swift index ec4d26a..c035745 100644 --- a/Sources/DuooomiBleSDK/DuooomiBleSDK+Transfer.swift +++ b/Sources/DuooomiBleSDK/DuooomiBleSDK+Transfer.swift @@ -154,7 +154,7 @@ extension DuooomiBleSDK { completion(.failure(DuooomiBleError.transferFailed("Format check failed: \(error.localizedDescription)"))) return } - guard let mime = (response as? HTTPURLResponse)?.allHeaderFields["Content-Type"] as? String else { + guard let mime = (response as? HTTPURLResponse)?.headerValue(caseInsensitive: "Content-Type") else { completion(.failure(DuooomiBleError.unsupportedFormat("unknown"))) return } @@ -183,7 +183,7 @@ extension DuooomiBleSDK { } if let http = response as? HTTPURLResponse { - if let lengthStr = http.allHeaderFields["Content-Length"] as? String, + if let lengthStr = http.headerValue(caseInsensitive: "Content-Length"), let length = Int(lengthStr), length > 0 { completion(.success(length)) return @@ -209,7 +209,7 @@ extension DuooomiBleSDK { return } if let http = response as? HTTPURLResponse, - let rangeHeader = http.allHeaderFields["Content-Range"] as? String, + let rangeHeader = http.headerValue(caseInsensitive: "Content-Range"), let totalStr = rangeHeader.split(separator: "/").last, let total = Int(totalStr), total > 0 { completion(.success(total)) diff --git a/Sources/DuooomiBleSDK/Utils/BeijingTimeProvider.swift b/Sources/DuooomiBleSDK/Utils/BeijingTimeProvider.swift index 6232331..a035add 100644 --- a/Sources/DuooomiBleSDK/Utils/BeijingTimeProvider.swift +++ b/Sources/DuooomiBleSDK/Utils/BeijingTimeProvider.swift @@ -69,7 +69,7 @@ final class BeijingTimeProvider { } if let http = resp as? HTTPURLResponse, - let dateHeader = (http.allHeaderFields["Date"] ?? http.allHeaderFields["date"]) as? String, + let dateHeader = http.headerValue(caseInsensitive: "Date"), let value = self.formatHTTPDateHeader(dateHeader) { done(value) return diff --git a/Sources/DuooomiBleSDK/Utils/HTTPURLResponse+Header.swift b/Sources/DuooomiBleSDK/Utils/HTTPURLResponse+Header.swift new file mode 100644 index 0000000..9c56318 --- /dev/null +++ b/Sources/DuooomiBleSDK/Utils/HTTPURLResponse+Header.swift @@ -0,0 +1,19 @@ +import Foundation + +extension HTTPURLResponse { + /// 大小写不敏感地读取 HTTP 响应头。 + /// + /// HTTP/2(RFC 7540 §8.1.2)强制把头字段名小写(如 `content-length`),而 + /// `allHeaderFields` 的字典下标是大小写敏感精确匹配,直接用 `["Content-Length"]` + /// 在 HTTP/2 响应下会取不到值。系统的 `value(forHTTPHeaderField:)` 能规避,但要求 + /// iOS 13+,本 SDK 最低支持 iOS 12,故手动遍历比较。 + func headerValue(caseInsensitive name: String) -> String? { + for (key, value) in allHeaderFields { + if let keyStr = key as? String, + keyStr.caseInsensitiveCompare(name) == .orderedSame { + return value as? String + } + } + return nil + } +}