Some users [are unable to register][1] because the server [returns a 400
error][2] if passed an invalid `Accept-Language` header.
This commit helps prevent two possible error modes:
- Filters out invalid language tags. Some users reported a "Workshopx"
language, which the server would reject because it's syntactically
invalid. Deleting this language (at the OS level) let them register.
- If no languages are valid, we should send `*` instead of the empty
string. There's no evidence that this happened in practice.
In addition, this commit:
- Adds tests.
- Sends a maximum of 10 languages instead of 6.
- Omits the `q` value when it's 1 because [that's the default][3].
- Marginally improves performance by iterating lazily.
[1]: https://github.com/signalapp/Signal-iOS/issues/5261
[2]: bf6d3aa324/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java (L271-L275)
[3]: https://www.rfc-editor.org/rfc/rfc9110.html#section-12.4.2
Co-authored-by: Nora Trapp <nora@signal.org>
48 lines
1.8 KiB
Swift
48 lines
1.8 KiB
Swift
//
|
|
// Copyright (c) 2022 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import SignalServiceKit
|
|
|
|
class OWSHttpHeadersTest: XCTestCase {
|
|
func testFormatAcceptLanguageHeader() throws {
|
|
func chars(_ str: String) -> [String] {
|
|
str.map { String($0) }
|
|
}
|
|
|
|
let testCases: [[String]: String] = [
|
|
[]: "*",
|
|
["invalid!"]: "*",
|
|
["bad1", "bad2", "no_unders", "itstoolong", "en--", "en--us", "en-*stars*", "en-**"]: "*",
|
|
|
|
["en-US"]: "en-US",
|
|
["en-*"]: "en-*",
|
|
["*-US"]: "*-US",
|
|
["*-*"]: "*-*",
|
|
["a-b-c2-d"]: "a-b-c2-d",
|
|
["bad1", "ok", "bad2"]: "ok",
|
|
|
|
// This was an actual string sent from someone's device, so we test that it's ignored.
|
|
["en-US@attribute=isk", "de"]: "de",
|
|
|
|
["a", "b", "c"]: "a, b;q=0.9, c;q=0.8",
|
|
["a", "b", "bad123", "c"]: "a, b;q=0.9, c;q=0.8",
|
|
chars("abcdefghij"): "a, b;q=0.9, c;q=0.8, d;q=0.7, e;q=0.6, f;q=0.5, g;q=0.4, h;q=0.3, i;q=0.2, j;q=0.1",
|
|
chars("abcdefghijklmnopqrst"): "a, b;q=0.9, c;q=0.8, d;q=0.7, e;q=0.6, f;q=0.5, g;q=0.4, h;q=0.3, i;q=0.2, j;q=0.1",
|
|
chars("a!b@c#d$e%f^g&h(i)j_"): "a, b;q=0.9, c;q=0.8, d;q=0.7, e;q=0.6, f;q=0.5, g;q=0.4, h;q=0.3, i;q=0.2, j;q=0.1"
|
|
]
|
|
|
|
for (languages, expected) in testCases {
|
|
let actual = OWSHttpHeaders.formatAcceptLanguageHeader(languages)
|
|
XCTAssertEqual(actual, expected, "Input: \(languages)")
|
|
}
|
|
}
|
|
|
|
func testAcceptLanguageHeaderValue() throws {
|
|
let expected = OWSHttpHeaders.formatAcceptLanguageHeader(Locale.preferredLanguages)
|
|
let actual = OWSHttpHeaders.acceptLanguageHeaderValue
|
|
XCTAssertEqual(actual, expected)
|
|
}
|
|
}
|