mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2026-01-31 14:51:11 +03:00
alignment with cspot
This commit is contained in:
@@ -53,6 +53,7 @@ struct HTTPResponse {
|
|||||||
bool useGzip = false;
|
bool useGzip = false;
|
||||||
std::string body;
|
std::string body;
|
||||||
std::string contentType;
|
std::string contentType;
|
||||||
|
std::vector<std::string> extraHeaders = std::vector<std::string>();
|
||||||
std::unique_ptr<ResponseReader> responseReader;
|
std::unique_ptr<ResponseReader> responseReader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ namespace bell
|
|||||||
|
|
||||||
void registerHandler(RequestType requestType, const std::string &, httpHandler);
|
void registerHandler(RequestType requestType, const std::string &, httpHandler);
|
||||||
void respond(const HTTPResponse &);
|
void respond(const HTTPResponse &);
|
||||||
|
void redirectTo(const std::string&, int connectionFd);
|
||||||
void publishEvent(std::string eventName, std::string eventData);
|
void publishEvent(std::string eventName, std::string eventData);
|
||||||
void closeConnection(int connection);
|
void closeConnection(int connection);
|
||||||
void listen();
|
void listen();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#include <esp_pthread.h>
|
#include <esp_pthread.h>
|
||||||
|
#include <esp_task.h>
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
#include <freertos/timers.h>
|
#include <freertos/timers.h>
|
||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
#else
|
#else
|
||||||
|
#include <time.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,51 +1,37 @@
|
|||||||
#include "HTTPServer.h"
|
#include "HTTPServer.h"
|
||||||
|
|
||||||
bell::HTTPServer::HTTPServer(int serverPort)
|
bell::HTTPServer::HTTPServer(int serverPort) { this->serverPort = serverPort; }
|
||||||
{
|
|
||||||
this->serverPort = serverPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char bell::HTTPServer::h2int(char c)
|
unsigned char bell::HTTPServer::h2int(char c) {
|
||||||
{
|
if (c >= '0' && c <= '9') {
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
{
|
|
||||||
return ((unsigned char)c - '0');
|
return ((unsigned char)c - '0');
|
||||||
}
|
}
|
||||||
if (c >= 'a' && c <= 'f')
|
if (c >= 'a' && c <= 'f') {
|
||||||
{
|
|
||||||
return ((unsigned char)c - 'a' + 10);
|
return ((unsigned char)c - 'a' + 10);
|
||||||
}
|
}
|
||||||
if (c >= 'A' && c <= 'F')
|
if (c >= 'A' && c <= 'F') {
|
||||||
{
|
|
||||||
return ((unsigned char)c - 'A' + 10);
|
return ((unsigned char)c - 'A' + 10);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string bell::HTTPServer::urlDecode(std::string str)
|
std::string bell::HTTPServer::urlDecode(std::string str) {
|
||||||
{
|
|
||||||
std::string encodedString = "";
|
std::string encodedString = "";
|
||||||
char c;
|
char c;
|
||||||
char code0;
|
char code0;
|
||||||
char code1;
|
char code1;
|
||||||
for (int i = 0; i < str.length(); i++)
|
for (int i = 0; i < str.length(); i++) {
|
||||||
{
|
|
||||||
c = str[i];
|
c = str[i];
|
||||||
if (c == '+')
|
if (c == '+') {
|
||||||
{
|
|
||||||
encodedString += ' ';
|
encodedString += ' ';
|
||||||
}
|
} else if (c == '%') {
|
||||||
else if (c == '%')
|
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
code0 = str[i];
|
code0 = str[i];
|
||||||
i++;
|
i++;
|
||||||
code1 = str[i];
|
code1 = str[i];
|
||||||
c = (h2int(code0) << 4) | h2int(code1);
|
c = (h2int(code0) << 4) | h2int(code1);
|
||||||
encodedString += c;
|
encodedString += c;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
encodedString += c;
|
encodedString += c;
|
||||||
}
|
}
|
||||||
@@ -54,23 +40,22 @@ std::string bell::HTTPServer::urlDecode(std::string str)
|
|||||||
return encodedString;
|
return encodedString;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> bell::HTTPServer::splitUrl(const std::string &url, char delimiter)
|
std::vector<std::string> bell::HTTPServer::splitUrl(const std::string &url,
|
||||||
{
|
char delimiter) {
|
||||||
std::stringstream ssb(url);
|
std::stringstream ssb(url);
|
||||||
std::string segment;
|
std::string segment;
|
||||||
std::vector<std::string> seglist;
|
std::vector<std::string> seglist;
|
||||||
|
|
||||||
while (std::getline(ssb, segment, delimiter))
|
while (std::getline(ssb, segment, delimiter)) {
|
||||||
{
|
|
||||||
seglist.push_back(segment);
|
seglist.push_back(segment);
|
||||||
}
|
}
|
||||||
return seglist;
|
return seglist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::registerHandler(RequestType requestType, const std::string &routeUrl, httpHandler handler)
|
void bell::HTTPServer::registerHandler(RequestType requestType,
|
||||||
{
|
const std::string &routeUrl,
|
||||||
if (routes.find(routeUrl) == routes.end())
|
httpHandler handler) {
|
||||||
{
|
if (routes.find(routeUrl) == routes.end()) {
|
||||||
routes.insert({routeUrl, std::vector<HTTPRoute>()});
|
routes.insert({routeUrl, std::vector<HTTPRoute>()});
|
||||||
}
|
}
|
||||||
this->routes[routeUrl].push_back(HTTPRoute{
|
this->routes[routeUrl].push_back(HTTPRoute{
|
||||||
@@ -79,9 +64,9 @@ void bell::HTTPServer::registerHandler(RequestType requestType, const std::strin
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::listen()
|
void bell::HTTPServer::listen() {
|
||||||
{
|
BELL_LOG(info, "http", "Starting configuration server at port %d",
|
||||||
BELL_LOG(info, "http", "Starting configuration server at port %d", this->serverPort);
|
this->serverPort);
|
||||||
|
|
||||||
// setup address
|
// setup address
|
||||||
struct addrinfo hints, *server;
|
struct addrinfo hints, *server;
|
||||||
@@ -91,8 +76,8 @@ void bell::HTTPServer::listen()
|
|||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
getaddrinfo(NULL, std::to_string(serverPort).c_str(), &hints, &server);
|
getaddrinfo(NULL, std::to_string(serverPort).c_str(), &hints, &server);
|
||||||
|
|
||||||
int sockfd = socket(server->ai_family,
|
int sockfd =
|
||||||
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 i;
|
||||||
@@ -104,12 +89,12 @@ void bell::HTTPServer::listen()
|
|||||||
FD_ZERO(&activeFdSet);
|
FD_ZERO(&activeFdSet);
|
||||||
FD_SET(sockfd, &activeFdSet);
|
FD_SET(sockfd, &activeFdSet);
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
|
||||||
/* Block until input arrives on one or more active sockets. */
|
/* Block until input arrives on one or more active sockets. */
|
||||||
readFdSet = activeFdSet;
|
readFdSet = activeFdSet;
|
||||||
if (select(FD_SETSIZE, &readFdSet, NULL, NULL, NULL) < 0)
|
struct timeval tv = {0, 100000};
|
||||||
{
|
|
||||||
|
if (select(FD_SETSIZE, &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);
|
||||||
@@ -117,118 +102,101 @@ void bell::HTTPServer::listen()
|
|||||||
|
|
||||||
/* Service all the sockets with input pending. */
|
/* Service all the sockets with input pending. */
|
||||||
for (i = 0; i < FD_SETSIZE; ++i)
|
for (i = 0; i < FD_SETSIZE; ++i)
|
||||||
if (FD_ISSET(i, &readFdSet))
|
if (FD_ISSET(i, &readFdSet)) {
|
||||||
{
|
if (i == sockfd) {
|
||||||
if (i == sockfd)
|
|
||||||
{
|
|
||||||
/* Connection request on original socket. */
|
/* Connection request on original socket. */
|
||||||
int newFd;
|
int newFd;
|
||||||
incomingSockSize = sizeof(clientname);
|
incomingSockSize = sizeof(clientname);
|
||||||
newFd = accept(sockfd, (struct sockaddr *)&clientname, &incomingSockSize);
|
newFd = accept(sockfd, (struct sockaddr *)&clientname,
|
||||||
if (newFd < 0)
|
&incomingSockSize);
|
||||||
{
|
if (newFd < 0) {
|
||||||
perror("accept");
|
perror("accept");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
FD_SET(newFd, &activeFdSet);
|
FD_SET(newFd, &activeFdSet);
|
||||||
|
|
||||||
HTTPConnection conn = {
|
HTTPConnection conn = {.buffer = std::vector<uint8_t>(128),
|
||||||
.buffer = std::vector<uint8_t>(128),
|
|
||||||
.httpMethod = ""};
|
.httpMethod = ""};
|
||||||
|
|
||||||
this->connections.insert({newFd, conn});
|
this->connections.insert({newFd, conn});
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Data arriving on an already-connected socket. */
|
/* Data arriving on an already-connected socket. */
|
||||||
readFromClient(i);
|
readFromClient(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = this->connections.cbegin(); it != this->connections.cend() /* not hoisted */; /* no increment */)
|
for (auto it = this->connections.cbegin();
|
||||||
{
|
it != this->connections.cend() /* not hoisted */;
|
||||||
if ((*it).second.toBeClosed)
|
/* no increment */) {
|
||||||
{
|
if ((*it).second.toBeClosed) {
|
||||||
close((*it).first);
|
close((*it).first);
|
||||||
FD_CLR((*it).first, &activeFdSet);
|
FD_CLR((*it).first, &activeFdSet);
|
||||||
this->connections.erase(it++); // or "it = m.erase(it)" since C++11
|
this->connections.erase(
|
||||||
}
|
it++); // or "it = m.erase(it)" since C++11
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
++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, &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");
|
||||||
this->closeConnection(clientFd);
|
this->closeConnection(clientFd);
|
||||||
}
|
} else if (nbytes == 0) {
|
||||||
else if (nbytes == 0)
|
|
||||||
{
|
|
||||||
this->closeConnection(clientFd);
|
this->closeConnection(clientFd);
|
||||||
}
|
} else {
|
||||||
else
|
conn.currentLine +=
|
||||||
{
|
std::string(conn.buffer.data(), conn.buffer.data() + nbytes);
|
||||||
conn.currentLine += std::string(conn.buffer.data(), conn.buffer.data() + nbytes);
|
|
||||||
READBODY:
|
READBODY:
|
||||||
if (!conn.isReadingBody)
|
if (!conn.isReadingBody) {
|
||||||
{
|
while (conn.currentLine.find("\r\n") != std::string::npos) {
|
||||||
while (conn.currentLine.find("\r\n") != std::string::npos)
|
auto line =
|
||||||
{
|
conn.currentLine.substr(0, conn.currentLine.find("\r\n"));
|
||||||
auto line = conn.currentLine.substr(0, conn.currentLine.find("\r\n"));
|
conn.currentLine = conn.currentLine.substr(
|
||||||
conn.currentLine = conn.currentLine.substr(conn.currentLine.find("\r\n") + 2, conn.currentLine.size());
|
conn.currentLine.find("\r\n") + 2, conn.currentLine.size());
|
||||||
if (line.find("GET ") != std::string::npos || line.find("POST ") != std::string::npos || line.find("OPTIONS ") != std::string::npos)
|
if (line.find("GET ") != std::string::npos ||
|
||||||
{
|
line.find("POST ") != std::string::npos ||
|
||||||
|
line.find("OPTIONS ") != std::string::npos) {
|
||||||
conn.httpMethod = line;
|
conn.httpMethod = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.find("Content-Length: ") != std::string::npos)
|
if (line.find("Content-Length: ") != std::string::npos) {
|
||||||
{
|
conn.contentLength =
|
||||||
conn.contentLength = std::stoi(line.substr(16, line.size() - 1));
|
std::stoi(line.substr(16, line.size() - 1));
|
||||||
BELL_LOG(info, "http", "Content-Length: %d", conn.contentLength);
|
BELL_LOG(info, "http", "Content-Length: %d",
|
||||||
|
conn.contentLength);
|
||||||
}
|
}
|
||||||
if (line.size() == 0)
|
if (line.size() == 0) {
|
||||||
{
|
if (conn.contentLength != 0) {
|
||||||
if (conn.contentLength != 0)
|
|
||||||
{
|
|
||||||
conn.isReadingBody = true;
|
conn.isReadingBody = true;
|
||||||
goto READBODY;
|
goto READBODY;
|
||||||
}
|
} else {
|
||||||
else
|
findAndHandleRoute(conn.httpMethod, conn.currentLine,
|
||||||
{
|
clientFd);
|
||||||
findAndHandleRoute(conn.httpMethod, conn.currentLine, clientFd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (conn.currentLine.size() >= conn.contentLength) {
|
||||||
{
|
|
||||||
if (conn.currentLine.size() >= conn.contentLength)
|
|
||||||
{
|
|
||||||
findAndHandleRoute(conn.httpMethod, conn.currentLine, clientFd);
|
findAndHandleRoute(conn.httpMethod, conn.currentLine, clientFd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::closeConnection(int connection)
|
void bell::HTTPServer::closeConnection(int connection) {
|
||||||
{
|
|
||||||
|
|
||||||
this->connections[connection].toBeClosed = true;
|
this->connections[connection].toBeClosed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::writeResponseEvents(int connFd)
|
void bell::HTTPServer::writeResponseEvents(int connFd) {
|
||||||
{
|
|
||||||
std::lock_guard lock(this->responseMutex);
|
std::lock_guard lock(this->responseMutex);
|
||||||
|
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
@@ -238,8 +206,10 @@ void bell::HTTPServer::writeResponseEvents(int connFd)
|
|||||||
stream << "Content-type: text/event-stream\r\n";
|
stream << "Content-type: text/event-stream\r\n";
|
||||||
stream << "Cache-Control: no-cache\r\n";
|
stream << "Cache-Control: no-cache\r\n";
|
||||||
stream << "Access-Control-Allow-Origin: *\r\n";
|
stream << "Access-Control-Allow-Origin: *\r\n";
|
||||||
stream << "Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS\r\n";
|
stream << "Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, "
|
||||||
stream << "Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token\r\n";
|
"OPTIONS\r\n";
|
||||||
|
stream << "Access-Control-Allow-Headers: Origin, Content-Type, "
|
||||||
|
"X-Auth-Token\r\n";
|
||||||
stream << "\r\n";
|
stream << "\r\n";
|
||||||
|
|
||||||
auto responseStr = stream.str();
|
auto responseStr = stream.str();
|
||||||
@@ -248,14 +218,12 @@ void bell::HTTPServer::writeResponseEvents(int connFd)
|
|||||||
this->connections[connFd].isEventConnection = true;
|
this->connections[connFd].isEventConnection = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::writeResponse(const HTTPResponse &response)
|
void bell::HTTPServer::writeResponse(const HTTPResponse &response) {
|
||||||
{
|
|
||||||
std::lock_guard lock(this->responseMutex);
|
std::lock_guard lock(this->responseMutex);
|
||||||
|
|
||||||
auto fileSize = response.body.size();
|
auto fileSize = response.body.size();
|
||||||
|
|
||||||
if (response.responseReader != nullptr)
|
if (response.responseReader != nullptr) {
|
||||||
{
|
|
||||||
fileSize = response.responseReader->getTotalSize();
|
fileSize = response.responseReader->getTotalSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,20 +233,25 @@ void bell::HTTPServer::writeResponse(const HTTPResponse &response)
|
|||||||
stream << "Connection: close\r\n";
|
stream << "Connection: close\r\n";
|
||||||
stream << "Content-type: " << response.contentType << "\r\n";
|
stream << "Content-type: " << response.contentType << "\r\n";
|
||||||
|
|
||||||
if (response.useGzip)
|
if (response.useGzip) {
|
||||||
{
|
|
||||||
stream << "Content-encoding: gzip"
|
stream << "Content-encoding: gzip"
|
||||||
<< "\r\n";
|
<< "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
stream << "Content-length:" << fileSize << "\r\n";
|
|
||||||
stream << "Access-Control-Allow-Origin: *\r\n";
|
stream << "Access-Control-Allow-Origin: *\r\n";
|
||||||
stream << "Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS\r\n";
|
stream << "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS\r\n";
|
||||||
stream << "Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token\r\n";
|
stream << "Access-Control-Expose-Headers: Location\r\n";
|
||||||
|
stream << "Access-Control-Allow-Headers: Origin, Content-Type, "
|
||||||
|
"X-Auth-Token\r\n";
|
||||||
|
|
||||||
|
// go over every item in request->extraHeaders
|
||||||
|
for (auto &header : response.extraHeaders) {
|
||||||
|
stream << header << "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
stream << "\r\n";
|
stream << "\r\n";
|
||||||
|
|
||||||
if (response.body.size() > 0)
|
if (response.body.size() > 0) {
|
||||||
{
|
|
||||||
stream << response.body;
|
stream << response.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,28 +259,40 @@ void bell::HTTPServer::writeResponse(const HTTPResponse &response)
|
|||||||
|
|
||||||
write(response.connectionFd, responseStr.c_str(), responseStr.size());
|
write(response.connectionFd, responseStr.c_str(), responseStr.size());
|
||||||
|
|
||||||
if (response.responseReader != nullptr)
|
if (response.responseReader != nullptr) {
|
||||||
{
|
|
||||||
size_t read;
|
size_t read;
|
||||||
do
|
do {
|
||||||
{
|
read = response.responseReader->read(responseBuffer.data(),
|
||||||
read = response.responseReader->read(responseBuffer.data(), responseBuffer.size());
|
responseBuffer.size());
|
||||||
if (read > 0)
|
if (read > 0) {
|
||||||
{
|
|
||||||
write(response.connectionFd, responseBuffer.data(), read);
|
write(response.connectionFd, responseBuffer.data(), read);
|
||||||
}
|
}
|
||||||
} while (read > 0);
|
} while (read > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BELL_LOG(info, "HTTP", "Closing connection");
|
||||||
this->closeConnection(response.connectionFd);
|
this->closeConnection(response.connectionFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::respond(const HTTPResponse &response)
|
void bell::HTTPServer::respond(const HTTPResponse &response) {
|
||||||
{
|
|
||||||
writeResponse(response);
|
writeResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::publishEvent(std::string eventName, std::string eventData)
|
void bell::HTTPServer::redirectTo(const std::string & url, int connectionFd) {
|
||||||
{
|
std::lock_guard lock(this->responseMutex);
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << "HTTP/1.1 301 Moved Permanently\r\n";
|
||||||
|
stream << "Server: EUPHONIUM\r\n";
|
||||||
|
stream << "Connection: close\r\n";
|
||||||
|
stream << "Location: " << url << "\r\n\r\n";
|
||||||
|
auto responseStr = stream.str();
|
||||||
|
|
||||||
|
write(connectionFd, responseStr.c_str(), responseStr.size());
|
||||||
|
this->closeConnection(connectionFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bell::HTTPServer::publishEvent(std::string eventName,
|
||||||
|
std::string eventData) {
|
||||||
std::lock_guard lock(this->responseMutex);
|
std::lock_guard lock(this->responseMutex);
|
||||||
BELL_LOG(info, "http", "Publishing event");
|
BELL_LOG(info, "http", "Publishing event");
|
||||||
|
|
||||||
@@ -317,27 +302,24 @@ void bell::HTTPServer::publishEvent(std::string eventName, std::string eventData
|
|||||||
auto responseStr = stream.str();
|
auto responseStr = stream.str();
|
||||||
|
|
||||||
// Reply to all event-connections
|
// Reply to all event-connections
|
||||||
for (auto it = this->connections.cbegin(); it != this->connections.cend(); ++it)
|
for (auto it = this->connections.cbegin(); it != this->connections.cend();
|
||||||
{
|
++it) {
|
||||||
if ((*it).second.isEventConnection)
|
if ((*it).second.isEventConnection) {
|
||||||
{
|
|
||||||
write(it->first, responseStr.c_str(), responseStr.size());
|
write(it->first, responseStr.c_str(), responseStr.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::string> bell::HTTPServer::parseQueryString(const std::string &queryString)
|
std::map<std::string, std::string>
|
||||||
{
|
bell::HTTPServer::parseQueryString(const std::string &queryString) {
|
||||||
std::map<std::string, std::string> query;
|
std::map<std::string, std::string> query;
|
||||||
auto prefixedString = "&" + queryString;
|
auto prefixedString = "&" + queryString;
|
||||||
while (prefixedString.find("&") != std::string::npos)
|
while (prefixedString.find("&") != std::string::npos) {
|
||||||
{
|
|
||||||
auto keyStart = prefixedString.find("&");
|
auto keyStart = prefixedString.find("&");
|
||||||
auto keyEnd = prefixedString.find("=");
|
auto keyEnd = prefixedString.find("=");
|
||||||
// Find second occurence of "&" in prefixedString
|
// Find second occurence of "&" in prefixedString
|
||||||
auto valueEnd = prefixedString.find("&", keyStart + 1);
|
auto valueEnd = prefixedString.find("&", keyStart + 1);
|
||||||
if (valueEnd == std::string::npos)
|
if (valueEnd == std::string::npos) {
|
||||||
{
|
|
||||||
valueEnd = prefixedString.size();
|
valueEnd = prefixedString.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,13 +332,13 @@ std::map<std::string, std::string> bell::HTTPServer::parseQueryString(const std:
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bell::HTTPServer::findAndHandleRoute(std::string &url, std::string &body, int connectionFd)
|
void bell::HTTPServer::findAndHandleRoute(std::string &url, std::string &body,
|
||||||
{
|
int connectionFd) {
|
||||||
std::map<std::string, std::string> pathParams;
|
std::map<std::string, std::string> pathParams;
|
||||||
std::map<std::string, std::string> queryParams;
|
std::map<std::string, std::string> queryParams;
|
||||||
|
BELL_LOG(info, "http", "URL %s", url.c_str());
|
||||||
|
|
||||||
if (url.find("OPTIONS /") != std::string::npos)
|
if (url.find("OPTIONS /") != std::string::npos) {
|
||||||
{
|
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << "HTTP/1.1 200 OK\r\n";
|
stream << "HTTP/1.1 200 OK\r\n";
|
||||||
stream << "Server: EUPHONIUM\r\n";
|
stream << "Server: EUPHONIUM\r\n";
|
||||||
@@ -364,7 +346,8 @@ void bell::HTTPServer::findAndHandleRoute(std::string &url, std::string &body, i
|
|||||||
stream << "Connection: close\r\n";
|
stream << "Connection: close\r\n";
|
||||||
stream << "Access-Control-Allow-Origin: *\r\n";
|
stream << "Access-Control-Allow-Origin: *\r\n";
|
||||||
stream << "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n";
|
stream << "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n";
|
||||||
stream << "Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token\r\n";
|
stream << "Access-Control-Allow-Headers: Origin, Content-Type, "
|
||||||
|
"X-Auth-Token\r\n";
|
||||||
stream << "\r\n";
|
stream << "\r\n";
|
||||||
|
|
||||||
auto responseStr = stream.str();
|
auto responseStr = stream.str();
|
||||||
@@ -374,36 +357,29 @@ void bell::HTTPServer::findAndHandleRoute(std::string &url, std::string &body, i
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.find("GET /events") != std::string::npos)
|
if (url.find("GET /events") != std::string::npos) {
|
||||||
{
|
|
||||||
// Handle SSE endpoint here
|
// Handle SSE endpoint here
|
||||||
writeResponseEvents(connectionFd);
|
writeResponseEvents(connectionFd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &routeSet : this->routes)
|
for (const auto &routeSet : this->routes) {
|
||||||
{
|
for (const auto &route : routeSet.second) {
|
||||||
for (const auto &route : routeSet.second)
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string path = url;
|
std::string path = url;
|
||||||
if (url.find("GET ") != std::string::npos && route.requestType == RequestType::GET)
|
if (url.find("GET ") != std::string::npos &&
|
||||||
{
|
route.requestType == RequestType::GET) {
|
||||||
path = path.substr(4);
|
path = path.substr(4);
|
||||||
}
|
} else if (url.find("POST ") != std::string::npos &&
|
||||||
else if (url.find("POST ") != std::string::npos && route.requestType == RequestType::POST)
|
route.requestType == RequestType::POST) {
|
||||||
{
|
|
||||||
path = path.substr(5);
|
path = path.substr(5);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = path.substr(0, path.find(" "));
|
path = path.substr(0, path.find(" "));
|
||||||
|
|
||||||
if (path.find("?") != std::string::npos)
|
if (path.find("?") != std::string::npos) {
|
||||||
{
|
|
||||||
auto urlEncodedSplit = splitUrl(path, '?');
|
auto urlEncodedSplit = splitUrl(path, '?');
|
||||||
path = urlEncodedSplit[0];
|
path = urlEncodedSplit[0];
|
||||||
queryParams = this->parseQueryString(urlEncodedSplit[1]);
|
queryParams = this->parseQueryString(urlEncodedSplit[1]);
|
||||||
@@ -415,42 +391,32 @@ void bell::HTTPServer::findAndHandleRoute(std::string &url, std::string &body, i
|
|||||||
|
|
||||||
pathParams.clear();
|
pathParams.clear();
|
||||||
|
|
||||||
if (routeSplit.size() == urlSplit.size())
|
if (routeSplit.size() == urlSplit.size()) {
|
||||||
{
|
for (int x = 0; x < routeSplit.size(); x++) {
|
||||||
for (int x = 0; x < routeSplit.size(); x++)
|
if (routeSplit[x] != urlSplit[x]) {
|
||||||
{
|
if (routeSplit[x][0] == ':') {
|
||||||
if (routeSplit[x] != urlSplit[x])
|
pathParams.insert(
|
||||||
{
|
{routeSplit[x].substr(1), urlSplit[x]});
|
||||||
if (routeSplit[x][0] == ':')
|
} else {
|
||||||
{
|
|
||||||
pathParams.insert({routeSplit[x].substr(1), urlSplit[x]});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
matches = false;
|
matches = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
matches = false;
|
matches = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routeSplit.back().find("*") != std::string::npos && urlSplit[1] == routeSplit[1])
|
if (routeSplit.back().find("*") != std::string::npos &&
|
||||||
{
|
urlSplit[1] == routeSplit[1]) {
|
||||||
matches = true;
|
matches = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matches)
|
if (matches) {
|
||||||
{
|
if (body.find("&") != std::string::npos) {
|
||||||
if (body.find("&") != std::string::npos)
|
|
||||||
{
|
|
||||||
queryParams = this->parseQueryString(body);
|
queryParams = this->parseQueryString(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPRequest req = {
|
HTTPRequest req = {.urlParams = pathParams,
|
||||||
.urlParams = pathParams,
|
|
||||||
.queryParams = queryParams,
|
.queryParams = queryParams,
|
||||||
.body = body,
|
.body = body,
|
||||||
.handlerId = 0,
|
.handlerId = 0,
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ void AudioChunkManager::runTask() {
|
|||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// usleep(100*1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ std::map<MercuryType, std::string> MercuryTypeMap({
|
|||||||
{MercuryType::UNSUB, "UNSUB"},
|
{MercuryType::UNSUB, "UNSUB"},
|
||||||
});
|
});
|
||||||
|
|
||||||
MercuryManager::MercuryManager(std::unique_ptr<Session> session): bell::Task("mercuryManager", 8 * 1024, +1, 1)
|
MercuryManager::MercuryManager(std::unique_ptr<Session> session): bell::Task("mercuryManager", 6 * 1024, +1, 1)
|
||||||
{
|
{
|
||||||
this->timeProvider = std::make_shared<TimeProvider>();
|
this->timeProvider = std::make_shared<TimeProvider>();
|
||||||
this->callbacks = std::map<uint64_t, mercuryCallback>();
|
this->callbacks = std::map<uint64_t, mercuryCallback>();
|
||||||
|
|||||||
@@ -5,7 +5,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
PlainConnection::PlainConnection(){};
|
PlainConnection::PlainConnection()
|
||||||
|
{
|
||||||
|
this->apSock = -1;
|
||||||
|
};
|
||||||
|
|
||||||
PlainConnection::~PlainConnection()
|
PlainConnection::~PlainConnection()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ void Player::runTask()
|
|||||||
currentTrack->audioStream->streamFinishedCallback = nullptr;
|
currentTrack->audioStream->streamFinishedCallback = nullptr;
|
||||||
currentTrack->audioStream->audioSink = nullptr;
|
currentTrack->audioStream->audioSink = nullptr;
|
||||||
currentTrack->audioStream->pcmCallback = nullptr;
|
currentTrack->audioStream->pcmCallback = nullptr;
|
||||||
|
} else {
|
||||||
|
//usleep(100000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user