1
0
mirror of https://github.com/SuperBFG7/ympd synced 2025-07-04 19:12:48 +00:00

Fix: no global state in web_server.c

This commit is contained in:
jcorporation 2019-01-06 09:36:34 +00:00
parent 4c086da611
commit 8634a52194
8 changed files with 54 additions and 49 deletions

View File

@ -27,6 +27,10 @@
#include <stdio.h> #include <stdio.h>
#include "global.h" #include "global.h"
int randrange(int n) {
return rand() / (RAND_MAX / (n + 1) + 1);
}
void sanitize_string(const char *data) { void sanitize_string(const char *data) {
static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz" static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

View File

@ -99,6 +99,7 @@ typedef struct {
t_config config; t_config config;
//global functions //global functions
int randrange(int n);
void sanitize_string(const char *data); void sanitize_string(const char *data);
int copy_string(char * const dest, char const * const src, size_t const dst_len, size_t const src_len); int copy_string(char * const dest, char const * const src, size_t const dst_len, size_t const src_len);
#endif #endif

View File

@ -81,7 +81,7 @@ int list_shuffle(struct list *l) {
if (l->length < 2) if (l->length < 2)
return 1; return 1;
srand((unsigned int)time(NULL)); // srand((unsigned int)time(NULL));
struct node *current = l->list; struct node *current = l->list;
while (current != NULL) { while (current != NULL) {

View File

@ -38,6 +38,7 @@
#include "global.h" #include "global.h"
#include "mpd_client.h" #include "mpd_client.h"
#include "web_server.h" #include "web_server.h"
#include "../dist/src/mongoose/mongoose.h"
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
@ -297,7 +298,7 @@ bool testdir(char *name, char *dirname) {
} }
} }
void *mpd_client_thread() { void *mpd_client_loop() {
while (s_signal_received == 0) { while (s_signal_received == 0) {
mpd_client_idle(100); mpd_client_idle(100);
} }
@ -310,7 +311,8 @@ int main(int argc, char **argv) {
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();
//mympd_queue = tiny_queue_create();
srand((unsigned int)time(NULL));
//defaults //defaults
config.mpdhost = "127.0.0.1"; config.mpdhost = "127.0.0.1";
@ -380,36 +382,36 @@ int main(int argc, char **argv) {
setvbuf(stderr, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IOLBF, 0);
//init webserver //init webserver
if (!web_server_init()) { struct mg_mgr mgr;
if (!web_server_init(&mgr)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
//drop privileges //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");
web_server_free(); web_server_free(&mgr);
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");
web_server_free(); web_server_free(&mgr);
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");
web_server_free(); web_server_free(&mgr);
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");
web_server_free(); web_server_free(&mgr);
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");
web_server_free(); web_server_free(&mgr);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -456,22 +458,21 @@ int main(int argc, char **argv) {
LOG_INFO() printf("Reading last played songs: %d\n", read_last_played()); LOG_INFO() printf("Reading last played songs: %d\n", read_last_played());
//Create working threads //Create working threads
pthread_t mpd_client, web_server; pthread_t mpd_client_thread, web_server_thread;
//mpd connection //mpd connection
pthread_create(&mpd_client, NULL, mpd_client_thread, NULL); pthread_create(&mpd_client_thread, NULL, mpd_client_loop, NULL);
//webserver //webserver
pthread_create(&web_server, NULL, web_server_thread, NULL); pthread_create(&web_server_thread, NULL, web_server_loop, &mgr);
//Do nothing... //Do nothing...
//clean up //clean up
pthread_join(mpd_client, NULL); pthread_join(mpd_client_thread, NULL);
pthread_join(web_server, NULL); pthread_join(web_server_thread, 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(web_server_queue);
tiny_queue_free(mpd_client_queue); tiny_queue_free(mpd_client_queue);
//tiny_queue_free(mympd_queue);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1362,7 +1362,7 @@ bool mpd_client_jukebox() {
return true; return true;
} }
srand((unsigned int)time(NULL)); //srand((unsigned int)time(NULL));
struct list add_list; struct list add_list;
list_init(&add_list); list_init(&add_list);
@ -1482,10 +1482,6 @@ bool mpd_client_jukebox() {
return true; return true;
} }
int randrange(int n) {
return rand() / (RAND_MAX / (n + 1) + 1);
}
int mpd_client_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) { int mpd_client_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) {
struct mpd_status *status; struct mpd_status *status;
const struct mpd_audio_format *audioformat; const struct mpd_audio_format *audioformat;

View File

@ -191,7 +191,6 @@ typedef struct {
t_mympd_state mympd_state; t_mympd_state mympd_state;
tiny_queue_t *mpd_client_queue; tiny_queue_t *mpd_client_queue;
int randrange(int n);
void mpd_client_idle(int timeout); void mpd_client_idle(int timeout);
void mpd_client_parse_idle(int idle_bitmask); void mpd_client_parse_idle(int idle_bitmask);
void mpd_client_api(struct work_request_t *request); void mpd_client_api(struct work_request_t *request);

View File

@ -28,10 +28,6 @@
#include "../dist/src/mongoose/mongoose.h" #include "../dist/src/mongoose/mongoose.h"
//non-api definitions //non-api definitions
static unsigned long s_next_id = 1;
struct mg_mgr mgr;
static struct mg_serve_http_opts s_http_server_opts;
static 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(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 ev_handler_redirect(struct mg_connection *nc_http, int ev, void *ev_data);
@ -39,19 +35,20 @@ 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); static void send_api_response(struct mg_mgr *mgr, struct work_result_t *response);
//api functions //api functions
bool web_server_init() { bool web_server_init(void *arg) {
struct mg_mgr *mgr = (struct mg_mgr *) arg;
struct mg_connection *nc; struct mg_connection *nc;
struct mg_connection *nc_http; struct mg_connection *nc_http;
struct mg_bind_opts bind_opts; struct mg_bind_opts bind_opts;
const char *err; const char *err;
mg_mgr_init(&mgr, NULL); mg_mgr_init(mgr, NULL);
if (config.ssl == true) { if (config.ssl == true) {
nc_http = mg_bind(&mgr, config.webport, ev_handler_redirect); nc_http = mg_bind(mgr, config.webport, ev_handler_redirect);
if (nc_http == NULL) { if (nc_http == NULL) {
printf("Error listening on port %s\n", config.webport); printf("Error listening on port %s\n", config.webport);
mg_mgr_free(&mgr); mg_mgr_free(mgr);
return false; return false;
} }
mg_set_protocol_http_websocket(nc_http); mg_set_protocol_http_websocket(nc_http);
@ -61,51 +58,52 @@ bool web_server_init() {
bind_opts.ssl_cert = config.sslcert; bind_opts.ssl_cert = config.sslcert;
bind_opts.ssl_key = config.sslkey; bind_opts.ssl_key = config.sslkey;
bind_opts.error_string = &err; bind_opts.error_string = &err;
nc = mg_bind_opt(&mgr, config.sslport, ev_handler, bind_opts); nc = mg_bind_opt(mgr, config.sslport, ev_handler, bind_opts);
if (nc == NULL) { if (nc == NULL) {
printf("Error listening on port %s: %s\n", config.sslport, err); printf("Error listening on port %s: %s\n", config.sslport, err);
mg_mgr_free(&mgr); mg_mgr_free(mgr);
return false; return false;
} }
LOG_INFO() printf("Listening on ssl port %s\n", config.sslport); LOG_INFO() printf("Listening on ssl port %s\n", config.sslport);
} }
else { else {
nc = mg_bind(&mgr, config.webport, ev_handler); nc = mg_bind(mgr, config.webport, ev_handler);
if (nc == NULL) { if (nc == NULL) {
printf("Error listening on port %s\n", config.webport); printf("Error listening on port %s\n", config.webport);
mg_mgr_free(&mgr); mg_mgr_free(mgr);
return false; return false;
} }
LOG_INFO() printf("Listening on http port %s\n", config.webport); LOG_INFO() printf("Listening on http port %s\n", config.webport);
} }
mg_set_protocol_http_websocket(nc); mg_set_protocol_http_websocket(nc);
s_http_server_opts.document_root = DOC_ROOT;
s_http_server_opts.enable_directory_listing = "no"; return mgr;
return true;
} }
void web_server_free() { void web_server_free(void *arg) {
mg_mgr_free(&mgr); struct mg_mgr *mgr = (struct mg_mgr *) arg;
mg_mgr_free(mgr);
} }
void *web_server_thread() { void *web_server_loop(void *arg) {
struct mg_mgr *mgr = (struct mg_mgr *) arg;
while (s_signal_received == 0) { while (s_signal_received == 0) {
mg_mgr_poll(&mgr, 10); mg_mgr_poll(mgr, 100);
unsigned web_server_queue_length = tiny_queue_length(web_server_queue); unsigned web_server_queue_length = tiny_queue_length(web_server_queue);
if (web_server_queue_length > 0) { if (web_server_queue_length > 0) {
struct work_result_t *response = tiny_queue_shift(web_server_queue); struct work_result_t *response = tiny_queue_shift(web_server_queue);
if (response->conn_id == 0) { if (response->conn_id == 0) {
//Websocket notify from mpd idle //Websocket notify from mpd idle
send_ws_notify(&mgr, response); send_ws_notify(mgr, response);
} }
else { else {
//api response //api response
send_api_response(&mgr, response); send_api_response(mgr, response);
} }
} }
} }
mg_mgr_free(&mgr); mg_mgr_free(mgr);
return NULL; return NULL;
} }
@ -148,8 +146,11 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
switch(ev) { switch(ev) {
case MG_EV_ACCEPT: { case MG_EV_ACCEPT: {
nc->user_data = (void *)++s_next_id; struct timespec start;
LOG_DEBUG() fprintf(stderr, "DEBUG: New connection id %lu.\n", s_next_id); clock_gettime(CLOCK_MONOTONIC_RAW, &start);
long unsigned conn_id = (start.tv_sec * 1000 + start.tv_nsec / 1000) * 100 + randrange(100);
nc->user_data = (void *)conn_id;
LOG_DEBUG() fprintf(stderr, "DEBUG: New connection id %lu.\n", conn_id);
break; break;
} }
case MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: { case MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: {
@ -178,6 +179,9 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
tiny_queue_push(mpd_client_queue, request); tiny_queue_push(mpd_client_queue, request);
} }
else { else {
static struct mg_serve_http_opts s_http_server_opts;
s_http_server_opts.document_root = DOC_ROOT;
s_http_server_opts.enable_directory_listing = "no";
mg_serve_http(nc, hm, s_http_server_opts); mg_serve_http(nc, hm, s_http_server_opts);
} }
break; break;

View File

@ -41,8 +41,8 @@ struct work_result_t {
int length; int length;
} work_result_t; } work_result_t;
void *web_server_thread(); void *web_server_loop(void *arg);
bool web_server_init(); bool web_server_init(void *arg);
void web_server_free(); void web_server_free(void *arg);
#endif #endif