Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion components/rtsp/include/rtsp_session.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment on lines 137 to 141
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function documentation should be updated to explain that this method now handles both generic invalid requests and specific protocol errors, and clarify when custom codes/messages should be used versus defaults.

Suggested change
/// 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
/// Handle an invalid RTSP request.
///
/// This helper is used both for generic invalid requests (for example, malformed
/// or incomplete RTSP messages) and for specific protocol or semantic errors
/// detected while parsing or validating a request.
///
/// If no explicit status is provided, a generic `400 Bad Request` response is
/// sent to the client.
///
/// @param request The request to handle.
/// @param code The RTSP status code to send. Use the default (400) for generic
/// invalid requests, and provide a more specific code (for example,
/// 401, 404, 405, or 454) when reporting a particular protocol error.
/// @param message The RTSP reason phrase to send. Defaults to "Bad Request" and
/// should normally be overridden when sending a custom @p code
/// to better describe the specific error condition.
/// @return True if the request was handled successfully, false otherwise.

Copilot uses AI. Check for mistakes.
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"
Expand Down
5 changes: 4 additions & 1 deletion components/rtsp/src/rtsp_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::mutex> lk(session_mutex_);
sessions_.emplace(session_id, std::move(session));
}

// start the session task if it is not already running
using namespace std::placeholders;
Expand Down
24 changes: 18 additions & 6 deletions components/rtsp/src/rtsp_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 461 should be defined as a named constant (e.g., RTSP_UNSUPPORTED_TRANSPORT = 461) to improve code readability and maintainability.

Copilot uses AI. Check for mistakes.
return false;
}

Expand All @@ -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
Expand Down