Sort Common Media Client Data keys to reduce fingerprinting surface

Based on the Common Media Client Data (CMCD) specification key-value pairs should be sequenced in alphabetical order of the key name in order to reduce the fingerprinting surface exposed by the player.

PiperOrigin-RevId: 558296264
This commit is contained in:
rohks 2023-08-19 02:13:37 +01:00 committed by Julia Bibik
parent afb8d6c9e2
commit b6b16b2895
5 changed files with 39 additions and 34 deletions

View File

@ -40,6 +40,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
@ -466,6 +467,7 @@ public final class CmcdHeadersFactory {
headerValueList.addAll(customDataList);
if (!headerValueList.isEmpty()) {
Collections.sort(headerValueList);
httpRequestHeaders.put(
CmcdConfiguration.KEY_CMCD_OBJECT, COMMA_JOINER.join(headerValueList));
}
@ -635,6 +637,7 @@ public final class CmcdHeadersFactory {
headerValueList.addAll(customDataList);
if (!headerValueList.isEmpty()) {
Collections.sort(headerValueList);
httpRequestHeaders.put(
CmcdConfiguration.KEY_CMCD_REQUEST, COMMA_JOINER.join(headerValueList));
}
@ -814,6 +817,7 @@ public final class CmcdHeadersFactory {
headerValueList.addAll(customDataList);
if (!headerValueList.isEmpty()) {
Collections.sort(headerValueList);
httpRequestHeaders.put(
CmcdConfiguration.KEY_CMCD_SESSION, COMMA_JOINER.join(headerValueList));
}
@ -920,6 +924,7 @@ public final class CmcdHeadersFactory {
headerValueList.addAll(customDataList);
if (!headerValueList.isEmpty()) {
Collections.sort(headerValueList);
httpRequestHeaders.put(
CmcdConfiguration.KEY_CMCD_STATUS, COMMA_JOINER.join(headerValueList));
}

View File

@ -83,13 +83,13 @@ public class CmcdHeadersFactoryTest {
assertThat(requestHeaders)
.containsExactly(
"CMCD-Object",
"br=840,tb=1000,d=3000,key-1=1,key-2-separated-by-multiple-hyphens=2",
"br=840,d=3000,key-1=1,key-2-separated-by-multiple-hyphens=2,tb=1000",
"CMCD-Request",
"bl=1800,mtp=500,dl=900,su,key-3=\"stringValue1,stringValue2\"",
"bl=1800,dl=900,key-3=\"stringValue1,stringValue2\",mtp=500,su",
"CMCD-Session",
"cid=\"mediaId\",sid=\"sessionId\",sf=d,st=l,pr=2.00",
"cid=\"mediaId\",pr=2.00,sf=d,sid=\"sessionId\",st=l",
"CMCD-Status",
"rtp=1700,bs,key-4=\"stringValue3=stringValue4\"");
"bs,key-4=\"stringValue3=stringValue4\",rtp=1700");
}
@Test

View File

@ -319,11 +319,11 @@ public class DefaultDashChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=700,tb=1300,d=4000,ot=v",
"br=700,d=4000,ot=v,tb=1300",
"CMCD-Request",
"bl=0,mtp=1000,dl=0,su",
"bl=0,dl=0,mtp=1000,su",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v");
"cid=\"mediaId\",sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
chunkSource.getNextChunk(
new LoadingInfo.Builder().setPlaybackPositionUs(3_000_000).setPlaybackSpeed(1.25f).build(),
@ -334,11 +334,11 @@ public class DefaultDashChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=700,tb=1300,d=4000,ot=v",
"br=700,d=4000,ot=v,tb=1300",
"CMCD-Request",
"bl=1000,mtp=1000,dl=800",
"bl=1000,dl=800,mtp=1000",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v,pr=1.25");
"cid=\"mediaId\",pr=1.25,sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
}
@Test
@ -418,9 +418,9 @@ public class DefaultDashChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=700,tb=1300,d=4000,ot=v",
"br=700,d=4000,ot=v,tb=1300",
"CMCD-Request",
"bl=0,mtp=1000,dl=0,su",
"bl=0,dl=0,mtp=1000,su",
"CMCD-Session",
"cid=\"mediaIdcontentIdSuffix\",sf=d,st=v",
"CMCD-Status",
@ -466,11 +466,11 @@ public class DefaultDashChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=700,tb=1300,d=4000,ot=v,key-1=1",
"br=700,d=4000,key-1=1,ot=v,tb=1300",
"CMCD-Request",
"bl=0,mtp=1000,dl=0,su,key-2=\"stringValue\"",
"bl=0,dl=0,key-2=\"stringValue\",mtp=1000,su",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v,key-3=3",
"cid=\"mediaId\",key-3=3,sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v",
"CMCD-Status",
"key-4=5.0");
}

View File

@ -214,11 +214,11 @@ public class HlsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=800,tb=800,d=4000,ot=v",
"br=800,d=4000,ot=v,tb=800",
"CMCD-Request",
"bl=0,dl=0,su",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=h,st=v");
"cid=\"mediaId\",sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
testChunkSource.getNextChunk(
new LoadingInfo.Builder().setPlaybackPositionUs(3_000_000).setPlaybackSpeed(1.25f).build(),
@ -230,11 +230,11 @@ public class HlsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=800,tb=800,d=4000,ot=v",
"br=800,d=4000,ot=v,tb=800",
"CMCD-Request",
"bl=1000,dl=800",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=h,st=v,pr=1.25");
"cid=\"mediaId\",pr=1.25,sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
}
@Test
@ -327,7 +327,7 @@ public class HlsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=800,tb=800,d=4000,ot=v",
"br=800,d=4000,ot=v,tb=800",
"CMCD-Request",
"bl=0,dl=0,su",
"CMCD-Session",
@ -376,11 +376,11 @@ public class HlsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=800,tb=800,d=4000,ot=v,key-1=1",
"br=800,d=4000,key-1=1,ot=v,tb=800",
"CMCD-Request",
"bl=0,dl=0,su,key-2=\"stringValue\"",
"bl=0,dl=0,key-2=\"stringValue\",su",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=h,st=v,key-3=3",
"cid=\"mediaId\",key-3=3,sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v",
"CMCD-Status",
"key-4=5.0");
}

