mirror of
https://github.com/curl/curl.git
synced 2026-07-29 02:13:05 +03:00
RTSP: improved RTP parser
- fix HTTP header parsing to report incomplete lines it buffers as consumed! - re-implement the RTP parser for interleave RTP messages for robustness. It is now keeping its state at the connection - RTSP protocol handler "readwrite" implementation now tracks if the response is before/in/after header parsing or "in" a bod by calling "Curl_http_readwrite_headers()" itself. This allows it to know when non-RTP bytes are "junk" or HEADER or BODY. - tested with #12035 and various small receive sizes where current master fails Closes #12052
This commit is contained in:
parent
117c9bd978
commit
7eb31c852d
4 changed files with 280 additions and 160 deletions
|
|
@ -423,7 +423,6 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
|||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
ssize_t nread; /* number of bytes read */
|
||||
size_t excess = 0; /* excess bytes read */
|
||||
bool readmore = FALSE; /* used by RTP to signal for more data */
|
||||
int maxloops = 100;
|
||||
curl_off_t max_recv = data->set.max_recv_speed?
|
||||
|
|
@ -439,6 +438,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
|||
read or we get a CURLE_AGAIN */
|
||||
do {
|
||||
bool is_empty_data = FALSE;
|
||||
size_t excess = 0; /* excess bytes read */
|
||||
size_t buffersize = data->set.buffer_size;
|
||||
size_t bytestoread = buffersize;
|
||||
/* For HTTP/2 and HTTP/3, read data without caring about the content
|
||||
|
|
@ -555,9 +555,11 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
|||
is non-headers. */
|
||||
if(!k->header && (nread > 0 || is_empty_data)) {
|
||||
|
||||
if(data->req.no_body) {
|
||||
if(data->req.no_body && nread > 0) {
|
||||
/* data arrives although we want none, bail out */
|
||||
streamclose(conn, "ignoring body");
|
||||
DEBUGF(infof(data, "did not want a BODY, but seeing %zd bytes",
|
||||
nread));
|
||||
*done = TRUE;
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
goto out;
|
||||
|
|
@ -642,17 +644,6 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
|||
(k->bytecount + nread >= k->maxdownload)) {
|
||||
|
||||
excess = (size_t)(k->bytecount + nread - k->maxdownload);
|
||||
if(excess > 0 && !k->ignorebody) {
|
||||
infof(data,
|
||||
"Excess found in a read:"
|
||||
" excess = %zu"
|
||||
", size = %" CURL_FORMAT_CURL_OFF_T
|
||||
", maxdownload = %" CURL_FORMAT_CURL_OFF_T
|
||||
", bytecount = %" CURL_FORMAT_CURL_OFF_T,
|
||||
excess, k->size, k->maxdownload, k->bytecount);
|
||||
connclose(conn, "excess found in a read");
|
||||
}
|
||||
|
||||
nread = (ssize_t) (k->maxdownload - k->bytecount);
|
||||
if(nread < 0) /* this should be unusual */
|
||||
nread = 0;
|
||||
|
|
@ -718,24 +709,39 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
|||
|
||||
} /* if(!header and data to read) */
|
||||
|
||||
if(conn->handler->readwrite && excess) {
|
||||
/* Parse the excess data */
|
||||
k->str += nread;
|
||||
if(excess > 0 && !k->ignorebody) {
|
||||
if(conn->handler->readwrite) {
|
||||
/* Give protocol handler a chance to do something with it */
|
||||
k->str += nread;
|
||||
if(&k->str[excess] > &buf[data->set.buffer_size]) {
|
||||
/* the excess amount was too excessive(!), make sure
|
||||
it doesn't read out of buffer */
|
||||
excess = &buf[data->set.buffer_size] - k->str;
|
||||
}
|
||||
nread = (ssize_t)excess;
|
||||
result = conn->handler->readwrite(data, conn, &nread, &readmore);
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
if(&k->str[excess] > &buf[data->set.buffer_size]) {
|
||||
/* the excess amount was too excessive(!), make sure
|
||||
it doesn't read out of buffer */
|
||||
excess = &buf[data->set.buffer_size] - k->str;
|
||||
if(readmore) {
|
||||
DEBUGASSERT(nread == 0);
|
||||
k->keepon |= KEEP_RECV; /* we're not done reading */
|
||||
}
|
||||
else if(nread == 0)
|
||||
break;
|
||||
/* protocol handler did not consume all excess data */
|
||||
excess = nread;
|
||||
}
|
||||
if(excess) {
|
||||
infof(data,
|
||||
"Excess found in a read:"
|
||||
" excess = %zu"
|
||||
", size = %" CURL_FORMAT_CURL_OFF_T
|
||||
", maxdownload = %" CURL_FORMAT_CURL_OFF_T
|
||||
", bytecount = %" CURL_FORMAT_CURL_OFF_T,
|
||||
excess, k->size, k->maxdownload, k->bytecount);
|
||||
connclose(conn, "excess found in a read");
|
||||
}
|
||||
nread = (ssize_t)excess;
|
||||
|
||||
result = conn->handler->readwrite(data, conn, &nread, &readmore);
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
if(readmore)
|
||||
k->keepon |= KEEP_RECV; /* we're not done reading */
|
||||
break;
|
||||
}
|
||||
|
||||
if(is_empty_data) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue