Skip to content

Commit 3bebe58

Browse files
committed
Make String(utf8Slice:from:) less ugly
1 parent 273ebad commit 3bebe58

File tree

1 file changed

+19
-21
lines changed

1 file changed

+19
-21
lines changed

Sources/AsyncHTTPClient/HTTPClient+HTTPCookie.swift

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ extension HTTPClient {
5757
guard !trimmedName.isEmpty else {
5858
return nil
5959
}
60+
6061
// FIXME: The parsed values should be validated to ensure they only contain ASCII characters allowed by RFC-6265.
6162
// https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1
62-
self.name = String(utf8Slice: trimmedName, in: header)
63-
self.value = String(utf8Slice: trimmedValue.trimmingPairedASCIIQuote(), in: header)
63+
self.name = String(aligningUTF8: trimmedName)
64+
self.value = String(aligningUTF8: trimmedValue.trimmingPairedASCIIQuote())
6465
self.path = "/"
6566
self.domain = defaultDomain
6667
self.expires_timestamp = nil
@@ -71,11 +72,11 @@ extension HTTPClient {
7172
for component in components {
7273
switch component.parseCookieComponent() {
7374
case ("path", .some(let value))?:
74-
self.path = String(utf8Slice: value, in: header)
75+
self.path = String(aligningUTF8: value)
7576
case ("domain", .some(let value))?:
76-
self.domain = String(utf8Slice: value, in: header)
77+
self.domain = String(aligningUTF8: value)
7778
case ("expires", .some(let value))?:
78-
self.expires_timestamp = parseCookieTime(value, in: header)
79+
self.expires_timestamp = parseCookieTime(value)
7980
case ("max-age", .some(let value))?:
8081
self.maxAge = Int(Substring(value))
8182
case ("secure", nil)?:
@@ -121,8 +122,8 @@ extension HTTPClient.Response {
121122

122123
extension String {
123124
/// Creates a String from a slice of UTF8 code-units, aligning the bounds to unicode scalar boundaries if needed.
124-
fileprivate init(utf8Slice: String.UTF8View.SubSequence, in base: String) {
125-
self.init(base[utf8Slice.startIndex..<utf8Slice.endIndex])
125+
fileprivate init(aligningUTF8 utf8Slice: String.UTF8View.SubSequence) {
126+
self.init(Substring(utf8Slice))
126127
}
127128
}
128129

@@ -176,33 +177,30 @@ private let posixLocale: UnsafeMutableRawPointer = {
176177
return UnsafeMutableRawPointer(_posixLocale)
177178
}()
178179

179-
private func parseTimestamp(_ string: String, format: String) -> tm? {
180+
private func parseTimestamp(_ utf8: String.UTF8View.SubSequence, format: String) -> tm? {
180181
var timeComponents = tm()
181-
guard swiftahc_cshims_strptime_l(string, format, &timeComponents, posixLocale) else {
182-
return nil
182+
let success = Substring(utf8).withCString { cString in
183+
swiftahc_cshims_strptime_l(cString, format, &timeComponents, posixLocale)
183184
}
184-
return timeComponents
185+
return success ? timeComponents : nil
185186
}
186187

187-
private func parseCookieTime(_ timestampUTF8: String.UTF8View.SubSequence, in header: String) -> Int64? {
188+
private func parseCookieTime(_ timestampUTF8: String.UTF8View.SubSequence) -> Int64? {
188189
if timestampUTF8.contains(where: { $0 < 0x20 /* Control characters */ || $0 == 0x7F /* DEL */ }) {
189190
return nil
190191
}
191-
let timestampString: String
192+
var timestampUTF8 = timestampUTF8
192193
if timestampUTF8.hasSuffix("GMT".utf8) {
193194
let timezoneStart = timestampUTF8.index(timestampUTF8.endIndex, offsetBy: -3)
194-
let trimmedTimestampUTF8 = timestampUTF8[..<timezoneStart].trimmingASCIISpaces()
195-
guard trimmedTimestampUTF8.endIndex != timezoneStart else {
195+
timestampUTF8 = timestampUTF8[..<timezoneStart].trimmingASCIISpaces()
196+
guard timestampUTF8.endIndex != timezoneStart else {
196197
return nil
197198
}
198-
timestampString = String(utf8Slice: trimmedTimestampUTF8, in: header)
199-
} else {
200-
timestampString = String(utf8Slice: timestampUTF8, in: header)
201199
}
202200
guard
203-
var timeComponents = parseTimestamp(timestampString, format: "%a, %d %b %Y %H:%M:%S")
204-
?? parseTimestamp(timestampString, format: "%a, %d-%b-%y %H:%M:%S")
205-
?? parseTimestamp(timestampString, format: "%a %b %d %H:%M:%S %Y")
201+
var timeComponents = parseTimestamp(timestampUTF8, format: "%a, %d %b %Y %H:%M:%S")
202+
?? parseTimestamp(timestampUTF8, format: "%a, %d-%b-%y %H:%M:%S")
203+
?? parseTimestamp(timestampUTF8, format: "%a %b %d %H:%M:%S %Y")
206204
else {
207205
return nil
208206
}

0 commit comments

Comments
 (0)