mirror of
https://github.com/SuperBFG7/ympd
synced 2025-07-24 04:02:50 +00:00
Fix: move webserver in separate source files
This commit is contained in:
parent
b65a5de933
commit
33f252734b
@ -14,10 +14,18 @@ else()
|
|||||||
set(DEBUG "ON")
|
set(DEBUG "ON")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||||
|
MESSAGE("++ 64 bit architecture")
|
||||||
|
set(PKGARCH64 "ON")
|
||||||
|
else()
|
||||||
|
MESSAGE("++ 32 bit architecture")
|
||||||
|
set(PKGARCH64 "OFF")
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(LibMPDClient REQUIRED)
|
find_package(LibMPDClient REQUIRED)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
configure_file(src/config.h.in ${PROJECT_BINARY_DIR}/config.h)
|
configure_file(src/global.h.in ${PROJECT_BINARY_DIR}/global.h)
|
||||||
include_directories(${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} ${LIBMPDCLIENT_INCLUDE_DIR})
|
include_directories(${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} ${LIBMPDCLIENT_INCLUDE_DIR})
|
||||||
|
|
||||||
include(CheckCSourceCompiles)
|
include(CheckCSourceCompiles)
|
||||||
@ -35,7 +43,7 @@ set(SOURCES
|
|||||||
src/web_server.c
|
src/web_server.c
|
||||||
src/list.c
|
src/list.c
|
||||||
src/tiny_queue.c
|
src/tiny_queue.c
|
||||||
src/common.c
|
src/global.c
|
||||||
dist/src/mongoose/mongoose.c
|
dist/src/mongoose/mongoose.c
|
||||||
dist/src/frozen/frozen.c
|
dist/src/frozen/frozen.c
|
||||||
dist/src/inih/ini.c
|
dist/src/inih/ini.c
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
/* myMPD
|
|
||||||
(c) 2018 Juergen Mang <mail@jcgames.de>
|
|
||||||
This project's homepage is: https://github.com/jcorporation/ympd
|
|
||||||
|
|
||||||
myMPD ist fork of:
|
|
||||||
|
|
||||||
ympd
|
|
||||||
(c) 2013-2014 Andrew Karpow <andy@ndyk.de>
|
|
||||||
This project's homepage is: http://www.ympd.org
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CONFIG_H__
|
|
||||||
#define __CONFIG_H__
|
|
||||||
|
|
||||||
#define MYMPD_VERSION_MAJOR ${CPACK_PACKAGE_VERSION_MAJOR}
|
|
||||||
#define MYMPD_VERSION_MINOR ${CPACK_PACKAGE_VERSION_MINOR}
|
|
||||||
#define MYMPD_VERSION_PATCH ${CPACK_PACKAGE_VERSION_PATCH}
|
|
||||||
#define MYMPD_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
|
|
||||||
#define SRC_PATH "${ASSETS_PATH}"
|
|
||||||
#cmakedefine DEBUG
|
|
||||||
#endif
|
|
@ -22,11 +22,10 @@
|
|||||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "common.h"
|
#include "global.h"
|
||||||
|
|
||||||
void sanitize_string(const char *data) {
|
void sanitize_string(const char *data) {
|
||||||
static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz"
|
static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz"
|
@ -22,19 +22,39 @@
|
|||||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __COMMON_H__
|
#ifndef __GLOBAL_H__
|
||||||
#define __COMMON_H__
|
#define __GLOBAL_H__
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
//architecture
|
||||||
|
#cmakedefine PKGARCH64
|
||||||
|
|
||||||
|
//myMPD version from cmake
|
||||||
|
#define MYMPD_VERSION_MAJOR ${CPACK_PACKAGE_VERSION_MAJOR}
|
||||||
|
#define MYMPD_VERSION_MINOR ${CPACK_PACKAGE_VERSION_MINOR}
|
||||||
|
#define MYMPD_VERSION_PATCH ${CPACK_PACKAGE_VERSION_PATCH}
|
||||||
|
#define MYMPD_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
|
||||||
|
|
||||||
|
//Webserver document root
|
||||||
|
#define DOC_ROOT "${ASSETS_PATH}"
|
||||||
|
|
||||||
|
//Max size of mpd_client response buffer
|
||||||
#define MAX_SIZE 2048 * 400
|
#define MAX_SIZE 2048 * 400
|
||||||
#define MAX_ELEMENTS_PER_PAGE 400
|
#define MAX_ELEMENTS_PER_PAGE 400
|
||||||
|
|
||||||
|
//central logging definition
|
||||||
|
#cmakedefine DEBUG
|
||||||
#define LOG_INFO() if (config.loglevel >= 1)
|
#define LOG_INFO() if (config.loglevel >= 1)
|
||||||
#define LOG_VERBOSE() if (config.loglevel >= 2)
|
#define LOG_VERBOSE() if (config.loglevel >= 2)
|
||||||
#define LOG_DEBUG() if (config.loglevel == 3)
|
#define LOG_DEBUG() if (config.loglevel == 3)
|
||||||
|
|
||||||
|
//signal handler
|
||||||
|
sig_atomic_t s_signal_received;
|
||||||
|
|
||||||
|
//myMPD configuration
|
||||||
typedef struct {
|
typedef struct {
|
||||||
long mpdport;
|
long mpdport;
|
||||||
const char *mpdhost;
|
const char *mpdhost;
|
@ -30,12 +30,10 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <mpd/client.h>
|
#include <mpd/client.h>
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "mpd_client.h"
|
#include "mpd_client.h"
|
||||||
#include "web_server.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "../dist/src/frozen/frozen.h"
|
#include "../dist/src/frozen/frozen.h"
|
||||||
|
|
||||||
const char * mpd_cmd_strs[] = {
|
const char * mpd_cmd_strs[] = {
|
||||||
@ -820,7 +818,11 @@ void mympd_api(struct work_request_t *request) {
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
|
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
|
||||||
uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
|
uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
|
||||||
|
#ifdef PKGARCH44
|
||||||
fprintf(stderr, "DEBUG: Time used: %lu\n", delta_us);
|
fprintf(stderr, "DEBUG: Time used: %lu\n", delta_us);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "DEBUG: Time used: %llu\n", delta_us);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
@ -1835,7 +1837,7 @@ int mympd_get_cover(const char *uri, char *cover, int cover_len) {
|
|||||||
path += 8;
|
path += 8;
|
||||||
replacechar(path, '/', '_');
|
replacechar(path, '/', '_');
|
||||||
replacechar(path, '.', '_');
|
replacechar(path, '.', '_');
|
||||||
snprintf(cover, cover_len, "%s/pics/%s.png", SRC_PATH, path);
|
snprintf(cover, cover_len, "%s/pics/%s.png", DOC_ROOT, path);
|
||||||
if (access(cover, F_OK ) == -1 )
|
if (access(cover, F_OK ) == -1 )
|
||||||
len = snprintf(cover, cover_len, "/assets/coverimage-httpstream.png");
|
len = snprintf(cover, cover_len, "/assets/coverimage-httpstream.png");
|
||||||
else
|
else
|
||||||
@ -1846,7 +1848,7 @@ int mympd_get_cover(const char *uri, char *cover, int cover_len) {
|
|||||||
else {
|
else {
|
||||||
if (mpd.feat_library) {
|
if (mpd.feat_library) {
|
||||||
dirname(path);
|
dirname(path);
|
||||||
snprintf(cover, cover_len, "%s/library/%s/%s", SRC_PATH, path, config.coverimagename);
|
snprintf(cover, cover_len, "%s/library/%s/%s", DOC_ROOT, path, config.coverimagename);
|
||||||
if (access(cover, F_OK ) == -1 )
|
if (access(cover, F_OK ) == -1 )
|
||||||
len = snprintf(cover, cover_len, "/assets/coverimage-notavailable.png");
|
len = snprintf(cover, cover_len, "/assets/coverimage-notavailable.png");
|
||||||
else
|
else
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#ifndef __MPD_CLIENT_H__
|
#ifndef __MPD_CLIENT_H__
|
||||||
#define __MPD_CLIENT_H__
|
#define __MPD_CLIENT_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "global.h"
|
||||||
#include "web_server.h"
|
#include "web_server.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "tiny_queue.h"
|
#include "tiny_queue.h"
|
||||||
|
104
src/mympd.c
104
src/mympd.c
@ -31,16 +31,13 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <mpd/client.h>
|
#include <mpd/client.h>
|
||||||
|
|
||||||
#include "../dist/src/mongoose/mongoose.h"
|
|
||||||
#include "../dist/src/inih/ini.h"
|
#include "../dist/src/inih/ini.h"
|
||||||
#include "common.h"
|
#include "global.h"
|
||||||
#include "mpd_client.h"
|
#include "mpd_client.h"
|
||||||
#include "web_server.h"
|
#include "web_server.h"
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
static sig_atomic_t s_signal_received = 0;
|
|
||||||
|
|
||||||
static void signal_handler(int sig_num) {
|
static void signal_handler(int sig_num) {
|
||||||
signal(sig_num, signal_handler); // Reinstantiate signal handler
|
signal(sig_num, signal_handler); // Reinstantiate signal handler
|
||||||
@ -307,33 +304,8 @@ void *mpd_client_thread() {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *web_server_thread(void *arg) {
|
|
||||||
struct mg_mgr *mgr = (struct mg_mgr *) arg;
|
|
||||||
while (s_signal_received == 0) {
|
|
||||||
mg_mgr_poll(mgr, 10);
|
|
||||||
unsigned web_server_queue_length = tiny_queue_length(web_server_queue);
|
|
||||||
if (web_server_queue_length > 0) {
|
|
||||||
struct work_result_t *response = tiny_queue_shift(web_server_queue);
|
|
||||||
if (response->conn_id == 0) {
|
|
||||||
//Websocket notify from mpd idle
|
|
||||||
send_ws_notify(mgr, response);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//api response
|
|
||||||
send_api_response(mgr, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mg_mgr_free(mgr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
struct mg_mgr mgr;
|
s_signal_received = 0;
|
||||||
struct mg_connection *nc;
|
|
||||||
struct mg_connection *nc_http;
|
|
||||||
struct mg_bind_opts bind_opts;
|
|
||||||
const char *err;
|
|
||||||
char testdirname[400];
|
char testdirname[400];
|
||||||
mpd_client_queue = tiny_queue_create();
|
mpd_client_queue = tiny_queue_create();
|
||||||
web_server_queue = tiny_queue_create();
|
web_server_queue = tiny_queue_create();
|
||||||
@ -385,7 +357,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("myMPD %s\n"
|
printf("myMPD %s\n"
|
||||||
"Copyright (C) 2018 Juergen Mang <mail@jcgames.de>\n"
|
"Copyright (C) 2018-2019 Juergen Mang <mail@jcgames.de>\n"
|
||||||
"https://github.com/jcorporation/myMPD\n"
|
"https://github.com/jcorporation/myMPD\n"
|
||||||
"Built " __DATE__ " "__TIME__"\n\n"
|
"Built " __DATE__ " "__TIME__"\n\n"
|
||||||
"Usage: %s /path/to/mympd.conf\n",
|
"Usage: %s /path/to/mympd.conf\n",
|
||||||
@ -405,67 +377,45 @@ int main(int argc, char **argv) {
|
|||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
setvbuf(stderr, NULL, _IOLBF, 0);
|
setvbuf(stderr, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
mg_mgr_init(&mgr, NULL);
|
//init webserver
|
||||||
|
if (!web_server_init()) {
|
||||||
if (config.ssl == true) {
|
|
||||||
nc_http = mg_bind(&mgr, config.webport, ev_handler_redirect);
|
|
||||||
if (nc_http == NULL) {
|
|
||||||
printf("Error listening on port %s\n", config.webport);
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
memset(&bind_opts, 0, sizeof(bind_opts));
|
|
||||||
bind_opts.ssl_cert = config.sslcert;
|
|
||||||
bind_opts.ssl_key = config.sslkey;
|
|
||||||
bind_opts.error_string = &err;
|
|
||||||
|
|
||||||
nc = mg_bind_opt(&mgr, config.sslport, ev_handler, bind_opts);
|
|
||||||
if (nc == NULL) {
|
|
||||||
printf("Error listening on port %s: %s\n", config.sslport, err);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nc = mg_bind(&mgr, config.webport, ev_handler);
|
|
||||||
if (nc == NULL) {
|
|
||||||
printf("Error listening on port %s\n", config.webport);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//drop privileges
|
||||||
if (config.user != NULL) {
|
if (config.user != NULL) {
|
||||||
LOG_INFO() printf("Droping privileges to %s\n", config.user);
|
LOG_INFO() printf("Droping privileges to %s\n", config.user);
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
if ((pw = getpwnam(config.user)) == NULL) {
|
if ((pw = getpwnam(config.user)) == NULL) {
|
||||||
printf("getpwnam() failed, unknown user\n");
|
printf("getpwnam() failed, unknown user\n");
|
||||||
mg_mgr_free(&mgr);
|
web_server_free();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} else if (setgroups(0, NULL) != 0) {
|
} else if (setgroups(0, NULL) != 0) {
|
||||||
printf("setgroups() failed\n");
|
printf("setgroups() failed\n");
|
||||||
mg_mgr_free(&mgr);
|
web_server_free();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} else if (setgid(pw->pw_gid) != 0) {
|
} else if (setgid(pw->pw_gid) != 0) {
|
||||||
printf("setgid() failed\n");
|
printf("setgid() failed\n");
|
||||||
mg_mgr_free(&mgr);
|
web_server_free();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} else if (setuid(pw->pw_uid) != 0) {
|
} else if (setuid(pw->pw_uid) != 0) {
|
||||||
printf("setuid() failed\n");
|
printf("setuid() failed\n");
|
||||||
mg_mgr_free(&mgr);
|
web_server_free();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getuid() == 0) {
|
if (getuid() == 0) {
|
||||||
printf("myMPD should not be run with root privileges\n");
|
printf("myMPD should not be run with root privileges\n");
|
||||||
mg_mgr_free(&mgr);
|
web_server_free();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!testdir("Document root", SRC_PATH))
|
//check needed directories
|
||||||
|
if (!testdir("Document root", DOC_ROOT))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
snprintf(testdirname, 400, "%s/library", SRC_PATH);
|
snprintf(testdirname, 400, "%s/library", DOC_ROOT);
|
||||||
if (testdir("Link to mpd music_directory", testdirname)) {
|
if (testdir("Link to mpd music_directory", testdirname)) {
|
||||||
LOG_INFO() printf("Enabling featLibrary support\n");
|
LOG_INFO() printf("Enabling featLibrary support\n");
|
||||||
mpd.feat_library = true;
|
mpd.feat_library = true;
|
||||||
@ -487,40 +437,38 @@ int main(int argc, char **argv) {
|
|||||||
if (!testdir("State dir", testdirname))
|
if (!testdir("State dir", testdirname))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
//read myMPD states under config.varlibdir
|
||||||
read_statefiles();
|
read_statefiles();
|
||||||
|
|
||||||
|
//read system command files
|
||||||
list_init(&syscmds);
|
list_init(&syscmds);
|
||||||
read_syscmds();
|
read_syscmds();
|
||||||
list_sort_by_value(&syscmds, true);
|
list_sort_by_value(&syscmds, true);
|
||||||
|
|
||||||
|
//init lists for tag handling
|
||||||
list_init(&mpd_tags);
|
list_init(&mpd_tags);
|
||||||
list_init(&mympd_tags);
|
list_init(&mympd_tags);
|
||||||
|
|
||||||
|
//read last played songs history file
|
||||||
list_init(&last_played);
|
list_init(&last_played);
|
||||||
LOG_INFO() printf("Reading last played songs: %d\n", read_last_played());
|
LOG_INFO() printf("Reading last played songs: %d\n", read_last_played());
|
||||||
|
|
||||||
if (config.ssl == true)
|
//Create working threads
|
||||||
mg_set_protocol_http_websocket(nc_http);
|
|
||||||
|
|
||||||
mg_set_protocol_http_websocket(nc);
|
|
||||||
s_http_server_opts.document_root = SRC_PATH;
|
|
||||||
s_http_server_opts.enable_directory_listing = "no";
|
|
||||||
|
|
||||||
LOG_INFO() printf("Listening on http port %s\n", config.webport);
|
|
||||||
if (config.ssl == true)
|
|
||||||
LOG_INFO() printf("Listening on ssl port %s\n", config.sslport);
|
|
||||||
|
|
||||||
pthread_t mpd_client, web_server;
|
pthread_t mpd_client, web_server;
|
||||||
|
//mpd connection
|
||||||
pthread_create(&mpd_client, NULL, mpd_client_thread, NULL);
|
pthread_create(&mpd_client, NULL, mpd_client_thread, NULL);
|
||||||
pthread_create(&web_server, NULL, web_server_thread, &mgr);
|
//webserver
|
||||||
|
pthread_create(&web_server, NULL, web_server_thread, NULL);
|
||||||
|
|
||||||
//Do nothing...
|
//Do nothing...
|
||||||
|
|
||||||
|
|
||||||
//clean up
|
//clean up
|
||||||
//todo: destroy tiny queues
|
|
||||||
pthread_join(mpd_client, NULL);
|
pthread_join(mpd_client, NULL);
|
||||||
pthread_join(web_server, NULL);
|
pthread_join(web_server, NULL);
|
||||||
list_free(&mpd_tags);
|
list_free(&mpd_tags);
|
||||||
list_free(&mympd_tags);
|
list_free(&mympd_tags);
|
||||||
|
tiny_queue_free(web_server_queue);
|
||||||
|
tiny_queue_free(mpd_client_queue);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,18 @@ tiny_queue_t* tiny_queue_create() {
|
|||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tiny_queue_free(tiny_queue_t *queue) {
|
||||||
|
struct tiny_msg_t *current_head = queue->head, *tmp = NULL;
|
||||||
|
while (current_head != NULL) {
|
||||||
|
free(current_head->data);
|
||||||
|
tmp = current_head;
|
||||||
|
current_head = current_head->next;
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
free(queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void tiny_queue_push(tiny_queue_t *queue, void *data) {
|
void tiny_queue_push(tiny_queue_t *queue, void *data) {
|
||||||
pthread_mutex_lock(&queue->mutex);
|
pthread_mutex_lock(&queue->mutex);
|
||||||
struct tiny_msg_t* new_node = (struct tiny_msg_t*)malloc(sizeof(struct tiny_msg_t));
|
struct tiny_msg_t* new_node = (struct tiny_msg_t*)malloc(sizeof(struct tiny_msg_t));
|
||||||
|
@ -34,6 +34,7 @@ typedef struct tiny_queue_t {
|
|||||||
} tiny_queue_t;
|
} tiny_queue_t;
|
||||||
|
|
||||||
tiny_queue_t* tiny_queue_create();
|
tiny_queue_t* tiny_queue_create();
|
||||||
|
void tiny_queue_free(tiny_queue_t *queue);
|
||||||
void tiny_queue_push(struct tiny_queue_t *queue, void *data);
|
void tiny_queue_push(struct tiny_queue_t *queue, void *data);
|
||||||
void *tiny_queue_shift(struct tiny_queue_t *queue);
|
void *tiny_queue_shift(struct tiny_queue_t *queue);
|
||||||
int tiny_queue_length(struct tiny_queue_t *queue);
|
int tiny_queue_length(struct tiny_queue_t *queue);
|
||||||
|
@ -22,18 +22,99 @@
|
|||||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "global.h"
|
||||||
#include "config.h"
|
|
||||||
#include "web_server.h"
|
#include "web_server.h"
|
||||||
#include "mpd_client.h"
|
#include "mpd_client.h"
|
||||||
|
#include "../dist/src/mongoose/mongoose.h"
|
||||||
|
|
||||||
|
//non-api definitions
|
||||||
static unsigned long s_next_id = 1;
|
static unsigned long s_next_id = 1;
|
||||||
|
struct mg_mgr mgr;
|
||||||
|
static struct mg_serve_http_opts s_http_server_opts;
|
||||||
|
|
||||||
int is_websocket(const struct mg_connection *nc) {
|
static int is_websocket(const struct mg_connection *nc);
|
||||||
|
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data);
|
||||||
|
static void ev_handler_redirect(struct mg_connection *nc_http, int ev, void *ev_data);
|
||||||
|
static void send_ws_notify(struct mg_mgr *mgr, struct work_result_t *response);
|
||||||
|
static void send_api_response(struct mg_mgr *mgr, struct work_result_t *response);
|
||||||
|
|
||||||
|
//api functions
|
||||||
|
bool web_server_init() {
|
||||||
|
struct mg_connection *nc;
|
||||||
|
struct mg_connection *nc_http;
|
||||||
|
struct mg_bind_opts bind_opts;
|
||||||
|
const char *err;
|
||||||
|
|
||||||
|
mg_mgr_init(&mgr, NULL);
|
||||||
|
|
||||||
|
if (config.ssl == true) {
|
||||||
|
nc_http = mg_bind(&mgr, config.webport, ev_handler_redirect);
|
||||||
|
if (nc_http == NULL) {
|
||||||
|
printf("Error listening on port %s\n", config.webport);
|
||||||
|
mg_mgr_free(&mgr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mg_set_protocol_http_websocket(nc_http);
|
||||||
|
LOG_INFO() printf("Listening on http port %s (redirect only).\n", config.webport);
|
||||||
|
|
||||||
|
memset(&bind_opts, 0, sizeof(bind_opts));
|
||||||
|
bind_opts.ssl_cert = config.sslcert;
|
||||||
|
bind_opts.ssl_key = config.sslkey;
|
||||||
|
bind_opts.error_string = &err;
|
||||||
|
nc = mg_bind_opt(&mgr, config.sslport, ev_handler, bind_opts);
|
||||||
|
if (nc == NULL) {
|
||||||
|
printf("Error listening on port %s: %s\n", config.sslport, err);
|
||||||
|
mg_mgr_free(&mgr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG_INFO() printf("Listening on ssl port %s\n", config.sslport);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nc = mg_bind(&mgr, config.webport, ev_handler);
|
||||||
|
if (nc == NULL) {
|
||||||
|
printf("Error listening on port %s\n", config.webport);
|
||||||
|
mg_mgr_free(&mgr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG_INFO() printf("Listening on http port %s\n", config.webport);
|
||||||
|
}
|
||||||
|
|
||||||
|
mg_set_protocol_http_websocket(nc);
|
||||||
|
s_http_server_opts.document_root = DOC_ROOT;
|
||||||
|
s_http_server_opts.enable_directory_listing = "no";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void web_server_free() {
|
||||||
|
mg_mgr_free(&mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *web_server_thread() {
|
||||||
|
while (s_signal_received == 0) {
|
||||||
|
mg_mgr_poll(&mgr, 10);
|
||||||
|
unsigned web_server_queue_length = tiny_queue_length(web_server_queue);
|
||||||
|
if (web_server_queue_length > 0) {
|
||||||
|
struct work_result_t *response = tiny_queue_shift(web_server_queue);
|
||||||
|
if (response->conn_id == 0) {
|
||||||
|
//Websocket notify from mpd idle
|
||||||
|
send_ws_notify(&mgr, response);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//api response
|
||||||
|
send_api_response(&mgr, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mg_mgr_free(&mgr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//non-api functions
|
||||||
|
static int is_websocket(const struct mg_connection *nc) {
|
||||||
return nc->flags & MG_F_IS_WEBSOCKET;
|
return nc->flags & MG_F_IS_WEBSOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_ws_notify(struct mg_mgr *mgr, struct work_result_t *response) {
|
static void send_ws_notify(struct mg_mgr *mgr, struct work_result_t *response) {
|
||||||
struct mg_connection *c;
|
struct mg_connection *c;
|
||||||
LOG_DEBUG() fprintf(stderr, "DEBUG: Got ws notify, broadcasting\n");
|
LOG_DEBUG() fprintf(stderr, "DEBUG: Got ws notify, broadcasting\n");
|
||||||
|
|
||||||
@ -45,7 +126,7 @@ void send_ws_notify(struct mg_mgr *mgr, struct work_result_t *response) {
|
|||||||
free(response);
|
free(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_api_response(struct mg_mgr *mgr, struct work_result_t *response) {
|
static void send_api_response(struct mg_mgr *mgr, struct work_result_t *response) {
|
||||||
struct mg_connection *c;
|
struct mg_connection *c;
|
||||||
LOG_DEBUG() fprintf(stderr, "DEBUG: Got API response for connection %lu.\n", response->conn_id);
|
LOG_DEBUG() fprintf(stderr, "DEBUG: Got API response for connection %lu.\n", response->conn_id);
|
||||||
|
|
||||||
@ -61,7 +142,7 @@ void send_api_response(struct mg_mgr *mgr, struct work_result_t *response) {
|
|||||||
free(response);
|
free(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||||
(void) nc;
|
(void) nc;
|
||||||
(void) ev_data;
|
(void) ev_data;
|
||||||
|
|
||||||
@ -94,8 +175,6 @@ void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
struct work_request_t *request = (struct work_request_t*)malloc(sizeof(struct work_request_t));
|
struct work_request_t *request = (struct work_request_t*)malloc(sizeof(struct work_request_t));
|
||||||
request->conn_id = (unsigned long)nc->user_data;
|
request->conn_id = (unsigned long)nc->user_data;
|
||||||
request->length = copy_string(request->data, hm->body.p, 1000, hm->body.len);
|
request->length = copy_string(request->data, hm->body.p, 1000, hm->body.len);
|
||||||
//sizeof(request->data) - 1 < hm->body.len ? sizeof(request->data) - 1 : hm->body.len;
|
|
||||||
//memcpy(request->data, hm->body.p, request->length);
|
|
||||||
tiny_queue_push(mpd_client_queue, request);
|
tiny_queue_push(mpd_client_queue, request);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -119,7 +198,7 @@ void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ev_handler_redirect(struct mg_connection *nc_http, int ev, void *ev_data) {
|
static void ev_handler_redirect(struct mg_connection *nc_http, int ev, void *ev_data) {
|
||||||
char *host;
|
char *host;
|
||||||
char host_header[1024];
|
char host_header[1024];
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#ifndef __WEB_SERVER_H__
|
#ifndef __WEB_SERVER_H__
|
||||||
#define __WEB_SERVER_H__
|
#define __WEB_SERVER_H__
|
||||||
|
|
||||||
#include "../dist/src/mongoose/mongoose.h"
|
|
||||||
#include "tiny_queue.h"
|
#include "tiny_queue.h"
|
||||||
|
|
||||||
tiny_queue_t *web_server_queue;
|
tiny_queue_t *web_server_queue;
|
||||||
@ -42,11 +41,8 @@ struct work_result_t {
|
|||||||
int length;
|
int length;
|
||||||
} work_result_t;
|
} work_result_t;
|
||||||
|
|
||||||
struct mg_serve_http_opts s_http_server_opts;
|
void *web_server_thread();
|
||||||
|
bool web_server_init();
|
||||||
|
void web_server_free();
|
||||||
|
|
||||||
int is_websocket(const struct mg_connection *nc);
|
|
||||||
void ev_handler(struct mg_connection *nc, int ev, void *ev_data);
|
|
||||||
void ev_handler_redirect(struct mg_connection *nc_http, int ev, void *ev_data);
|
|
||||||
void send_ws_notify(struct mg_mgr *mgr, struct work_result_t *response);
|
|
||||||
void send_api_response(struct mg_mgr *mgr, struct work_result_t *response);
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user