resolvePlayAlias not called consistently for playlist/chunklist/.ts files
I'm setting up a custom Wowza module that uses the IMediaStreamNameAliasProvider2 interface to authenticate playback through stream aliases. This works excellently, but I'm having problem blocking access to a stream in progress because resolvePlayAlias() isn't called consistenly for playlist.m3u8, chunklist* and *.ts files within the stream.
The use case is simple: I need to switch the stream from public to private while it's still broadcasting, and the strategy is to change the stream's alias when this happens. This means that users watching the public stream should no longer get access to the any playlist, chunklist or chunk on the prior stream names.
- Only a small subset these requests though are routed through resolvePlayAlias(). Often with minutes passing between requests to the alias methods and this is the case even when the contents of the chunklist changes.
- At a given point, I'm defining "live:public-stream.mp4" to no longer be a valid stream name within resolvePlayAlias().
- However, since requests do not consistently hit resolvePlayAlias(), users can keep watching the now private stream.
A few notes:
- I'm testing this on 4.0.3 build10989, with HTTP Origin Mode activated.
- I'm testing this on HTTP directly against Wowza, with no proxies or CDN in front of it.
- This doesn't seem to be a caching issue: While testing in Safari, the browser would hit resolvePlayAlias() seemingly at random and receive a 404 -- only to restart the stream with the public stream name and receive HTTP 200 statuses with playlists, chunklists and chunks.
- For what it's worth, my very, very limited testing hasn't revealed the same problem with HDS. At least not yet.
So. I'm clearly missing something -- I hope you guys can point me in the right direction?
I don't think IMediaStreamNameAliasProvider2 is the place to do this. Generally resolvePlayAlias() runs once for playback, tho it may run more than once for during HLS playback if there is a pause for example, but not during uninterrupted playback. You can end an HTTP session with HTTPSession.rejectSession() and HTTPSession.shutdown() (do both) anytime, and you might be able to use HTTPSession.redirectSession() during the session, i.e., after onHTTPSessionCreate. Of course you have to keep track of sessions, which you would start doing in onHTTPSessionCreate()
I thought I had replied to this yesterday but didn't hit send so basically, adding to Richard's answer.
With HTTP Origin mode enabled, there are no separate sessions for a stream so all connections for a stream name will use the same session.
The resolvePlayAlias methods are only called when a session is first created. This will normally be for the playlist.m3u8 request but can also occur for the chunklist.m3u8 request or the media*.ts requests if the player has paused for enough time for the session to timeout.
If you are going to change the alias at some time then when you do this, you also need to disconnect any active sessions that are using the old alias. You can do this by iterating through the sessions connected to the stream name and rejecting them. For HTTP Origin, there will probably only be one session unless you are returning the same name from various requested names.
Once the reject flag is set on the session then all future requests for that session will be rejected until it times out. After it does time out, it may restart again if a player has been paused or doesn't handle the rejection well. In these cases, your resolvePlayAlias method will be called again and you should return null for the old session so that the player receives a 404 response.
The following snippet will iterate through the sessions and reject them.
List<IHTTPStreamerSession> sessions = appInstance.getHTTPStreamerSessions(oldStreamName); // oldStreamName is the resolved name (from previous resolvePlayAlias request).
for (IHTTPStreamerSession session : sessions)
You can also timeout the session immediately by calling session.shutdownSession();. The difference will be the response code that is sent to the player. Reject will send a 403 status whereas shutdown will return a 404 (if the new request to your resolvePlayAlias method returns null).