/// <summary> /// Remove handler that protects stream publishing. /// </summary> /// <param name="handler">Handler to remove.</param> public void UnregisterStreamPublishSecurity(IStreamPublishSecurity handler) { _publishSecurityHandlers.Remove(handler); }
/// <summary> /// Add handler that protects stream publishing. /// </summary> /// <param name="handler">Handler to add.</param> public void RegisterStreamPublishSecurity(IStreamPublishSecurity handler) { _publishSecurityHandlers.Add(handler); }
public void publish(string name, string mode) { IConnection connection = FluorineContext.Current.Connection; if (!(connection is IStreamCapableConnection)) { return; } IStreamCapableConnection streamConnection = connection as IStreamCapableConnection; IScope scope = connection.Scope; int streamId = GetCurrentStreamId(); if (name == null || string.Empty.Equals(name)) { SendNSFailed(streamConnection as RtmpConnection, "The stream name may not be empty.", name, streamId); return; } IStreamSecurityService security = ScopeUtils.GetScopeService(scope, typeof(IStreamSecurityService)) as IStreamSecurityService; if (security != null) { IEnumerator handlers = security.GetStreamPublishSecurity(); while (handlers.MoveNext()) { IStreamPublishSecurity handler = handlers.Current as IStreamPublishSecurity; if (!handler.IsPublishAllowed(scope, name, mode)) { SendNSFailed(streamConnection as RtmpConnection, "You are not allowed to publish the stream.", name, streamId); return; } } } IBroadcastScope bsScope = GetBroadcastScope(scope, name); if (bsScope != null && bsScope.GetProviders().Count > 0) { // Another stream with that name is already published. StatusASO badName = new StatusASO(StatusASO.NS_PUBLISH_BADNAME); badName.clientid = streamId; badName.details = name; badName.level = "error"; // FIXME: there should be a direct way to send the status RtmpChannel channel = (streamConnection as RtmpConnection).GetChannel((byte)(4 + ((streamId - 1) * 5))); channel.SendStatus(badName); return; } IClientStream stream = streamConnection.GetStreamById(streamId); if (stream != null && !(stream is IClientBroadcastStream)) { return; } bool created = false; if (stream == null) { stream = streamConnection.NewBroadcastStream(streamId); created = true; } IClientBroadcastStream bs = stream as IClientBroadcastStream; try { bs.PublishedName = name; IScopeContext context = connection.Scope.Context; //IProviderService providerService = (IProviderService)context.getBean(IProviderService.BEAN_NAME); IProviderService providerService = ScopeUtils.GetScopeService(connection.Scope, typeof(IProviderService)) as IProviderService; // TODO handle registration failure if (providerService.RegisterBroadcastStream(connection.Scope, name, bs)) { bsScope = GetBroadcastScope(connection.Scope, name); bsScope.SetAttribute(Constants.BroadcastScopeStreamAttribute, bs); if (connection is BaseConnection) { (connection as BaseConnection).RegisterBasicScope(bsScope); } } if (Constants.ClientStreamModeRecord.Equals(mode)) { bs.Start(); bs.SaveAs(name, false); } else if (Constants.ClientStreamModeAppend.Equals(mode)) { bs.Start(); bs.SaveAs(name, true); } else if (Constants.ClientStreamModeLive.Equals(mode)) { bs.Start(); } bs.StartPublishing(); } catch (System.IO.IOException ex) { StatusASO accessDenied = new StatusASO(StatusASO.NS_RECORD_NOACCESS); accessDenied.clientid = streamId; accessDenied.description = "The file could not be created/written to." + ex.Message; accessDenied.details = name; accessDenied.level = "error"; // FIXME: there should be a direct way to send the status RtmpChannel channel = (streamConnection as RtmpConnection).GetChannel((byte)(4 + ((streamId - 1) * 5))); channel.SendStatus(accessDenied); bs.Close(); if (created) { streamConnection.DeleteStreamById(streamId); } } catch (Exception ex) { log.Warn("Publish caught exception", ex); } }
public void publish(string name, string mode) { IConnection connection = FluorineContext.Current.Connection; if (connection is IStreamCapableConnection) { IStreamCapableConnection connection2 = connection as IStreamCapableConnection; IScope scope = connection.Scope; int currentStreamId = this.GetCurrentStreamId(); if ((name == null) || string.Empty.Equals(name)) { this.SendNSFailed(connection2 as RtmpConnection, "The stream name may not be empty.", name, currentStreamId); } else { IStreamSecurityService scopeService = ScopeUtils.GetScopeService(scope, typeof(IStreamSecurityService)) as IStreamSecurityService; if (scopeService != null) { IEnumerator streamPublishSecurity = scopeService.GetStreamPublishSecurity(); while (streamPublishSecurity.MoveNext()) { IStreamPublishSecurity current = streamPublishSecurity.Current as IStreamPublishSecurity; if (!current.IsPublishAllowed(scope, name, mode)) { this.SendNSFailed(connection2 as RtmpConnection, "You are not allowed to publish the stream.", name, currentStreamId); return; } } } IBroadcastScope broadcastScope = this.GetBroadcastScope(scope, name); if ((broadcastScope != null) && (broadcastScope.GetProviders().Count > 0)) { StatusASO status = new StatusASO("NetStream.Publish.BadName") { clientid = currentStreamId, details = name, level = "error" }; (connection2 as RtmpConnection).GetChannel((byte)(4 + ((currentStreamId - 1) * 5))).SendStatus(status); } else { IClientStream streamById = connection2.GetStreamById(currentStreamId); if ((streamById == null) || (streamById is IClientBroadcastStream)) { bool flag = false; if (streamById == null) { streamById = connection2.NewBroadcastStream(currentStreamId); flag = true; } IClientBroadcastStream broadcastStream = streamById as IClientBroadcastStream; try { broadcastStream.PublishedName = name; IScopeContext context = connection.Scope.Context; IProviderService service2 = ScopeUtils.GetScopeService(connection.Scope, typeof(IProviderService)) as IProviderService; if (service2.RegisterBroadcastStream(connection.Scope, name, broadcastStream)) { broadcastScope = this.GetBroadcastScope(connection.Scope, name); broadcastScope.SetAttribute("_transient_publishing_stream", broadcastStream); if (connection is BaseConnection) { (connection as BaseConnection).RegisterBasicScope(broadcastScope); } } if ("record".Equals(mode)) { broadcastStream.Start(); broadcastStream.SaveAs(name, false); } else if ("append".Equals(mode)) { broadcastStream.Start(); broadcastStream.SaveAs(name, true); } else if ("live".Equals(mode)) { broadcastStream.Start(); } broadcastStream.StartPublishing(); } catch (IOException exception) { StatusASO saso2 = new StatusASO("NetStream.Record.NoAccess") { clientid = currentStreamId, description = "The file could not be created/written to." + exception.Message, details = name, level = "error" }; (connection2 as RtmpConnection).GetChannel((byte)(4 + ((currentStreamId - 1) * 5))).SendStatus(saso2); broadcastStream.Close(); if (flag) { connection2.DeleteStreamById(currentStreamId); } } catch (Exception exception2) { log.Warn("Publish caught exception", exception2); } } } } } }