Remove null keys from DefaultHttpDataSource#getResponseHeaders
PiperOrigin-RevId: 410507648
This commit is contained in:
parent
d5b6250350
commit
191185096c
@ -20,7 +20,6 @@ import androidx.media3.test.utils.DataSourceContractTest;
|
||||
import androidx.media3.test.utils.HttpDataSourceTestEnv;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@ -44,8 +43,4 @@ public class DefaultHttpDataSourceContractTest extends DataSourceContractTest {
|
||||
protected Uri getNotFoundUri() {
|
||||
return Uri.parse(httpDataSourceTestEnv.getNonexistentUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Ignore("internal b/205811776")
|
||||
public void getResponseHeaders_noNullKeysOrValues() {}
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import androidx.media3.datasource.DataSpec.HttpMethod;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ForwardingMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -40,10 +43,10 @@ import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
@ -312,7 +315,18 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return connection == null ? Collections.emptyMap() : connection.getHeaderFields();
|
||||
if (connection == null) {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
// connection.getHeaderFields() always contains a null key with a value like
|
||||
// ["HTTP/1.1 200 OK"]. The response code is available from HttpURLConnection#getResponseCode()
|
||||
// and the HTTP version is fixed when establishing the connection.
|
||||
// DataSource#getResponseHeaders() doesn't allow null keys in the returned map, so we need to
|
||||
// remove it.
|
||||
// connection.getHeaderFields() returns a special unmodifiable case-insensitive Map
|
||||
// so we can't just remove the null key or make a copy without the null key. Instead we wrap it
|
||||
// in a ForwardingMap subclass that ignores and filters out null keys in the read methods.
|
||||
return new NullFilteringHeadersMap(connection.getHeaderFields());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -817,4 +831,64 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
||||
String contentEncoding = connection.getHeaderField("Content-Encoding");
|
||||
return "gzip".equalsIgnoreCase(contentEncoding);
|
||||
}
|
||||
|
||||
private static class NullFilteringHeadersMap extends ForwardingMap<String, List<String>> {
|
||||
|
||||
private final Map<String, List<String>> headers;
|
||||
|
||||
public NullFilteringHeadersMap(Map<String, List<String>> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, List<String>> delegate() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(@Nullable Object key) {
|
||||
return key != null && super.containsKey(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> get(@Nullable Object key) {
|
||||
return key == null ? null : super.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return Sets.filter(super.keySet(), key -> key != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<String, List<String>>> entrySet() {
|
||||
return Sets.filter(super.entrySet(), entry -> entry.getKey() != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return super.size() - (super.containsKey(null) ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() || (super.size() == 1 && super.containsKey(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(@Nullable Object value) {
|
||||
return super.standardContainsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object object) {
|
||||
return object != null && super.standardEquals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.standardHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -547,11 +547,6 @@ public abstract class DataSourceContractTest {
|
||||
|
||||
Map<String, List<String>> responseHeaders = dataSource.getResponseHeaders();
|
||||
for (String key : responseHeaders.keySet()) {
|
||||
// TODO(internal b/205811776): Remove this when DefaultHttpDataSource is fixed to not
|
||||
// return a null key.
|
||||
if (key == null) {
|
||||
continue;
|
||||
}
|
||||
String caseFlippedKey = invertAsciiCaseOfEveryOtherCharacter(key);
|
||||
assertWithMessage("key='%s', caseFlippedKey='%s'", key, caseFlippedKey)
|
||||
.that(responseHeaders.get(caseFlippedKey))
|
||||
|
Loading…
x
Reference in New Issue
Block a user