View File

@ -69,11 +69,11 @@ public class DefaultSsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=308,tb=1536,d=1968,ot=v",
"br=308,d=1968,ot=v,tb=1536",
"CMCD-Request",
"bl=0,mtp=1000,dl=0,su",
"bl=0,dl=0,mtp=1000,su",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=s,st=v");
"cid=\"mediaId\",sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
chunkSource.getNextChunk(
new LoadingInfo.Builder().setPlaybackPositionUs(3_000_000).setPlaybackSpeed(2.0f).build(),
@ -84,11 +84,11 @@ public class DefaultSsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=308,tb=1536,d=898,ot=v",
"br=308,d=898,ot=v,tb=1536",
"CMCD-Request",
"bl=1000,mtp=1000,dl=500",
"bl=1000,dl=500,mtp=1000",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=s,st=v,pr=2.00");
"cid=\"mediaId\",pr=2.00,sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v");
}
@Test
@ -168,9 +168,9 @@ public class DefaultSsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=308,tb=1536,d=1968,ot=v",
"br=308,d=1968,ot=v,tb=1536",
"CMCD-Request",
"bl=0,mtp=1000,dl=0,su",
"bl=0,dl=0,mtp=1000,su",
"CMCD-Session",
"cid=\"mediaIdcontentIdSuffix\",sf=s,st=v",
"CMCD-Status",
@ -216,11 +216,11 @@ public class DefaultSsChunkSourceTest {
assertThat(output.chunk.dataSpec.httpRequestHeaders)
.containsExactly(
"CMCD-Object",
"br=308,tb=1536,d=1968,ot=v,key-1=1",
"br=308,d=1968,key-1=1,ot=v,tb=1536",
"CMCD-Request",
"bl=0,mtp=1000,dl=0,su,key-2=\"stringValue\"",
"bl=0,dl=0,key-2=\"stringValue\",mtp=1000,su",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=s,st=v,key-3=3",
"cid=\"mediaId\",key-3=3,sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v",
"CMCD-Status",
"key-4=5.0");
}