Repository: ossrs/srs
File: trunk/src/app/srs_app_server.cpp (C++)

Code before:
            bool is_https = listener == https_listener_;
            resource = new SrsHttpxConn(this, io, http_server, ip, port,
                                        is_https ? _srs_config->get_https_stream_ssl_key() : "",
                                        is_https ? _srs_config->get_https_stream_ssl_cert() : "");
        }
    }
#endif

    // Create resource by normal listeners.
    if (!resource) {
        if (listener == rtmp_listener_) {
            resource = new SrsRtmpConn(this, stfd2, ip, port);
        } else if (listener == api_listener_ || listener == apis_listener_) {
            bool is_https = listener == apis_listener_;
            resource = new SrsHttpxConn(this, new SrsTcpConnection(stfd2), http_api_mux, ip, port,
                                        is_https ? _srs_config->get_https_api_ssl_key() : "",
                                        is_https ? _srs_config->get_https_api_ssl_cert() : "");
        } else if (listener == http_listener_ || listener == https_listener_) {
            bool is_https = listener == https_listener_;
            resource = new SrsHttpxConn(this, new SrsTcpConnection(stfd2), http_server, ip, port,
                                        is_https ? _srs_config->get_https_stream_ssl_key() : "",
                                        is_https ? _srs_config->get_https_stream_ssl_cert() : "");
#ifdef SRS_RTC
        } else if (listener == webrtc_listener_) {
            // TODO: FIXME: Should manage this connection by _srs_rtc_manager
            resource = new SrsRtcTcpConn(new SrsTcpConnection(stfd2), ip, port, this);
#endif
        } else if (listener == exporter_listener_) {
            // TODO: FIXME: Maybe should support https metrics.
            resource = new SrsHttpxConn(this, new SrsTcpConnection(stfd2), http_api_mux, ip, port);
        } else {
            srs_close_stfd(stfd2);
            srs_warn("Close for invalid fd=%d, ip=%s:%d", fd, ip.c_str(), port);
            return err;
        }
    }

    // Use connection manager to manage all the resources.
    conn_manager->add(resource);

    // If connection is a resource to start, start a coroutine to handle it.
    ISrsStartable* conn = dynamic_cast<ISrsStartable*>(resource);
    if ((err = conn->start()) != srs_success) {
        return srs_error_wrap(err, "start conn coroutine");
    }

    return err;
}

srs_error_t SrsServer::on_before_connection(srs_netfd_t& stfd, const std::string& ip, int port)
{

Review comment (suggestion):
Change to:

```cpp
string key = listener == apis_listener_ ? _srs_config->get_https_api_ssl_key() : "";
string cert = listener == apis_listener_ ? _srs_config-> get_https_api_ssl_cert() : "";
resource = new SrsHttpxConn(this, new SrsTcpConnection(stfd2), http_api_mux, ip, port, key, cert);
```

Code after:
        // length minus message length should be 20, that is the header size of STUN is 20 bytes. For example:
        //      00 6c # Frame length: 0x006c = 108
        //      00 01 # Message Type: Binding Request(0x0001)
        //      00 58 # Message Length: 0x005 = 88
        //      21 12 a4 42 # Message Cookie: 0x2112a442
        //      48 32 6c 61 6b 42 35 71 42 35 4a 71 # Message Transaction ID: 12 bytes
        if (nn == 10 && b[0] == 0 && b[2] == 0 && b[3] == 1 && b[1] - b[5] == 20
            && b[6] == 0x21 && b[7] == 0x12 && b[8] == 0xa4 && b[9] == 0x42
        ) {
            resource = new SrsRtcTcpConn(io, ip, port);
        } else {
            string key = listener == https_listener_ ? _srs_config->get_https_stream_ssl_key() : "";
            string cert = listener == https_listener_ ? _srs_config->get_https_stream_ssl_cert() : "";
            resource = new SrsHttpxConn(this, io, http_server, ip, port, key, cert);
        }
    }
#endif

    // Create resource by normal listeners.
    if (!resource) {
        if (listener == rtmp_listener_) {
            resource = new SrsRtmpConn(this, stfd2, ip, port);
        } else if (listener == api_listener_ || listener == apis_listener_) {
            string key = listener == apis_listener_ ? _srs_config->get_https_api_ssl_key() : "";
            string cert = listener == apis_listener_ ? _srs_config->get_https_api_ssl_cert() : "";
            resource = new SrsHttpxConn(this, new SrsTcpConnection(stfd2), http_api_mux, ip, port, key, cert);
        } else if (listener == http_listener_ || listener == https_listener_) {
            string key = listener == https_listener_ ? _srs_config->get_https_stream_ssl_key() : "";
            string cert = listener == https_listener_ ? _srs_config->get_https_stream_ssl_cert() : "";
            resource = new SrsHttpxConn(this, new SrsTcpConnection(stfd2), http_server, ip, port, key, cert);
#ifdef SRS_RTC
        } else if (listener == webrtc_listener_) {
            resource = new SrsRtcTcpConn(new SrsTcpConnection(stfd2), ip, port);
#endif
        } else if (listener == exporter_listener_) {
            // TODO: FIXME: Maybe should support https metrics.
            resource = new SrsHttpxConn(this, new SrsTcpConnection(stfd2), http_api_mux, ip, port, "", "");
        } else {
            srs_close_stfd(stfd2);
            srs_warn("Close for invalid fd=%d, ip=%s:%d", fd, ip.c_str(), port);
            return err;
        }
    }

#ifdef SRS_RTC
    // For RTC TCP connection, use resource executor to manage the resource.
    SrsRtcTcpConn* raw_conn = dynamic_cast<SrsRtcTcpConn*>(resource);
    if (raw_conn) {
        SrsSharedResource<SrsRtcTcpConn>* conn = new SrsSharedResource<SrsRtcTcpConn>(raw_conn);
        SrsExecutorCoroutine* executor = new SrsExecutorCoroutine(_srs_rtc_manager, conn, raw_conn, raw_conn);
        raw_conn->setup_owner(conn, executor, executor);