зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1677086 - Parse SvcParamKeyAlpn as defined in spec r=necko-reviewers,valentin
Differential Revision: https://phabricator.services.mozilla.com/D97000
This commit is contained in:
Родитель
4e5d703a9d
Коммит
2e58759c35
|
@ -376,9 +376,15 @@ nsresult LookupHelper::ConstructHTTPSRRAnswer(LookupArgument* aArgument) {
|
|||
nextRecord->mAlpn.Construct();
|
||||
nextRecord->mAlpn.Value().mType = type;
|
||||
nsCOMPtr<nsISVCParamAlpn> alpnParam = do_QueryInterface(value);
|
||||
nsCString alpnStr;
|
||||
Unused << alpnParam->GetAlpn(alpnStr);
|
||||
CopyASCIItoUTF16(alpnStr, nextRecord->mAlpn.Value().mAlpn);
|
||||
nsTArray<nsCString> alpn;
|
||||
Unused << alpnParam->GetAlpn(alpn);
|
||||
nsAutoCString alpnStr;
|
||||
for (const auto& str : alpn) {
|
||||
alpnStr.Append(str);
|
||||
alpnStr.Append(',');
|
||||
}
|
||||
CopyASCIItoUTF16(Span(alpnStr.BeginReading(), alpnStr.Length() - 1),
|
||||
nextRecord->mAlpn.Value().mAlpn);
|
||||
break;
|
||||
}
|
||||
case SvcParamKeyNoDefaultAlpn: {
|
||||
|
|
|
@ -67,12 +67,12 @@ SvcParam::GetType(uint16_t* aType) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SvcParam::GetAlpn(nsACString& aAlpn) {
|
||||
SvcParam::GetAlpn(nsTArray<nsCString>& aAlpn) {
|
||||
if (!mValue.is<SvcParamAlpn>()) {
|
||||
MOZ_ASSERT(false, "Unexpected type for variant");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
aAlpn = mValue.as<SvcParamAlpn>().mValue;
|
||||
aAlpn.AppendElements(mValue.as<SvcParamAlpn>().mValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -172,13 +172,13 @@ bool SVCB::NoDefaultAlpn() const {
|
|||
Maybe<Tuple<nsCString, bool>> SVCB::GetAlpn(bool aNoHttp2,
|
||||
bool aNoHttp3) const {
|
||||
Maybe<Tuple<nsCString, bool>> alpn;
|
||||
nsAutoCString alpnValue;
|
||||
for (const auto& value : mSvcFieldValue) {
|
||||
if (value.mValue.is<SvcParamAlpn>()) {
|
||||
alpn.emplace();
|
||||
alpnValue = value.mValue.as<SvcParamAlpn>().mValue;
|
||||
if (!alpnValue.IsEmpty()) {
|
||||
alpn = Some(SelectAlpnFromAlpnList(alpnValue, aNoHttp2, aNoHttp3));
|
||||
nsTArray<nsCString> alpnList;
|
||||
alpnList.AppendElements(value.mValue.as<SvcParamAlpn>().mValue);
|
||||
if (!alpnList.IsEmpty()) {
|
||||
alpn.emplace();
|
||||
alpn = Some(SelectAlpnFromAlpnList(alpnList, aNoHttp2, aNoHttp3));
|
||||
}
|
||||
return alpn;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ struct SvcParamAlpn {
|
|||
bool operator==(const SvcParamAlpn& aOther) const {
|
||||
return mValue == aOther.mValue;
|
||||
}
|
||||
nsCString mValue;
|
||||
CopyableTArray<nsCString> mValue;
|
||||
};
|
||||
|
||||
struct SvcParamNoDefaultAlpn {
|
||||
|
|
|
@ -1399,8 +1399,20 @@ nsresult TRR::ParseSvcParam(unsigned int svcbIndex, uint16_t key,
|
|||
break;
|
||||
}
|
||||
case SvcParamKeyAlpn: {
|
||||
field.mValue = AsVariant(SvcParamAlpn{
|
||||
.mValue = nsCString((const char*)(&mResponse[svcbIndex]), length)});
|
||||
field.mValue = AsVariant(SvcParamAlpn());
|
||||
auto& alpnArray = field.mValue.as<SvcParamAlpn>().mValue;
|
||||
while (length > 0) {
|
||||
uint8_t alpnIdLength = mResponse[svcbIndex++];
|
||||
length -= 1;
|
||||
if (alpnIdLength > length) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
alpnArray.AppendElement(
|
||||
nsCString((const char*)&mResponse[svcbIndex], alpnIdLength));
|
||||
length -= alpnIdLength;
|
||||
svcbIndex += alpnIdLength;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SvcParamKeyNoDefaultAlpn: {
|
||||
|
|
|
@ -60,7 +60,7 @@ interface nsISVCParam : nsISupports {
|
|||
|
||||
[scriptable, uuid(0dc58309-4d67-4fc4-a4e3-38dbde9d9f4c)]
|
||||
interface nsISVCParamAlpn : nsISupports {
|
||||
readonly attribute ACString alpn;
|
||||
readonly attribute Array<ACString> alpn;
|
||||
};
|
||||
|
||||
[scriptable, uuid(b3ed89c3-2ae6-4c92-8176-b76bc2437fcb)]
|
||||
|
|
|
@ -1003,16 +1003,12 @@ nsresult HttpProxyResponseToErrorCode(uint32_t aStatusCode) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
Tuple<nsCString, bool> SelectAlpnFromAlpnList(const nsACString& aAlpnList,
|
||||
bool aNoHttp2, bool aNoHttp3) {
|
||||
Tuple<nsCString, bool> SelectAlpnFromAlpnList(
|
||||
const nsTArray<nsCString>& aAlpnList, bool aNoHttp2, bool aNoHttp3) {
|
||||
nsCString h3Value;
|
||||
nsCString h2Value;
|
||||
nsCString h1Value;
|
||||
// aAlpnList is a list of alpn-id and use comma as a delimiter.
|
||||
nsCCharSeparatedTokenizer tokenizer(aAlpnList, ',');
|
||||
nsAutoCString npnStr;
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsACString& npnToken(tokenizer.nextToken());
|
||||
for (const auto& npnToken : aAlpnList) {
|
||||
bool isHttp3 = gHttpHandler->IsHttp3VersionSupported(npnToken);
|
||||
if (isHttp3 && h3Value.IsEmpty()) {
|
||||
h3Value.Assign(npnToken);
|
||||
|
|
|
@ -379,8 +379,8 @@ nsresult HttpProxyResponseToErrorCode(uint32_t aStatusCode);
|
|||
// Tuple<alpn-id, isHttp3>. The first element is the alpn-id and the second one
|
||||
// is a boolean to indicate if this alpn-id is for http3. If no supported
|
||||
// alpn-id is found, the first element would be a n empty string.
|
||||
Tuple<nsCString, bool> SelectAlpnFromAlpnList(const nsACString& aAlpnList,
|
||||
bool aNoHttp2, bool aNoHttp3);
|
||||
Tuple<nsCString, bool> SelectAlpnFromAlpnList(
|
||||
const nsTArray<nsCString>& aAlpnList, bool aNoHttp2, bool aNoHttp3);
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -15,38 +15,44 @@ TEST(TestSupportAlpn, testSvcParamKeyAlpn)
|
|||
do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http");
|
||||
|
||||
// h2 and h3 are enabled, so first appearance h3 alpn-id is returned.
|
||||
Tuple<nsCString, bool> result =
|
||||
SelectAlpnFromAlpnList("h3-28,h3-27,h2,http/1.1"_ns, false, false);
|
||||
nsTArray<nsCString> alpn = {"h3-28"_ns, "h3-27"_ns, "h2"_ns, "http/1.1"_ns};
|
||||
Tuple<nsCString, bool> result = SelectAlpnFromAlpnList(alpn, false, false);
|
||||
ASSERT_EQ(Get<0>(result), "h3-28"_ns);
|
||||
ASSERT_EQ(Get<1>(result), true);
|
||||
|
||||
// We don't support h3-26, so we should choose h2.
|
||||
result = SelectAlpnFromAlpnList("h3-26,h2,http/1.1"_ns, false, false);
|
||||
alpn = {"h3-26"_ns, "h2"_ns, "http/1.1"_ns};
|
||||
result = SelectAlpnFromAlpnList(alpn, false, false);
|
||||
ASSERT_EQ(Get<0>(result), "h2"_ns);
|
||||
ASSERT_EQ(Get<1>(result), false);
|
||||
|
||||
// h3 is disabled, so we will use h2.
|
||||
result = SelectAlpnFromAlpnList("h3-28,h3-27,h2,http/1.1"_ns, false, true);
|
||||
alpn = {"h3-28"_ns, "h3-27"_ns, "h2"_ns, "http/1.1"_ns};
|
||||
result = SelectAlpnFromAlpnList(alpn, false, true);
|
||||
ASSERT_EQ(Get<0>(result), "h2"_ns);
|
||||
ASSERT_EQ(Get<1>(result), false);
|
||||
|
||||
// h3 is disabled and h2 is not found, so we will select http/1.1.
|
||||
result = SelectAlpnFromAlpnList("h3-28,h3-27,http/1.1"_ns, false, true);
|
||||
alpn = {"h3-28"_ns, "h3-27"_ns, "http/1.1"_ns};
|
||||
result = SelectAlpnFromAlpnList(alpn, false, true);
|
||||
ASSERT_EQ(Get<0>(result), "http/1.1"_ns);
|
||||
ASSERT_EQ(Get<1>(result), false);
|
||||
|
||||
// h3 and h2 are disabled, so we will select http/1.1.
|
||||
result = SelectAlpnFromAlpnList("h3-28,h3-27,h2,http/1.1"_ns, true, true);
|
||||
alpn = {"h3-28"_ns, "h3-27"_ns, "h2"_ns, "http/1.1"_ns};
|
||||
result = SelectAlpnFromAlpnList(alpn, true, true);
|
||||
ASSERT_EQ(Get<0>(result), "http/1.1"_ns);
|
||||
ASSERT_EQ(Get<1>(result), false);
|
||||
|
||||
// h3 and h2 are disabled and http1.1 is not found, we return an empty string.
|
||||
result = SelectAlpnFromAlpnList("h3-28,h3-27,h2"_ns, true, true);
|
||||
alpn = {"h3-28"_ns, "h3-27"_ns, "h2"_ns};
|
||||
result = SelectAlpnFromAlpnList(alpn, true, true);
|
||||
ASSERT_EQ(Get<0>(result), ""_ns);
|
||||
ASSERT_EQ(Get<1>(result), false);
|
||||
|
||||
// No supported alpn.
|
||||
result = SelectAlpnFromAlpnList("ftp,h2c"_ns, true, true);
|
||||
alpn = {"ftp"_ns, "h2c"_ns};
|
||||
result = SelectAlpnFromAlpnList(alpn, true, true);
|
||||
ASSERT_EQ(Get<0>(result), ""_ns);
|
||||
ASSERT_EQ(Get<1>(result), false);
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ add_task(async function testStoreIPHint() {
|
|||
priority: 1,
|
||||
name: "test.IPHint.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "port", value: 8888 },
|
||||
{ key: "ipv4hint", value: ["1.2.3.4", "5.6.7.8"] },
|
||||
{ key: "ipv6hint", value: ["::1", "fe80::794f:6d2c:3d5e:7836"] },
|
||||
|
@ -156,9 +156,9 @@ add_task(async function testStoreIPHint() {
|
|||
Assert.equal(answer[0].priority, 1);
|
||||
Assert.equal(answer[0].name, "test.IPHint.com");
|
||||
Assert.equal(answer[0].values.length, 4);
|
||||
Assert.equal(
|
||||
Assert.deepEqual(
|
||||
answer[0].values[0].QueryInterface(Ci.nsISVCParamAlpn).alpn,
|
||||
"h2,h3",
|
||||
["h2", "h3"],
|
||||
"got correct answer"
|
||||
);
|
||||
Assert.equal(
|
||||
|
|
|
@ -121,7 +121,7 @@ add_task(async function testPriorityAndECHConfig() {
|
|||
data: {
|
||||
priority: 1,
|
||||
name: "test.p1.com",
|
||||
values: [{ key: "alpn", value: "h2,h3" }],
|
||||
values: [{ key: "alpn", value: ["h2", "h3"] }],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -159,7 +159,7 @@ add_task(async function testFallbackToTheLastRecord() {
|
|||
priority: 1,
|
||||
name: "test.fallback1.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "123..." },
|
||||
],
|
||||
},
|
||||
|
@ -173,7 +173,7 @@ add_task(async function testFallbackToTheLastRecord() {
|
|||
priority: 4,
|
||||
name: "foo.example.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "port", value: h2Port },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
|
@ -188,7 +188,7 @@ add_task(async function testFallbackToTheLastRecord() {
|
|||
priority: 3,
|
||||
name: "test.fallback3.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
@ -202,7 +202,7 @@ add_task(async function testFallbackToTheLastRecord() {
|
|||
priority: 2,
|
||||
name: "test.fallback2.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
@ -262,7 +262,7 @@ add_task(async function testFallbackToTheOrigin() {
|
|||
priority: 1,
|
||||
name: "test.foo1.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "123..." },
|
||||
],
|
||||
},
|
||||
|
@ -276,7 +276,7 @@ add_task(async function testFallbackToTheOrigin() {
|
|||
priority: 3,
|
||||
name: "test.foo3.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
@ -290,7 +290,7 @@ add_task(async function testFallbackToTheOrigin() {
|
|||
priority: 2,
|
||||
name: "test.foo2.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
@ -361,7 +361,7 @@ add_task(async function testAllRecordsFailed() {
|
|||
priority: 1,
|
||||
name: "test.bar1.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "123..." },
|
||||
],
|
||||
},
|
||||
|
@ -375,7 +375,7 @@ add_task(async function testAllRecordsFailed() {
|
|||
priority: 3,
|
||||
name: "test.bar3.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
@ -389,7 +389,7 @@ add_task(async function testAllRecordsFailed() {
|
|||
priority: 2,
|
||||
name: "test.bar2.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
@ -447,7 +447,7 @@ add_task(async function testFallbackToTheOrigin2() {
|
|||
data: {
|
||||
priority: 1,
|
||||
name: "test.example1.com",
|
||||
values: [{ key: "alpn", value: "h2,h3" }],
|
||||
values: [{ key: "alpn", value: ["h2", "h3"] }],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -458,7 +458,7 @@ add_task(async function testFallbackToTheOrigin2() {
|
|||
data: {
|
||||
priority: 3,
|
||||
name: "test.example3.com",
|
||||
values: [{ key: "alpn", value: "h2,h3" }],
|
||||
values: [{ key: "alpn", value: ["h2", "h3"] }],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
@ -539,7 +539,7 @@ add_task(async function testFallbackToTheOrigin3() {
|
|||
priority: 1,
|
||||
name: "vulnerable1.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
@ -553,7 +553,7 @@ add_task(async function testFallbackToTheOrigin3() {
|
|||
priority: 2,
|
||||
name: "vulnerable2.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
@ -566,7 +566,7 @@ add_task(async function testFallbackToTheOrigin3() {
|
|||
data: {
|
||||
priority: 3,
|
||||
name: "vulnerable3.com",
|
||||
values: [{ key: "alpn", value: "h2,h3" }],
|
||||
values: [{ key: "alpn", value: ["h2", "h3"] }],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
@ -624,7 +624,7 @@ add_task(async function testResetExclusionList() {
|
|||
priority: 1,
|
||||
name: "test.reset1.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "port", value: h2Port },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
|
@ -639,7 +639,7 @@ add_task(async function testResetExclusionList() {
|
|||
priority: 2,
|
||||
name: "test.reset2.com",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "echconfig", value: "456..." },
|
||||
],
|
||||
},
|
||||
|
|
|
@ -134,9 +134,9 @@ add_task(async function testHTTPSSVC() {
|
|||
Assert.equal(answer[0].priority, 1);
|
||||
Assert.equal(answer[0].name, "h3pool");
|
||||
Assert.equal(answer[0].values.length, 6);
|
||||
Assert.equal(
|
||||
Assert.deepEqual(
|
||||
answer[0].values[0].QueryInterface(Ci.nsISVCParamAlpn).alpn,
|
||||
"h2,h3",
|
||||
["h2", "h3"],
|
||||
"got correct answer"
|
||||
);
|
||||
Assert.ok(
|
||||
|
@ -168,9 +168,9 @@ add_task(async function testHTTPSSVC() {
|
|||
Assert.equal(answer[1].priority, 2);
|
||||
Assert.equal(answer[1].name, "test.httpssvc.com");
|
||||
Assert.equal(answer[1].values.length, 4);
|
||||
Assert.equal(
|
||||
Assert.deepEqual(
|
||||
answer[1].values[0].QueryInterface(Ci.nsISVCParamAlpn).alpn,
|
||||
"h2",
|
||||
["h2"],
|
||||
"got correct answer"
|
||||
);
|
||||
Assert.equal(
|
||||
|
@ -310,7 +310,7 @@ add_task(async function test_aliasform() {
|
|||
priority: 1,
|
||||
name: "h3pool",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "no-default-alpn" },
|
||||
{ key: "port", value: 8888 },
|
||||
{ key: "ipv4hint", value: "1.2.3.4" },
|
||||
|
@ -396,7 +396,7 @@ add_task(async function test_aliasform() {
|
|||
priority: 1,
|
||||
name: "h3pool",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "no-default-alpn" },
|
||||
{ key: "port", value: 8888 },
|
||||
{ key: "ipv4hint", value: "1.2.3.4" },
|
||||
|
@ -452,7 +452,7 @@ add_task(async function test_aliasform() {
|
|||
{ key: "ipv4hint", value: "1.2.3.4" },
|
||||
{ key: "port", value: 8888 },
|
||||
{ key: "no-default-alpn" },
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -487,8 +487,8 @@ add_task(async function test_aliasform() {
|
|||
priority: 1,
|
||||
name: "h3pool",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: "h2,h3,h4" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "alpn", value: ["h2", "h3", "h4"] },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -524,7 +524,7 @@ add_task(async function test_aliasform() {
|
|||
name: "h3pool",
|
||||
values: [
|
||||
{ key: "mandatory", value: ["key100"] },
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "key100" },
|
||||
],
|
||||
},
|
||||
|
@ -568,7 +568,7 @@ add_task(async function test_aliasform() {
|
|||
"ipv6hint",
|
||||
],
|
||||
},
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "no-default-alpn" },
|
||||
{ key: "port", value: 8888 },
|
||||
{ key: "ipv4hint", value: "1.2.3.4" },
|
||||
|
@ -634,7 +634,7 @@ add_task(async function test_aliasform() {
|
|||
data: {
|
||||
priority: 1,
|
||||
name: ".",
|
||||
values: [{ key: "alpn", value: "h2,h3" }],
|
||||
values: [{ key: "alpn", value: ["h2", "h3"] }],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -1347,13 +1347,27 @@ svcparam.encode = function(param, buf, offset) {
|
|||
svcparam.encode.bytes += 2;
|
||||
}
|
||||
} else if (key == 1) { // alpn
|
||||
let len = param.value.length
|
||||
buf.writeUInt16BE(len || 0, offset);
|
||||
let val = param.value;
|
||||
if (!Array.isArray(val)) val = [val];
|
||||
// The alpn param is prefixed by its length as a single byte, so the
|
||||
// initialValue to reduce function is the length of the array.
|
||||
let total = val.reduce(function(result, id) {
|
||||
return result += id.length;
|
||||
}, val.length);
|
||||
|
||||
buf.writeUInt16BE(total, offset);
|
||||
offset += 2;
|
||||
svcparam.encode.bytes += 2;
|
||||
buf.write(param.value, offset)
|
||||
offset += len;
|
||||
svcparam.encode.bytes += len;
|
||||
|
||||
for (let id of val) {
|
||||
buf.writeUInt8(id.length, offset);
|
||||
offset += 1;
|
||||
svcparam.encode.bytes += 1;
|
||||
|
||||
buf.write(id, offset);
|
||||
offset += id.length;
|
||||
svcparam.encode.bytes += id.length;
|
||||
}
|
||||
} else if (key == 2) { // no-default-alpn
|
||||
buf.writeUInt16BE(0, offset);
|
||||
offset += 2;
|
||||
|
@ -1433,7 +1447,14 @@ svcparam.encodingLength = function (param) {
|
|||
|
||||
switch (param.key) {
|
||||
case 'mandatory' : return 4 + 2*(Array.isArray(param.value) ? param.value.length : 1)
|
||||
case 'alpn' : return 4 + param.value.length
|
||||
case 'alpn' : {
|
||||
let val = param.value;
|
||||
if (!Array.isArray(val)) val = [val];
|
||||
let total = val.reduce(function(result, id) {
|
||||
return result += id.length;
|
||||
}, val.length);
|
||||
return 4 + total;
|
||||
}
|
||||
case 'no-default-alpn' : return 4
|
||||
case 'port' : return 4 + 2
|
||||
case 'ipv4hint' : return 4 + 4 * (Array.isArray(param.value) ? param.value.length : 1)
|
||||
|
|
|
@ -849,7 +849,7 @@ function handleRequest(req, res) {
|
|||
priority: 1,
|
||||
name: "h3pool",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2,h3" },
|
||||
{ key: "alpn", value: ["h2", "h3"] },
|
||||
{ key: "no-default-alpn" },
|
||||
{ key: "port", value: 8888 },
|
||||
{ key: "ipv4hint", value: "1.2.3.4" },
|
||||
|
|
Загрузка…
Ссылка в новой задаче