Open stufan opened 5 years ago
Cronet doesn't store cookies, as per this issue. I think the best approach here would be to:
CookieStore
interface in the Cronet extension, and allow an implementation to be injected from app code.CookieStore
to trivially map onto OkHttp
's CookieJar
or the platform CookieHandler
, so developers can easily implement CookieStore
as a wrapper around one of these APIs. It would probably just define:put(Uri uri, Map<String, List<String>> responseHeaders);
Map<String, List<String>> get(Uri);
Comment 4 on the issue above has a few changed references that show how easy the mapping is, and how the interface would be used from inside CronetDataSource
.
We wont be treating this as high priority, but would accept a pull request if you're able to help ;).
I have used this additional method to add the Cookie Header every time for the existing httpDataSourceFactory
manually and works for me.
private static HttpDataSource.@MonotonicNonNull Factory httpDataSourceFactory;
public static synchronized HttpDataSource.Factory getHttpDataSourceFactory(final Context context) {
if (httpDataSourceFactory == null) {
CronetEngineWrapper cronetEngineWrapper = new CronetEngineWrapper(context.getApplicationContext(),
USER_AGENT, /* preferGMSCoreCronet= */ false);
httpDataSourceFactory = new CronetDataSource.Factory(cronetEngineWrapper, Executors.newSingleThreadExecutor())
.setHandleSetCookieRequests(true).setAllowCrossProtocolRedirects(true);
}
return httpDataSourceFactory;
}
public static void addCronetCookies(final Context context, final HashMap<String, String> cookies) {
if (httpDataSourceFactory == null) {
getHttpDataSourceFactory(context);
}
StringBuilder builder = new StringBuilder();
for (String key : cookies.keySet()) {
if (builder.length() > 0) {
builder.append(";");
}
builder.append(key).append("=").append(cookies.get(key));
}
HashMap<String, String> headerCookie = new HashMap<>();
headerCookie.put("Cookie", builder.toString());
httpDataSourceFactory.setDefaultRequestProperties(headerCookie);
}
I am trying to switch streaming from HttpDataSource to CronetDataSource. The way I am doing it by adding official ExoPlayer cronet extension: https://github.com/google/ExoPlayer/tree/release-v2/extensions/cronet
Then in code just change:
DataSource.Factory mDataSourceFactory = new DefaultDataSourceFactory(mContext, RemoteGateway.getUserAgent(), bandwidthMeter);
to:
What happens is that the stream works without any issues when using HttpDataSource but fails with CronetDataSource. After debugging it turns out that CronetDataSource doesn't process Set-Cookie header(s) return by my streaming CDN (Amazon CloudFront) on master playlist response and doesn't pass those cookies on subsequent requests for AES key and/or chunklists.
I search for ExoPlayer documentation and wasn't able to find info how to correctly configure cookie management when Cronet extension is used.
Here is my ExoPlayer info: D/CronetEngineWrapper: CronetEngine built using App-Packaged-Cronet-Provider I/ExoPlayerImpl: Init ef5675b [ExoPlayerLib/2.10.1] [generic_x86, sdk_google_atv_x86, unknown, 25]
Thanks Stefan