netfile: some chunked mode fixes

This commit is contained in:
Jacek Jendrzej
2020-01-17 12:22:40 +01:00
parent 685e118efd
commit 08cef8734d
2 changed files with 44 additions and 44 deletions

View File

@@ -178,6 +178,8 @@ magic_t known_magic[] =
#define is_redirect(a) ((a == 301) || (a == 302)) #define is_redirect(a) ((a == 301) || (a == 302))
static int meta_interval; /*chunked mode */
static bool chunked; /*chunked mode */
char err_txt[2048]; /* human readable error message */ char err_txt[2048]; /* human readable error message */
char redirect_url[2048]; /* new url if we've been redirected (HTTP 301/302) */ char redirect_url[2048]; /* new url if we've been redirected (HTTP 301/302) */
static int debug = 0; /* print debugging output or not */ static int debug = 0; /* print debugging output or not */
@@ -592,8 +594,10 @@ int parse_response(URL *url, void * /*opt*/, CSTATE *state)
char header[2049], /*str[255]*/ str[2049]; // combined with 2nd local str from id3 part char header[2049], /*str[255]*/ str[2049]; // combined with 2nd local str from id3 part
char *ptr, chr=0, lastchr=0; char *ptr, chr=0, lastchr=0;
int hlen = 0, response; int hlen = 0, response;
int meta_interval = 0, rval; int rval;
int fd = url->fd; int fd = url->fd;
meta_interval = 0;
chunked = false;
memset(header, 0, 2049); memset(header, 0, 2049);
ptr = header; ptr = header;
@@ -671,23 +675,12 @@ int parse_response(URL *url, void * /*opt*/, CSTATE *state)
getHeaderVal("icy-metaint:", meta_interval); getHeaderVal("icy-metaint:", meta_interval);
if(meta_interval < 0) if(meta_interval < 0)
meta_interval = 0; meta_interval = 0;
if (state != NULL)
state->meta_interval = meta_interval;
/* yet another hack: this is only implemented to be able to fetch */ /* yet another hack: this is only implemented to be able to fetch */
/* the playlists from shoutcast */ /* the playlists from shoutcast */
if(strstr(header, "Transfer-Encoding: chunked")) if(strstr(header, "Transfer-Encoding: chunked"))
{ {
readln(fd, str); chunked = true;
sscanf(str, "%x", &rval);
if (state != NULL)
{
int chunksize = rval;
if(chunksize < 0)
chunksize = 0;
state->chunksize = chunksize;
recv(fd, str, 1, 0);
}
return rval;
} }
if (state != NULL) { if (state != NULL) {
@@ -1457,7 +1450,7 @@ int push(FILE *fd, char *buf, long len)
if(amt[j] > blen) if(amt[j] > blen)
amt[j] = blen; amt[j] = blen;
if(amt[j]) if(amt[j] > 0)
{ {
memmove(cache[i].wptr, buf, amt[j]); memmove(cache[i].wptr, buf, amt[j]);
cache[i].wptr = cache[i].cache + cache[i].wptr = cache[i].cache +
@@ -1619,23 +1612,27 @@ int pop(FILE *fd, char *buf, long len)
return rval; return rval;
} }
static int http_read_stream_all(FILE *fd, char *buf, int size) static int http_read_stream_all(STREAM_CACHE *scache, char *buf, int size)
{ {
int pos = 0; int pos = 0;
while (pos < size) { while (!scache->closed && pos < size) {
int len = read(fileno(fd), buf + pos, size - pos); int len = read(fileno(scache->fd), buf + pos, size - pos);
if (len == 0) if (len <= 0)
return len; {
scache->closed = 1;
return 0;
}
pos += len; pos += len;
} }
return pos; return pos;
} }
static bool getChunkSizeLine(FILE *fd,char *line,int size) static bool getChunkSizeLine(STREAM_CACHE *scache,char *line,int size)
{ {
char c = 0; char c = 0;
int pos = 0,rn = 0,rnc = 4; int pos = 0,rn = 0,rnc = 4;
while(read(fileno(fd), &c, 1)!=0) int len = 0;
while(len = read(fileno(scache->fd), &c, 1) != 0)
{ {
if(pos >= size) if(pos >= size)
break; break;
@@ -1656,6 +1653,11 @@ static bool getChunkSizeLine(FILE *fd,char *line,int size)
break; break;
} }
} }
if (len <= 0)
{
scache->closed = 1;
return false;
}
if(c == '\n' || rn == 2) if(c == '\n' || rn == 2)
{ {
line[pos++] = 0; line[pos++] = 0;
@@ -1674,25 +1676,20 @@ void CacheFillThread(void *c)
set_threadname("netfile:cache"); set_threadname("netfile:cache");
dprintf(stderr, "CacheFillThread: thread started, using stream %p\n", scache->fd); dprintf(stderr, "CacheFillThread: thread started, using stream %p\n", scache->fd);
int bufSize = CACHEBTRANS;
if(chunked && meta_interval > 0)
bufSize = meta_interval;
int meta_interval = CACHEBTRANS; char *buf = (char*)malloc(bufSize);
if(scache->filter_arg && scache->filter_arg->state && scache->filter_arg->state->meta_interval)
meta_interval = scache->filter_arg->state->meta_interval;
char *buf = (char*)malloc(meta_interval);
if(!buf) if(!buf)
{ {
dprintf(stderr, "CacheFillThread: fatal error ! Could not allocate memory. Terminating.\n"); dprintf(stderr, "CacheFillThread: fatal error ! Could not allocate memory. Terminating.\n");
exit(-1); exit(-1);
} }
int chunkSize = 0; int chunkSize = 0;
if(scache->filter_arg && scache->filter_arg->state && scache->filter_arg->state->chunksize)
chunkSize = scache->filter_arg->state->chunksize;
int rest = 0; int rest = 0;
int rval = 0; int rval = 0;
int datalen = 0; int datalen = 0;
bool chunked = chunkSize ? true : false;
/* endless loop; read a block of data from the stream */ /* endless loop; read a block of data from the stream */
/* and push it into the cache */ /* and push it into the cache */
@@ -1701,7 +1698,7 @@ void CacheFillThread(void *c)
struct pollfd pfd; struct pollfd pfd;
/* has a f_close() call in an other thread already closed the cache ? */ /* has a f_close() call in an other thread already closed the cache ? */
datalen = meta_interval; datalen = bufSize;
pfd.fd = fileno(scache->fd); pfd.fd = fileno(scache->fd);
pfd.events = POLLIN | POLLPRI; pfd.events = POLLIN | POLLPRI;
@@ -1716,7 +1713,7 @@ void CacheFillThread(void *c)
{ {
chunkSize = 0; chunkSize = 0;
char line[32]; char line[32];
if(getChunkSizeLine(scache->fd,line,sizeof(line))) if(getChunkSizeLine(scache,line,sizeof(line)))
chunkSize = strtol(line, NULL, 16); chunkSize = strtol(line, NULL, 16);
if(!chunkSize) if(!chunkSize)
@@ -1725,7 +1722,7 @@ void CacheFillThread(void *c)
break; break;
} }
} }
datalen = meta_interval; datalen = bufSize;
if(chunkSize && chunkSize < datalen) if(chunkSize && chunkSize < datalen)
{ {
datalen = chunkSize ; datalen = chunkSize ;
@@ -1737,8 +1734,8 @@ void CacheFillThread(void *c)
} }
} }
rval = http_read_stream_all(scache->fd, buf, datalen); rval = http_read_stream_all(scache, buf, datalen);
if (rval == 0) if (rval <= 0)
break; /* exit cache fill thread if eof and nothing to push */ break; /* exit cache fill thread if eof and nothing to push */
/* if there is a filter function set up for this stream, then */ /* if there is a filter function set up for this stream, then */
/* we need to call it with the propper arguments */ /* we need to call it with the propper arguments */
@@ -1754,17 +1751,20 @@ void CacheFillThread(void *c)
break; break;
if(chunked) if(chunked)
chunkSize -= rval;
if(enable_metadata && chunked)
{ {
chunkSize -= rval;
if(chunkSize <= 0) if(chunkSize <= 0)
{ {
rest = meta_interval - rval; rest = bufSize - rval;
} }
}
if(chunked && scache->filter)
{
if(chunkSize > 0) if(chunkSize > 0)
{ {
rval = http_read_stream_all(scache->fd, buf, 1); rval = read(fileno(scache->fd), buf, 1);
if (rval <= 0)
break;
chunkSize -= rval; chunkSize -= rval;
if(rval) if(rval)
{ {
@@ -1775,7 +1775,9 @@ void CacheFillThread(void *c)
char icybuf[icybufsize]; char icybuf[icybufsize];
memset(icybuf,0, icybufsize); memset(icybuf,0, icybufsize);
int len = (ch * 16); int len = (ch * 16);
rval = http_read_stream_all(scache->fd, icybuf,len ); rval = http_read_stream_all(scache, icybuf,len );
if (rval <= 0)
break;
chunkSize -= rval; chunkSize -= rval;
ShoutCAST_ParseMetaData(icybuf, scache->filter_arg->state); ShoutCAST_ParseMetaData(icybuf, scache->filter_arg->state);
if(scache->filter_arg->state->cb) if(scache->filter_arg->state->cb)

View File

@@ -112,8 +112,6 @@ typedef struct
int state; /* CONNECTING, BUFFERING, RUNNING */ int state; /* CONNECTING, BUFFERING, RUNNING */
int bitrate; int bitrate;
int buffered; /* "waterlevel" in the cache; 0 ... 65535 */ int buffered; /* "waterlevel" in the cache; 0 ... 65535 */
int chunksize;
int meta_interval;
char station_url[1024]; /*station url */ char station_url[1024]; /*station url */
char station[1024]; /* station name */ char station[1024]; /* station name */
char genre[4096]; /* station genre */ char genre[4096]; /* station genre */