mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
make various responses going back to the client be done via the file serving thread
svn path=/icecast/trunk/icecast/; revision=9740
This commit is contained in:
parent
61267a308b
commit
dde143d4b1
33
src/client.c
33
src/client.c
@ -32,6 +32,7 @@
|
|||||||
#include "refbuf.h"
|
#include "refbuf.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
#include "fserve.h"
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
@ -143,46 +144,36 @@ int client_read_bytes (client_t *client, void *buf, unsigned len)
|
|||||||
|
|
||||||
|
|
||||||
void client_send_400(client_t *client, char *message) {
|
void client_send_400(client_t *client, char *message) {
|
||||||
int bytes;
|
snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
|
||||||
bytes = sock_write(client->con->sock, "HTTP/1.0 400 Bad Request\r\n"
|
"HTTP/1.0 400 Bad Request\r\n"
|
||||||
"Content-Type: text/html\r\n\r\n"
|
"Content-Type: text/html\r\n\r\n"
|
||||||
"<b>%s</b>\r\n", message);
|
"<b>%s</b>\r\n", message);
|
||||||
if(bytes > 0) client->con->sent_bytes = bytes;
|
|
||||||
client->respcode = 400;
|
client->respcode = 400;
|
||||||
client_destroy(client);
|
client->refbuf->len = strlen (client->refbuf->data);
|
||||||
|
fserve_add_client (client, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_send_404(client_t *client, char *message) {
|
void client_send_404(client_t *client, char *message) {
|
||||||
|
|
||||||
int bytes;
|
snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
|
||||||
bytes = sock_write(client->con->sock, "HTTP/1.0 404 File Not Found\r\n"
|
"HTTP/1.0 404 File Not Found\r\n"
|
||||||
"Content-Type: text/html\r\n\r\n"
|
"Content-Type: text/html\r\n\r\n"
|
||||||
"<b>%s</b>\r\n", message);
|
"<b>%s</b>\r\n", message);
|
||||||
if(bytes > 0) client->con->sent_bytes = bytes;
|
|
||||||
client->respcode = 404;
|
client->respcode = 404;
|
||||||
client_destroy(client);
|
client->refbuf->len = strlen (client->refbuf->data);
|
||||||
|
fserve_add_client (client, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_send_504(client_t *client, char *message) {
|
|
||||||
int bytes;
|
|
||||||
client->respcode = 504;
|
|
||||||
bytes = sock_write(client->con->sock,
|
|
||||||
"HTTP/1.0 504 Server Full\r\n"
|
|
||||||
"Content-Type: text/html\r\n\r\n"
|
|
||||||
"<b>%s</b>\r\n", message);
|
|
||||||
if (bytes > 0) client->con->sent_bytes = bytes;
|
|
||||||
client_destroy(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void client_send_401(client_t *client) {
|
void client_send_401(client_t *client) {
|
||||||
int bytes = sock_write(client->con->sock,
|
snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
|
||||||
"HTTP/1.0 401 Authentication Required\r\n"
|
"HTTP/1.0 401 Authentication Required\r\n"
|
||||||
"WWW-Authenticate: Basic realm=\"Icecast2 Server\"\r\n"
|
"WWW-Authenticate: Basic realm=\"Icecast2 Server\"\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"You need to authenticate\r\n");
|
"You need to authenticate\r\n");
|
||||||
if(bytes > 0) client->con->sent_bytes = bytes;
|
|
||||||
client->respcode = 401;
|
client->respcode = 401;
|
||||||
client_destroy(client);
|
client->refbuf->len = strlen (client->refbuf->data);
|
||||||
|
fserve_add_client (client, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_send_403(client_t *client) {
|
void client_send_403(client_t *client) {
|
||||||
|
@ -764,8 +764,13 @@ static void _handle_source_request (client_t *client, char *uri, int auth_style)
|
|||||||
source_free_source (source);
|
source_free_source (source);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
thread_create ("Source Thread", source_client_thread,
|
{
|
||||||
source, THREAD_DETACHED);
|
client->respcode = 200;
|
||||||
|
snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
|
||||||
|
"HTTP/1.0 200 OK\r\n\r\n");
|
||||||
|
client->refbuf->len = strlen (client->refbuf->data);
|
||||||
|
fserve_add_client_callback (client, source_client_callback, source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -787,14 +792,10 @@ static void _handle_stats_request (client_t *client, char *uri)
|
|||||||
}
|
}
|
||||||
|
|
||||||
client->respcode = 200;
|
client->respcode = 200;
|
||||||
if (sock_write (client->con->sock, "HTTP/1.0 200 OK\r\n\r\n") < 19)
|
snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
|
||||||
{
|
"HTTP/1.0 200 OK\r\n\r\n");
|
||||||
client_destroy (client);
|
client->refbuf->len = strlen (client->refbuf->data);
|
||||||
ERROR0 ("failed to write header");
|
fserve_add_client_callback (client, stats_callback, NULL);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_create("Stats Connection", stats_connection, (void *)client, THREAD_DETACHED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _handle_get_request (client_t *client, char *passed_uri)
|
static void _handle_get_request (client_t *client, char *passed_uri)
|
||||||
|
36
src/fserve.c
36
src/fserve.c
@ -352,8 +352,11 @@ static void fserve_client_destroy(fserve_t *fclient)
|
|||||||
if (fclient->file)
|
if (fclient->file)
|
||||||
fclose (fclient->file);
|
fclose (fclient->file);
|
||||||
|
|
||||||
if (fclient->client)
|
if (fclient->callback)
|
||||||
client_destroy (fclient->client);
|
fclient->callback (fclient->client, fclient->arg);
|
||||||
|
else
|
||||||
|
if (fclient->client)
|
||||||
|
client_destroy (fclient->client);
|
||||||
free (fclient);
|
free (fclient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,8 +399,7 @@ int fserve_client_create (client_t *httpclient, const char *path)
|
|||||||
m3u_file_available = 0;
|
m3u_file_available = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
client_set_queue (httpclient, NULL);
|
httpclient->refbuf->len = PER_CLIENT_REFBUF_SIZE;
|
||||||
httpclient->refbuf = refbuf_new (BUFSIZE);
|
|
||||||
|
|
||||||
if (m3u_requested && m3u_file_available == 0)
|
if (m3u_requested && m3u_file_available == 0)
|
||||||
{
|
{
|
||||||
@ -580,6 +582,32 @@ int fserve_add_client (client_t *client, FILE *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* add client to file serving engine, but just write out the buffer contents,
|
||||||
|
* then pass the client to the callback with the provided arg
|
||||||
|
*/
|
||||||
|
void fserve_add_client_callback (client_t *client, fserve_callback_t callback, void *arg)
|
||||||
|
{
|
||||||
|
fserve_t *fclient = calloc (1, sizeof(fserve_t));
|
||||||
|
|
||||||
|
DEBUG0 ("Adding client to file serving engine");
|
||||||
|
if (fclient == NULL)
|
||||||
|
{
|
||||||
|
client_send_404 (client, "memory exhausted");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fclient->file = NULL;
|
||||||
|
fclient->client = client;
|
||||||
|
fclient->ready = 0;
|
||||||
|
fclient->callback = callback;
|
||||||
|
fclient->arg = arg;
|
||||||
|
|
||||||
|
thread_mutex_lock (&pending_lock);
|
||||||
|
fclient->next = (fserve_t *)pending_list;
|
||||||
|
pending_list = fclient;
|
||||||
|
thread_mutex_unlock (&pending_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int _delete_mapping(void *mapping) {
|
static int _delete_mapping(void *mapping) {
|
||||||
mime_type *map = mapping;
|
mime_type *map = mapping;
|
||||||
free(map->ext);
|
free(map->ext);
|
||||||
|
@ -15,12 +15,16 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef void (*fserve_callback_t)(client_t *, void *);
|
||||||
|
|
||||||
typedef struct _fserve_t
|
typedef struct _fserve_t
|
||||||
{
|
{
|
||||||
client_t *client;
|
client_t *client;
|
||||||
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
int ready;
|
int ready;
|
||||||
|
void (*callback)(client_t *, void *);
|
||||||
|
void *arg;
|
||||||
struct _fserve_t *next;
|
struct _fserve_t *next;
|
||||||
} fserve_t;
|
} fserve_t;
|
||||||
|
|
||||||
@ -28,6 +32,7 @@ void fserve_initialize(void);
|
|||||||
void fserve_shutdown(void);
|
void fserve_shutdown(void);
|
||||||
int fserve_client_create(client_t *httpclient, const char *path);
|
int fserve_client_create(client_t *httpclient, const char *path);
|
||||||
int fserve_add_client (client_t *client, FILE *file);
|
int fserve_add_client (client_t *client, FILE *file);
|
||||||
|
void fserve_add_client_callback (client_t *client, fserve_callback_t callback, void *arg);
|
||||||
char *fserve_content_type (const char *path);
|
char *fserve_content_type (const char *path);
|
||||||
|
|
||||||
|
|
||||||
|
46
src/source.c
46
src/source.c
@ -1184,28 +1184,6 @@ void *source_client_thread (void *arg)
|
|||||||
{
|
{
|
||||||
source_t *source = arg;
|
source_t *source = arg;
|
||||||
|
|
||||||
if (source->client && source->client->con)
|
|
||||||
{
|
|
||||||
const char ok_msg[] = "HTTP/1.0 200 OK\r\n\r\n";
|
|
||||||
int bytes;
|
|
||||||
const char *agent;
|
|
||||||
|
|
||||||
source->client->respcode = 200;
|
|
||||||
bytes = sock_write_bytes (source->client->con->sock, ok_msg, sizeof (ok_msg)-1);
|
|
||||||
if (bytes < (int)(sizeof (ok_msg)-1))
|
|
||||||
{
|
|
||||||
global_lock();
|
|
||||||
global.sources--;
|
|
||||||
global_unlock();
|
|
||||||
WARN0 ("Error writing 200 OK message to source client");
|
|
||||||
source_free_source (source);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
stats_event (source->mount, "source_ip", source->client->con->ip);
|
|
||||||
agent = httpp_getvar (source->client->parser, "user-agent");
|
|
||||||
if (agent)
|
|
||||||
stats_event (source->mount, "user_agent", agent);
|
|
||||||
}
|
|
||||||
stats_event_inc(NULL, "source_client_connections");
|
stats_event_inc(NULL, "source_client_connections");
|
||||||
stats_event (source->mount, "listeners", "0");
|
stats_event (source->mount, "listeners", "0");
|
||||||
|
|
||||||
@ -1218,6 +1196,30 @@ void *source_client_thread (void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void source_client_callback (client_t *client, void *arg)
|
||||||
|
{
|
||||||
|
const char *agent;
|
||||||
|
source_t *source = arg;
|
||||||
|
|
||||||
|
if (client->con->error)
|
||||||
|
{
|
||||||
|
global_lock();
|
||||||
|
global.sources--;
|
||||||
|
global_unlock();
|
||||||
|
source_free_source (source);
|
||||||
|
client_destroy (client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stats_event (source->mount, "source_ip", source->client->con->ip);
|
||||||
|
agent = httpp_getvar (source->client->parser, "user-agent");
|
||||||
|
if (agent)
|
||||||
|
stats_event (source->mount, "user_agent", agent);
|
||||||
|
|
||||||
|
thread_create ("Source Thread", source_client_thread,
|
||||||
|
source, THREAD_DETACHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
static void source_run_script (char *command, char *mountpoint)
|
static void source_run_script (char *command, char *mountpoint)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,7 @@ typedef struct source_tag
|
|||||||
|
|
||||||
source_t *source_reserve (const char *mount);
|
source_t *source_reserve (const char *mount);
|
||||||
void *source_client_thread (void *arg);
|
void *source_client_thread (void *arg);
|
||||||
|
void source_client_callback (client_t *client, void *source);
|
||||||
void source_update_settings (ice_config_t *config, source_t *source, mount_proxy *mountinfo);
|
void source_update_settings (ice_config_t *config, source_t *source, mount_proxy *mountinfo);
|
||||||
void source_clear_source (source_t *source);
|
void source_clear_source (source_t *source);
|
||||||
source_t *source_find_mount(const char *mount);
|
source_t *source_find_mount(const char *mount);
|
||||||
|
21
src/stats.c
21
src/stats.c
@ -59,17 +59,17 @@ typedef struct _event_listener_tag
|
|||||||
struct _event_listener_tag *next;
|
struct _event_listener_tag *next;
|
||||||
} event_listener_t;
|
} event_listener_t;
|
||||||
|
|
||||||
volatile static int _stats_running = 0;
|
static volatile int _stats_running = 0;
|
||||||
static thread_type *_stats_thread_id;
|
static thread_type *_stats_thread_id;
|
||||||
volatile static int _stats_threads = 0;
|
static volatile int _stats_threads = 0;
|
||||||
|
|
||||||
static stats_t _stats;
|
static stats_t _stats;
|
||||||
static mutex_t _stats_mutex;
|
static mutex_t _stats_mutex;
|
||||||
|
|
||||||
volatile static stats_event_t *_global_event_queue;
|
static volatile stats_event_t *_global_event_queue;
|
||||||
mutex_t _global_event_mutex;
|
mutex_t _global_event_mutex;
|
||||||
|
|
||||||
volatile static event_listener_t *_event_listeners;
|
static volatile event_listener_t *_event_listeners;
|
||||||
|
|
||||||
|
|
||||||
static void *_stats_thread(void *arg);
|
static void *_stats_thread(void *arg);
|
||||||
@ -842,6 +842,19 @@ void *stats_connection(void *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void stats_callback (client_t *client, void *notused)
|
||||||
|
{
|
||||||
|
if (client->con->error)
|
||||||
|
{
|
||||||
|
client_destroy (client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client_set_queue (client, NULL);
|
||||||
|
thread_create("Stats Connection", stats_connection, (void *)client, THREAD_DETACHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct _source_xml_tag {
|
typedef struct _source_xml_tag {
|
||||||
char *mount;
|
char *mount;
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
|
@ -84,7 +84,7 @@ void stats_event_hidden (const char *source, const char *name, int hidden);
|
|||||||
void stats_event_time (const char *mount, const char *name);
|
void stats_event_time (const char *mount, const char *name);
|
||||||
|
|
||||||
void *stats_connection(void *arg);
|
void *stats_connection(void *arg);
|
||||||
void *stats_callback(void *arg);
|
void stats_callback (client_t *client, void *notused);
|
||||||
|
|
||||||
void stats_transform_xslt(client_t *client, const char *uri);
|
void stats_transform_xslt(client_t *client, const char *uri);
|
||||||
void stats_sendxml(client_t *client);
|
void stats_sendxml(client_t *client);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user