diff --git a/components/rtsp/include/rtsp_session.hpp b/components/rtsp/include/rtsp_session.hpp index 4048dd913..cf7c83c0c 100644 --- a/components/rtsp/include/rtsp_session.hpp +++ b/components/rtsp/include/rtsp_session.hpp @@ -136,8 +136,11 @@ class RtspSession : public BaseComponent { /// Handle an invalid RTSP request /// @param request The request to handle + /// @param code The response code to send (default: 400) + /// @param message The response message to send (default: "Bad Request") /// @return True if the request was handled successfully, false otherwise - bool handle_rtsp_invalid_request(std::string_view request); + bool handle_rtsp_invalid_request(std::string_view request, int code = 400, + std::string_view message = "Bad Request"); /// Handle a single RTSP request /// @note Requests are of the form "METHOD RTSP_PATH RTSP_VERSION" diff --git a/components/rtsp/src/rtsp_server.cpp b/components/rtsp/src/rtsp_server.cpp index 40fd27025..f753a7776 100644 --- a/components/rtsp/src/rtsp_server.cpp +++ b/components/rtsp/src/rtsp_server.cpp @@ -186,7 +186,10 @@ bool RtspServer::accept_task_function(std::mutex &m, std::condition_variable &cv // add the session to the list of sessions auto session_id = session->get_session_id(); - sessions_.emplace(session_id, std::move(session)); + { + std::lock_guard lk(session_mutex_); + sessions_.emplace(session_id, std::move(session)); + } // start the session task if it is not already running using namespace std::placeholders; diff --git a/components/rtsp/src/rtsp_session.cpp b/components/rtsp/src/rtsp_session.cpp index 1917a8a48..c7338ddab 100644 --- a/components/rtsp/src/rtsp_session.cpp +++ b/components/rtsp/src/rtsp_session.cpp @@ -152,7 +152,9 @@ bool RtspSession::handle_rtsp_setup(std::string_view request) { int client_rtp_port; int client_rtcp_port; if (!parse_rtsp_setup_request(request, rtsp_path, client_rtp_port, client_rtcp_port)) { - // the parse function will send the response, so we just need to return + // the parse function will send the response, so we just need to + // teardown the session since setup failed and streaming cannot proceed + teardown(); return false; } // parse the sequence number from the request @@ -215,11 +217,10 @@ bool RtspSession::handle_rtsp_teardown(std::string_view request) { return send_response(code, message, sequence_number, headers); } -bool RtspSession::handle_rtsp_invalid_request(std::string_view request) { +bool RtspSession::handle_rtsp_invalid_request(std::string_view request, int code, + std::string_view message) { logger_.info("RTSP invalid request"); // create a response - int code = 400; - std::string message = "Bad Request"; int sequence_number = 0; if (!parse_rtsp_command_sequence(request, sequence_number)) { return send_response(code, message); @@ -357,29 +358,36 @@ bool RtspSession::parse_rtsp_setup_request(std::string_view request, std::string // parse the rtsp path from the request rtsp_path = parse_rtsp_path(request); if (rtsp_path.empty()) { + logger_.error("Failed to parse RTSP path from request"); + handle_rtsp_invalid_request(request); return false; } logger_.debug("Parsing setup request:\n{}", request); // parse the transport header from the request auto transport_index = request.find("Transport: "); if (transport_index == std::string::npos) { + logger_.error("Failed to parse Transport header (start) from request"); + handle_rtsp_invalid_request(request); return false; } auto transport_end_index = request.find('\r', transport_index); if (transport_end_index == std::string::npos) { + logger_.error("Failed to parse Transport header (end) from request"); + handle_rtsp_invalid_request(request); return false; } std::string_view transport = request.substr(transport_index + 11, transport_end_index - transport_index - 11); if (transport.empty()) { + logger_.error("Transport header is empty"); + handle_rtsp_invalid_request(request); return false; } logger_.debug("Transport header: {}", transport); // we don't support TCP, so return an error if the transport is not RTP/AVP/UDP if (transport.find("RTP/AVP/TCP") != std::string::npos) { logger_.error("TCP transport is not supported"); - // TODO: this doesn't send the sequence number back to the client - send_response(461, "Unsupported Transport"); + handle_rtsp_invalid_request(request, 461, "Unsupported Transport"); return false; } @@ -389,12 +397,16 @@ bool RtspSession::parse_rtsp_setup_request(std::string_view request, std::string std::string_view rtp_port = request.substr(client_port_index + 12, dash_index - client_port_index - 12); if (rtp_port.empty()) { + logger_.error("Failed to parse client RTP port from request"); + handle_rtsp_invalid_request(request); return false; } // parse the rtcp port from the request std::string_view rtcp_port = request.substr(dash_index + 1, request.find('\r', client_port_index) - dash_index - 1); if (rtcp_port.empty()) { + logger_.error("Empty client RTCP port in request"); + handle_rtsp_invalid_request(request); return false; } // convert the rtp and rtcp ports to integers