Commit 1a6b9a98 authored by Tommy Winther's avatar Tommy Winther Committed by Martin Storsjö

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: 's avatarMartin Storsjö <martin@martin.st>
parent f234e8a3
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment