📄 rtsp_resp.c
字号:
(header_types[ix].parse_routine)(after, info->decode_response, 0);
*last_number = ix;
return;
}
ix++;
}
if (last_number >= 0 && isspace(*lptr)) {
//asdf
ADV_SPACE(lptr);
(header_types[*last_number].parse_routine)(lptr, info->decode_response, 1);
} else
rtsp_debug(LOG_DEBUG, "Not processing response header: %s", lptr);
}
static int rtsp_read_into_buffer (rtsp_client_t *cptr,
uint32_t buffer_offset,
int wait)
{
int ret;
ret = rtsp_receive_socket(cptr,
cptr->m_resp_buffer + buffer_offset,
RECV_BUFF_DEFAULT_LEN - buffer_offset,
cptr->recv_timeout,
wait);
if (ret <= 0) return (ret);
cptr->m_buffer_len = buffer_offset + ret;
cptr->m_resp_buffer[cptr->m_buffer_len] = '\0';
return ret;
}
int rtsp_bytes_in_buffer (rtsp_client_t *cptr)
{
return (cptr->m_buffer_len - cptr->m_offset_on);
}
int rtsp_recv (rtsp_client_t *cptr,
char *buffer,
uint32_t len)
{
uint32_t mlen;
int copied, result;
copied = 0;
if (cptr->m_offset_on < cptr->m_buffer_len) {
mlen = MIN(len, cptr->m_buffer_len - cptr->m_offset_on);
memmove(buffer,
&cptr->m_resp_buffer[cptr->m_offset_on],
mlen);
cptr->m_offset_on += mlen;
len -= mlen;
copied += mlen;
}
if (len > 0) {
result = rtsp_receive_socket(cptr,
buffer + copied,
len,
0,
0);
if (result >= 0) {
copied += result;
}
}
return copied;
}
static int rtsp_save_and_read (rtsp_client_t *cptr)
{
int last_on;
int ret;
cptr->m_buffer_len -= cptr->m_offset_on;
if (cptr->m_buffer_len >= RECV_BUFF_DEFAULT_LEN) {
return 0;
} else if (cptr->m_buffer_len != 0) {
memmove(cptr->m_resp_buffer,
&cptr->m_resp_buffer[cptr->m_offset_on],
cptr->m_buffer_len);
last_on = cptr->m_buffer_len;
} else {
last_on = 0;
}
cptr->m_offset_on = 0;
ret = rtsp_read_into_buffer(cptr, cptr->m_buffer_len, 0);
if (ret > 0) {
last_on += ret;
}
return (last_on);
}
static const char *rtsp_get_next_line (rtsp_client_t *cptr,
const char *seperator)
{
int ret;
int last_on;
char *sep;
/*
* If we don't have any data, try to read a buffer full
*/
if (cptr->m_buffer_len <= 0) {
cptr->m_offset_on = 0;
ret = rtsp_read_into_buffer(cptr, 0, 1);
if (ret <= 0) {
return (NULL);
}
}
/*
* Look for CR/LF in the buffer. If we find it, NULL terminate at
* the CR, then set the buffer values to look past the crlf
*/
sep = strstr(&cptr->m_resp_buffer[cptr->m_offset_on],
seperator);
if (sep != NULL) {
const char *retval = &cptr->m_resp_buffer[cptr->m_offset_on];
cptr->m_offset_on = sep - cptr->m_resp_buffer;
cptr->m_offset_on += strlen(seperator);
*sep = '\0';
return (retval);
}
if (cptr->m_offset_on == 0) {
return (NULL);
}
/*
* We don't have a line. So, move the data down in the buffer, then
* read into the rest of the buffer
*/
last_on = rtsp_save_and_read(cptr);
if (last_on < 0) return (NULL);
/*
* Continue searching through the buffer. If we get this far, we've
* received like 2K or 4K without a CRLF - most likely a bad response
*/
sep = strstr(&cptr->m_resp_buffer[last_on],
seperator);
if (sep != NULL) {
const char *retval = &cptr->m_resp_buffer[cptr->m_offset_on];
cptr->m_offset_on = sep - cptr->m_resp_buffer;
cptr->m_offset_on += strlen(seperator);
*sep = '\0';
return (retval);
}
return (NULL);
}
/*
* rtsp_parse_response - parse out response headers lines. Figure out
* where seperators are, then use them to determine where the body is
*/
static int rtsp_parse_response (rtsp_client_t *info)
{
const char *seperator;
const char *lptr, *p;
rtsp_decode_t *decode;
int ret, done;
int last_header = -1;
uint32_t len;
decode = info->decode_response;
// Figure out what seperator is being used throughout the response
ret = rtsp_save_and_read(info);
if (ret < 0) {
return (RTSP_RESPONSE_RECV_ERROR);
}
seperator = find_seperator(info->m_resp_buffer);
if (seperator == NULL) {
rtsp_debug(LOG_INFO, "Could not find seperator in header");
return RTSP_RESPONSE_MALFORM_HEADER;
}
//rtsp_debug(LOG_DEBUG, "Response buffer:\n%s", info->m_resp_buffer);
do {
lptr = rtsp_get_next_line(info, seperator);
if (lptr == NULL) {
rtsp_debug(LOG_INFO, "Couldn't get next line");
return (RTSP_RESPONSE_MALFORM_HEADER);
}
} while (*lptr == '\0');
rtsp_debug(LOG_DEBUG, lptr);
if (strncasecmp(lptr, "RTSP/1.0", strlen("RTSP/1.0")) != 0) {
rtsp_debug(LOG_INFO, "RTSP/1.0 not found");
return RTSP_RESPONSE_MALFORM_HEADER;
}
p = lptr + strlen("RTSP/1.0");
ADV_SPACE(p);
memcpy(decode->retcode, p, 3);
decode->retcode[3] = '\0';
switch (*p) {
case '1':
case '2':
case '3':
case '4':
case '5':
break;
default:
rtsp_debug(LOG_INFO, "Bad error code %s", p);
return RTSP_RESPONSE_MALFORM_HEADER;
}
p += 3;
ADV_SPACE(p);
if (p != '\0') {
decode->retresp = strdup(p);
}
rtsp_debug(LOG_DEBUG, "Decoded status - code %s %s",
decode->retcode, decode->retresp);
done = 0;
do {
lptr = rtsp_get_next_line(info, seperator);
if (lptr == NULL) {
return (RTSP_RESPONSE_MALFORM_HEADER);
}
if (*lptr == '\0') {
done = 1;
} else {
rtsp_debug(LOG_DEBUG, lptr);
rtsp_decode_header(lptr, info, &last_header);
}
} while (done == 0);
if (decode->content_length != 0) {
rtsp_debug(LOG_DEBUG, "reading content length %d", decode->content_length);
decode->body = malloc(decode->content_length + 1);
decode->body[decode->content_length] = '\0';
len = info->m_buffer_len - info->m_offset_on;
rtsp_debug(LOG_DEBUG, "Copied %d bytes from buffer", len);
if (len < decode->content_length) {
// not enough in memory - need to read
memcpy(decode->body,
&info->m_resp_buffer[info->m_offset_on],
len);
while (len < decode->content_length) {
int left;
ret = rtsp_read_into_buffer(info, 0, 1);
if (ret <= 0) {
rtsp_debug(LOG_DEBUG, "Returned from rtsp_read_into_buffer - error %d",
ret);
return (-1);
}
left = decode->content_length - len;
if (left < info->m_buffer_len) {
// we have more data in the buffer then we need
memcpy(decode->body + len,
info->m_resp_buffer,
left);
len += left;
info->m_offset_on = left;
} else {
// exact or less - we're cool
memcpy(decode->body + len,
info->m_resp_buffer,
info->m_buffer_len);
len += info->m_buffer_len;
info->m_offset_on = info->m_buffer_len; // get ready for next...
}
}
} else {
// Plenty in memory - copy it, continue to end...
memcpy(decode->body,
&info->m_resp_buffer[info->m_offset_on],
decode->content_length);
info->m_offset_on += decode->content_length;
}
} else if (decode->close_connection) {
// No termination - just deal with what we've got...
len = info->m_buffer_len - info->m_offset_on;
decode->body = (char *)malloc(len + 1);
memcpy(decode->body,
&info->m_resp_buffer[info->m_offset_on],
len);
decode->body[len] = '\0';
}
if (decode->body != NULL)
rtsp_debug(LOG_DEBUG, "%s", decode->body);
return (0);
}
/*
* rtsp_get_response - wait for a complete response. Interesting that
* it could be in multiple packets, so deal with that.
*/
int rtsp_get_response (rtsp_client_t *info)
{
int ret;
rtsp_decode_t *decode;
int response_okay;
while (1) {
// In case we didn't get a response that we wanted.
if (info->decode_response != NULL) {
clear_decode_response(info->decode_response);
decode = info->decode_response;
} else {
decode = info->decode_response = malloc(sizeof(rtsp_decode_t));
if (decode == NULL) {
rtsp_debug(LOG_ALERT, "Couldn't create decode response");
return (RTSP_RESPONSE_RECV_ERROR);
}
}
memset(decode, 0, sizeof(rtsp_decode_t));
do {
// Parse response.
ret = rtsp_parse_response(info);
rtsp_debug(LOG_DEBUG, "parsed response - len %d offset %d",
info->m_buffer_len, info->m_offset_on);
if (ret != 0) {
if (info->thread == NULL)
rtsp_close_socket(info);
rtsp_debug(LOG_ERR, "return code %d from rtsp_parse_response", ret);
return (RTSP_RESPONSE_RECV_ERROR);
}
if (decode->close_connection) {
rtsp_debug(LOG_DEBUG, "Response requested connection close");
rtsp_close_socket(info);
}
response_okay = TRUE;
// Okay - we have a good response. - check the cseq, and return
// the correct error code.
if (info->next_cseq == decode->cseq) {
info->next_cseq++;
if ((decode->retcode[0] == '4') ||
(decode->retcode[0] == '5')) {
return (RTSP_RESPONSE_BAD);
}
if (decode->cookie != NULL) {
// move cookie to rtsp_client
info->cookie = strdup(decode->cookie);
}
if (decode->retcode[0] == '2') {
return (RTSP_RESPONSE_GOOD);
}
if (decode->retcode[0] == '3') {
if (decode->location == NULL) {
return (RTSP_RESPONSE_BAD);
}
if (rtsp_setup_redirect(info) != 0) {
return (RTSP_RESPONSE_BAD);
}
return (RTSP_RESPONSE_REDIRECT);
}
}
#if 0
if (info->m_buffer_len != 0) {
// We have more in the buffer - see if it's what
// we need
// clear out last response
clear_decode_response(decode);
memset(decode, 0, sizeof(rtsp_decode_t));
}
#endif
} while (info->m_buffer_len != 0);
}
return (RTSP_RESPONSE_RECV_ERROR);
}
/* end file rtsp_resp.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -