/* * RED5 Open Source Flash Server - https://github.com/Red5/ * * Copyright 2006-2015 by respective authors (see below). All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.red5.client.net.rtmps; import java.net.InetSocketAddress; import javax.net.ssl.SSLContext; import org.apache.mina.core.future.IoFuture; import org.apache.mina.core.future.IoFutureListener; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.ssl.SslFilter; import org.apache.mina.transport.socket.nio.NioSocketConnector; import org.red5.client.net.rtmp.RTMPClient; import org.red5.client.net.rtmp.RTMPMinaIoHandler; import org.red5.client.net.ssl.BogusSslContextFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * RTMPS client object (RTMPS Native) * * <pre> * var nc:NetConnection = new NetConnection(); * nc.proxyType = "best"; * nc.connect("rtmps:\\localhost\app"); * </pre> * * @author The Red5 Project * @author Paul Gregoire (mondain@gmail.com) * @author Kevin Green (kevygreen@gmail.com) */ public class RTMPSClient extends RTMPClient { private static final Logger log = LoggerFactory.getLogger(RTMPSClient.class); // I/O handler private final RTMPSClientIoHandler ioHandler; /** * Password for accessing the keystore. */ @SuppressWarnings("unused") private char[] password; /** * The keystore type, valid options are JKS and PKCS12 */ @SuppressWarnings("unused") private String keyStoreType = "JKS"; /** Constructs a new RTMPClient. */ public RTMPSClient() { protocol = "rtmps"; ioHandler = new RTMPSClientIoHandler(); ioHandler.setHandler(this); } @SuppressWarnings({ "rawtypes" }) @Override protected void startConnector(String server, int port) { socketConnector = new NioSocketConnector(); socketConnector.setHandler(ioHandler); future = socketConnector.connect(new InetSocketAddress(server, port)); future.addListener(new IoFutureListener() { @Override public void operationComplete(IoFuture future) { try { // will throw RuntimeException after connection error future.getSession(); } catch (Throwable e) { //if there isn't an ClientExceptionHandler set, a //RuntimeException may be thrown in handleException handleException(e); } } }); // Do the close requesting that the pending messages are sent before // the session is closed //future.getSession().close(false); // Now wait for the close to be completed future.awaitUninterruptibly(CONNECTOR_WORKER_TIMEOUT); // We can now dispose the connector //socketConnector.dispose(); } /** * Password used to access the keystore file. * * @param password */ public void setKeyStorePassword(String password) { this.password = password.toCharArray(); } /** * Set the key store type, JKS or PKCS12. * * @param keyStoreType */ public void setKeyStoreType(String keyStoreType) { this.keyStoreType = keyStoreType; } private class RTMPSClientIoHandler extends RTMPMinaIoHandler { /** {@inheritDoc} */ @Override public void sessionOpened(IoSession session) throws Exception { // START OF NATIVE SSL STUFF SSLContext sslContext = BogusSslContextFactory.getInstance(false); SslFilter sslFilter = new SslFilter(sslContext); sslFilter.setUseClientMode(true); if (sslFilter != null) { session.getFilterChain().addFirst("sslFilter", sslFilter); } // END OF NATIVE SSL STUFF super.sessionOpened(session); } /** {@inheritDoc} */ @SuppressWarnings("deprecation") @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { log.warn("Exception caught {}", cause.getMessage()); if (log.isDebugEnabled()) { log.error("Exception detail", cause); } //if there are any errors using ssl, kill the session session.close(true); } } }