Commit 95c0c5ca by claincly Committed by bachinger

Allow TCP retry when using authentication.

The old version's retry logic will not work if using authentication.
Specifically, we use the same authentication parameters from the previous
session, and the RTSP server will reject such parameter.

In this fix, we reset the authentication info on retry. Further, we retry the
last request on receiving a 401 Unauthorized, rather than sending out another
DESCRIBE request.

#minor-release

PiperOrigin-RevId: 377539711
parent 146648ce
...@@ -50,10 +50,13 @@ import com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.RtspSessionHead ...@@ -50,10 +50,13 @@ import com.google.android.exoplayer2.source.rtsp.RtspMessageUtil.RtspSessionHead
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.net.SocketFactory; import javax.net.SocketFactory;
...@@ -105,10 +108,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -105,10 +108,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private @MonotonicNonNull PlaybackEventListener playbackEventListener; private @MonotonicNonNull PlaybackEventListener playbackEventListener;
@Nullable private String sessionId; @Nullable private String sessionId;
@Nullable private KeepAliveMonitor keepAliveMonitor; @Nullable private KeepAliveMonitor keepAliveMonitor;
@Nullable private RtspAuthenticationInfo rtspAuthenticationInfo;
private boolean hasUpdatedTimelineAndTracks; private boolean hasUpdatedTimelineAndTracks;
private boolean receivedAuthorizationRequest; private boolean receivedAuthorizationRequest;
private long pendingSeekPositionUs; private long pendingSeekPositionUs;
private @MonotonicNonNull RtspAuthenticationInfo rtspAuthenticationInfo;
/** /**
* Creates a new instance. * Creates a new instance.
...@@ -219,6 +222,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -219,6 +222,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
messageChannel.open(getSocket(uri)); messageChannel.open(getSocket(uri));
sessionId = null; sessionId = null;
receivedAuthorizationRequest = false; receivedAuthorizationRequest = false;
rtspAuthenticationInfo = null;
} catch (IOException e) { } catch (IOException e) {
checkNotNull(playbackEventListener).onPlaybackError(new RtspPlaybackException(e)); checkNotNull(playbackEventListener).onPlaybackError(new RtspPlaybackException(e));
} }
...@@ -295,6 +299,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -295,6 +299,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final class MessageSender { private final class MessageSender {
private int cSeq; private int cSeq;
private @MonotonicNonNull RtspRequest lastRequest;
public void sendOptionsRequest(Uri uri, @Nullable String sessionId) { public void sendOptionsRequest(Uri uri, @Nullable String sessionId) {
sendRequest( sendRequest(
...@@ -339,6 +344,28 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -339,6 +344,28 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
METHOD_PAUSE, sessionId, /* additionalHeaders= */ ImmutableMap.of(), uri)); METHOD_PAUSE, sessionId, /* additionalHeaders= */ ImmutableMap.of(), uri));
} }
public void retryLastRequest() {
checkStateNotNull(lastRequest);
Multimap<String, String> headersMultiMap = lastRequest.headers.asMultiMap();
Map<String, String> lastRequestHeaders = new HashMap<>();
for (String headerName : headersMultiMap.keySet()) {
if (headerName.equals(RtspHeaders.CSEQ)
|| headerName.equals(RtspHeaders.USER_AGENT)
|| headerName.equals(RtspHeaders.SESSION)
|| headerName.equals(RtspHeaders.AUTHORIZATION)) {
// Clear session-specific header values.
continue;
}
// Only include the header value that is written most recently.
lastRequestHeaders.put(headerName, Iterables.getLast(headersMultiMap.get(headerName)));
}
sendRequest(
getRequestWithCommonHeaders(
lastRequest.method, sessionId, lastRequestHeaders, lastRequest.uri));
}
private RtspRequest getRequestWithCommonHeaders( private RtspRequest getRequestWithCommonHeaders(
@RtspRequest.Method int method, @RtspRequest.Method int method,
@Nullable String sessionId, @Nullable String sessionId,
...@@ -346,7 +373,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -346,7 +373,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
Uri uri) { Uri uri) {
RtspHeaders.Builder headersBuilder = new RtspHeaders.Builder(); RtspHeaders.Builder headersBuilder = new RtspHeaders.Builder();
headersBuilder.add(RtspHeaders.CSEQ, String.valueOf(cSeq++)); headersBuilder.add(RtspHeaders.CSEQ, String.valueOf(cSeq++));
if (userAgent != null) { if (userAgent != null) {
headersBuilder.add(RtspHeaders.USER_AGENT, userAgent); headersBuilder.add(RtspHeaders.USER_AGENT, userAgent);
} }
...@@ -375,6 +401,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -375,6 +401,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
checkState(pendingRequests.get(cSeq) == null); checkState(pendingRequests.get(cSeq) == null);
pendingRequests.append(cSeq, request); pendingRequests.append(cSeq, request);
messageChannel.send(RtspMessageUtil.serializeRequest(request)); messageChannel.send(RtspMessageUtil.serializeRequest(request));
lastRequest = request;
} }
} }
...@@ -426,7 +453,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -426,7 +453,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
rtspAuthenticationInfo = rtspAuthenticationInfo =
RtspMessageUtil.parseWwwAuthenticateHeader(wwwAuthenticateHeader); RtspMessageUtil.parseWwwAuthenticateHeader(wwwAuthenticateHeader);
messageSender.sendDescribeRequest(uri, sessionId); messageSender.retryLastRequest();
receivedAuthorizationRequest = true; receivedAuthorizationRequest = true;
return; return;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment