mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-20 06:20:40 +00:00
rtsp: Handle requests from server to client
This returns 200 OK for OPTIONS requests and 501 Not Implemented for all other requests. Even though this doesn't do much actual handling of the requests, it makes the code properly identify server requests as such, instead of interpreting it as a reply to the client's request as it did before. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
f234e8a32e
commit
1a6b9a98ce
@ -900,9 +900,13 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
|
||||
char buf[4096], buf1[1024], *q;
|
||||
unsigned char ch;
|
||||
const char *p;
|
||||
int ret, content_length, line_count = 0;
|
||||
int ret, content_length, line_count = 0, request = 0;
|
||||
unsigned char *content = NULL;
|
||||
|
||||
start:
|
||||
line_count = 0;
|
||||
request = 0;
|
||||
content = NULL;
|
||||
memset(reply, 0, sizeof(*reply));
|
||||
|
||||
/* parse reply (XXX: use buffers) */
|
||||
@ -938,9 +942,15 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
|
||||
if (line_count == 0) {
|
||||
/* get reply code */
|
||||
get_word(buf1, sizeof(buf1), &p);
|
||||
get_word(buf1, sizeof(buf1), &p);
|
||||
reply->status_code = atoi(buf1);
|
||||
av_strlcpy(reply->reason, p, sizeof(reply->reason));
|
||||
if (!strncmp(buf1, "RTSP/", 5)) {
|
||||
get_word(buf1, sizeof(buf1), &p);
|
||||
reply->status_code = atoi(buf1);
|
||||
av_strlcpy(reply->reason, p, sizeof(reply->reason));
|
||||
} else {
|
||||
av_strlcpy(reply->reason, buf1, sizeof(reply->reason)); // method
|
||||
get_word(buf1, sizeof(buf1), &p); // object
|
||||
request = 1;
|
||||
}
|
||||
} else {
|
||||
ff_rtsp_parse_line(reply, p, rt, method);
|
||||
av_strlcat(rt->last_reply, p, sizeof(rt->last_reply));
|
||||
@ -949,7 +959,7 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
|
||||
line_count++;
|
||||
}
|
||||
|
||||
if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0')
|
||||
if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0' && !request)
|
||||
av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));
|
||||
|
||||
content_length = reply->content_length;
|
||||
@ -964,6 +974,44 @@ int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
|
||||
else
|
||||
av_free(content);
|
||||
|
||||
if (request) {
|
||||
char buf[1024];
|
||||
char base64buf[AV_BASE64_SIZE(sizeof(buf))];
|
||||
const char* ptr = buf;
|
||||
|
||||
if (!strcmp(reply->reason, "OPTIONS")) {
|
||||
snprintf(buf, sizeof(buf), "RTSP/1.0 200 OK\r\n");
|
||||
if (reply->seq)
|
||||
av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", reply->seq);
|
||||
if (reply->session_id[0])
|
||||
av_strlcatf(buf, sizeof(buf), "Session: %s\r\n",
|
||||
reply->session_id);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "RTSP/1.0 501 Not Implemented\r\n");
|
||||
}
|
||||
av_strlcat(buf, "\r\n", sizeof(buf));
|
||||
|
||||
if (rt->control_transport == RTSP_MODE_TUNNEL) {
|
||||
av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
|
||||
ptr = base64buf;
|
||||
}
|
||||
ffurl_write(rt->rtsp_hd_out, ptr, strlen(ptr));
|
||||
|
||||
rt->last_cmd_time = av_gettime();
|
||||
/* Even if the request from the server had data, it is not the data
|
||||
* that the caller wants or expects. The memory could also be leaked
|
||||
* if the actual following reply has content data. */
|
||||
if (content_ptr)
|
||||
av_freep(content_ptr);
|
||||
/* If method is set, this is called from ff_rtsp_send_cmd,
|
||||
* where a reply to exactly this request is awaited. For
|
||||
* callers from within packet reciving, we just want to
|
||||
* return to the caller and go back to receiving packets. */
|
||||
if (method)
|
||||
goto start;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rt->seq != reply->seq) {
|
||||
av_log(s, AV_LOG_WARNING, "CSeq %d expected, %d received.\n",
|
||||
rt->seq, reply->seq);
|
||||
|
Loading…
Reference in New Issue
Block a user