mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-09-29 04:25:55 -04:00
Feature: Implemented a way to put back data read from a connection
This commit is contained in:
parent
460477230d
commit
f370e88335
@ -271,6 +271,12 @@ void connection_uses_tls(connection_t *con)
|
|||||||
if (con->tls)
|
if (con->tls)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (con->readbufferlen) {
|
||||||
|
ICECAST_LOG_ERROR("Connection is now using TLS but has data put back. BAD. Discarding putback data.");
|
||||||
|
free(con->readbuffer);
|
||||||
|
con->readbufferlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
con->tlsmode = ICECAST_TLSMODE_RFC2818;
|
con->tlsmode = ICECAST_TLSMODE_RFC2818;
|
||||||
con->read = connection_read_tls;
|
con->read = connection_read_tls;
|
||||||
con->send = connection_send_tls;
|
con->send = connection_send_tls;
|
||||||
@ -282,7 +288,70 @@ void connection_uses_tls(connection_t *con)
|
|||||||
|
|
||||||
ssize_t connection_read_bytes(connection_t *con, void *buf, size_t len)
|
ssize_t connection_read_bytes(connection_t *con, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
return con->read(con, buf, len);
|
ssize_t done = 0;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
if (con->readbufferlen) {
|
||||||
|
ICECAST_LOG_DEBUG("On connection %p we read from putback buffer, filled with %zu bytes, requested are %zu bytes", con, con->readbufferlen, len);
|
||||||
|
if (len >= con->readbufferlen) {
|
||||||
|
memcpy(buf, con->readbuffer, con->readbufferlen);
|
||||||
|
free(con->readbuffer);
|
||||||
|
if (len == con->readbufferlen) {
|
||||||
|
con->readbufferlen = 0;
|
||||||
|
return len;
|
||||||
|
} else {
|
||||||
|
len -= con->readbufferlen;
|
||||||
|
buf += con->readbufferlen;
|
||||||
|
done = con->readbufferlen;
|
||||||
|
con->readbufferlen = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(buf, con->readbuffer, len);
|
||||||
|
memmove(con->readbuffer, con->readbuffer+len, con->readbufferlen-len);
|
||||||
|
con->readbufferlen -= len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = con->read(con, buf, len);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
if (done == 0) {
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return done + ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int connection_read_put_back(connection_t *con, const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
void *n;
|
||||||
|
|
||||||
|
if (con->readbufferlen) {
|
||||||
|
n = realloc(con->readbuffer, con->readbufferlen + len);
|
||||||
|
if (!n)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy(n + con->readbufferlen, buf, len);
|
||||||
|
con->readbuffer = n;
|
||||||
|
con->readbufferlen += len;
|
||||||
|
|
||||||
|
ICECAST_LOG_DEBUG("On connection %p %zu bytes have been put back.", con, len);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
n = malloc(len);
|
||||||
|
if (!n)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy(n, buf, len);
|
||||||
|
con->readbuffer = n;
|
||||||
|
con->readbufferlen = len;
|
||||||
|
ICECAST_LOG_DEBUG("On connection %p %zu bytes have been put back.", con, len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static sock_t wait_for_serversock(int timeout)
|
static sock_t wait_for_serversock(int timeout)
|
||||||
@ -1043,13 +1112,10 @@ static void _handle_shoutcast_compatible(client_queue_t *node)
|
|||||||
httpp_initialize(parser, NULL);
|
httpp_initialize(parser, NULL);
|
||||||
if (httpp_parse(parser, http_compliant, strlen(http_compliant))) {
|
if (httpp_parse(parser, http_compliant, strlen(http_compliant))) {
|
||||||
/* we may have more than just headers, so prepare for it */
|
/* we may have more than just headers, so prepare for it */
|
||||||
if (node->stream_offset == node->offset) {
|
if (node->stream_offset != node->offset) {
|
||||||
client->refbuf->len = 0;
|
connection_read_put_back(client->con, client->refbuf->data + node->stream_offset, node->offset - node->stream_offset);
|
||||||
} else {
|
|
||||||
char *ptr = client->refbuf->data;
|
|
||||||
client->refbuf->len = node->offset - node->stream_offset;
|
|
||||||
memmove(ptr, ptr + node->stream_offset, client->refbuf->len);
|
|
||||||
}
|
}
|
||||||
|
client->refbuf->len = 0;
|
||||||
client->parser = parser;
|
client->parser = parser;
|
||||||
client->protocol = ICECAST_PROTOCOL_SHOUTCAST;
|
client->protocol = ICECAST_PROTOCOL_SHOUTCAST;
|
||||||
node->shoutcast = 0;
|
node->shoutcast = 0;
|
||||||
@ -1402,13 +1468,10 @@ static void _handle_connection(void)
|
|||||||
const char *upgrade, *connection;
|
const char *upgrade, *connection;
|
||||||
|
|
||||||
/* we may have more than just headers, so prepare for it */
|
/* we may have more than just headers, so prepare for it */
|
||||||
if (node->stream_offset == node->offset) {
|
if (node->stream_offset != node->offset) {
|
||||||
client->refbuf->len = 0;
|
connection_read_put_back(client->con, client->refbuf->data + node->stream_offset, node->offset - node->stream_offset);
|
||||||
} else {
|
|
||||||
char *ptr = client->refbuf->data;
|
|
||||||
client->refbuf->len = node->offset - node->stream_offset;
|
|
||||||
memmove (ptr, ptr + node->stream_offset, client->refbuf->len);
|
|
||||||
}
|
}
|
||||||
|
client->refbuf->len = 0;
|
||||||
|
|
||||||
rawuri = httpp_getvar(parser, HTTPP_VAR_URI);
|
rawuri = httpp_getvar(parser, HTTPP_VAR_URI);
|
||||||
|
|
||||||
@ -1579,5 +1642,7 @@ void connection_close(connection_t *con)
|
|||||||
sock_close(con->sock);
|
sock_close(con->sock);
|
||||||
if (con->ip)
|
if (con->ip)
|
||||||
free(con->ip);
|
free(con->ip);
|
||||||
|
if (con->readbufferlen)
|
||||||
|
free(con->readbuffer);
|
||||||
free(con);
|
free(con);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,9 @@ struct connection_tag {
|
|||||||
int (*send)(connection_t *handle, const void *buf, size_t len);
|
int (*send)(connection_t *handle, const void *buf, size_t len);
|
||||||
int (*read)(connection_t *handle, void *buf, size_t len);
|
int (*read)(connection_t *handle, void *buf, size_t len);
|
||||||
|
|
||||||
|
void *readbuffer;
|
||||||
|
size_t readbufferlen;
|
||||||
|
|
||||||
char *ip;
|
char *ip;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,6 +58,7 @@ void connection_queue(connection_t *con);
|
|||||||
void connection_uses_tls(connection_t *con);
|
void connection_uses_tls(connection_t *con);
|
||||||
|
|
||||||
ssize_t connection_read_bytes(connection_t *con, void *buf, size_t len);
|
ssize_t connection_read_bytes(connection_t *con, void *buf, size_t len);
|
||||||
|
int connection_read_put_back(connection_t *con, const void *buf, size_t len);
|
||||||
|
|
||||||
extern rwlock_t _source_shutdown_rwlock;
|
extern rwlock_t _source_shutdown_rwlock;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user