mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 13:07:03 +03:00
fix potential cspot on socket timeout & optimize HTTP server - release
This commit is contained in:
@@ -80,9 +80,8 @@ void bell::HTTPServer::listen() {
|
|||||||
socket(server->ai_family, server->ai_socktype, server->ai_protocol);
|
socket(server->ai_family, server->ai_socktype, server->ai_protocol);
|
||||||
struct sockaddr_in clientname;
|
struct sockaddr_in clientname;
|
||||||
socklen_t incomingSockSize;
|
socklen_t incomingSockSize;
|
||||||
int i;
|
|
||||||
int yes = true;
|
int yes = true;
|
||||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) {
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*) &yes, sizeof(int)) < 0) {
|
||||||
throw std::runtime_error("setsockopt failed: " +
|
throw std::runtime_error("setsockopt failed: " +
|
||||||
std::string(strerror(errno)));
|
std::string(strerror(errno)));
|
||||||
}
|
}
|
||||||
@@ -100,22 +99,19 @@ void bell::HTTPServer::listen() {
|
|||||||
FD_ZERO(&activeFdSet);
|
FD_ZERO(&activeFdSet);
|
||||||
FD_SET(sockfd, &activeFdSet);
|
FD_SET(sockfd, &activeFdSet);
|
||||||
|
|
||||||
for (;;) {
|
for (int maxfd = sockfd;;) {
|
||||||
/* Block until input arrives on one or more active sockets. */
|
/* Block until input arrives on one or more active sockets. */
|
||||||
readFdSet = activeFdSet;
|
readFdSet = activeFdSet;
|
||||||
struct timeval tv = {0, 100000};
|
struct timeval tv = {0, 100000};
|
||||||
|
|
||||||
if (select(FD_SETSIZE, &readFdSet, NULL, NULL, &tv) < 0) {
|
if (select(maxfd + 1, &readFdSet, NULL, NULL, &tv) < 0) {
|
||||||
BELL_LOG(error, "http", "Error in select");
|
BELL_LOG(error, "http", "Error in select");
|
||||||
perror("select");
|
perror("select");
|
||||||
// exit(EXIT_FAILURE);
|
// exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Service all the sockets with input pending. */
|
/* Service listening socket. */
|
||||||
for (i = 0; i < FD_SETSIZE; ++i)
|
if (FD_ISSET(sockfd, &readFdSet)) {
|
||||||
if (FD_ISSET(i, &readFdSet)) {
|
|
||||||
if (i == sockfd) {
|
|
||||||
/* Connection request on original socket. */
|
|
||||||
int newFd;
|
int newFd;
|
||||||
incomingSockSize = sizeof(clientname);
|
incomingSockSize = sizeof(clientname);
|
||||||
newFd = accept(sockfd, (struct sockaddr*)&clientname,
|
newFd = accept(sockfd, (struct sockaddr*)&clientname,
|
||||||
@@ -131,31 +127,37 @@ void bell::HTTPServer::listen() {
|
|||||||
.httpMethod = "" };
|
.httpMethod = "" };
|
||||||
|
|
||||||
this->connections.insert({ newFd, conn });
|
this->connections.insert({ newFd, conn });
|
||||||
} else {
|
|
||||||
/* Data arriving on an already-connected socket. */
|
|
||||||
readFromClient(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Service other sockets and update set & max */
|
||||||
|
maxfd = sockfd;
|
||||||
for (auto it = this->connections.cbegin();
|
for (auto it = this->connections.cbegin();
|
||||||
it != this->connections.cend() /* not hoisted */;
|
it != this->connections.cend() /* not hoisted */;
|
||||||
/* no increment */) {
|
/* no increment */) {
|
||||||
|
int fd = (*it).first;
|
||||||
if ((*it).second.toBeClosed) {
|
if ((*it).second.toBeClosed) {
|
||||||
close((*it).first);
|
close(fd);
|
||||||
FD_CLR((*it).first, &activeFdSet);
|
FD_CLR(fd, &activeFdSet);
|
||||||
this->connections.erase(
|
this->connections.erase(
|
||||||
it++); // or "it = m.erase(it)" since C++11
|
it++); // or "it = m.erase(it)" since C++11
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
|
if (fd != sockfd && FD_ISSET(fd, &readFdSet)) {
|
||||||
|
/* Data arriving on an already-connected socket. */
|
||||||
|
readFromClient(fd);
|
||||||
|
}
|
||||||
|
if (fd > maxfd) maxfd = fd;
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::readFromClient(int clientFd) {
|
void bell::HTTPServer::readFromClient(int clientFd) {
|
||||||
HTTPConnection &conn = this->connections[clientFd];
|
HTTPConnection &conn = this->connections[clientFd];
|
||||||
|
|
||||||
int nbytes = recv(clientFd, &conn.buffer[0], conn.buffer.size(), 0);
|
int nbytes = recv(clientFd, (char*) &conn.buffer[0], conn.buffer.size(), 0);
|
||||||
if (nbytes < 0) {
|
if (nbytes < 0) {
|
||||||
BELL_LOG(error, "http", "Error reading from client");
|
BELL_LOG(error, "http", "Error reading from client");
|
||||||
perror("recv");
|
perror("recv");
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ std::vector<uint8_t> PlainConnection::readBlock(size_t size)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (retries++ > 4) throw std::runtime_error("Error in read");
|
if (retries++ > 4) throw std::runtime_error("Error in read");
|
||||||
|
goto READ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx += n;
|
idx += n;
|
||||||
|
|||||||
Reference in New Issue
Block a user