output/httpd: bind port when output is enabled

Implement the methods enable() and disable().  Bind the HTTP port in
the enable() method, but reject all incoming connections until the
output is opened.
This commit is contained in:
Max Kellermann 2009-11-05 23:47:29 +01:00
parent 979cd5a768
commit 945287358b
3 changed files with 51 additions and 14 deletions

3
NEWS
View File

@ -28,6 +28,7 @@ ver 0.16 (20??/??/??)
- twolame: new encoder plugin based on libtwolame - twolame: new encoder plugin based on libtwolame
* output: * output:
- recorder: new output plugin for recording radio streams - recorder: new output plugin for recording radio streams
- alsa: don't recover on CANCEL
- openal: new output plugin - openal: new output plugin
- pulse: announce "media.role=music" - pulse: announce "media.role=music"
- pulse: renamed context to "Music Player Daemon" - pulse: renamed context to "Music Player Daemon"
@ -38,8 +39,8 @@ ver 0.16 (20??/??/??)
- jack: added option "client_name" - jack: added option "client_name"
- jack: clear ring buffers before activating - jack: clear ring buffers before activating
- jack: support mono input - jack: support mono input
- httpd: bind port when output is enabled
- wildcards allowed in audio_format configuration - wildcards allowed in audio_format configuration
- alsa: don't recover on CANCEL
- consistently lock audio output objects - consistently lock audio output objects
* mixers: * mixers:
- removed support for legacy mixer configuration - removed support for legacy mixer configuration

View File

@ -30,10 +30,17 @@
#include <glib.h> #include <glib.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <stdbool.h>
struct httpd_client; struct httpd_client;
struct httpd_output { struct httpd_output {
/**
* True if the audio output is open and accepts client
* connections.
*/
bool open;
/** /**
* The configured encoder plugin. * The configured encoder plugin.
*/ */

View File

@ -151,8 +151,9 @@ httpd_listen_in_event(G_GNUC_UNUSED GIOChannel *source,
fd = accept(httpd->fd, (struct sockaddr*)&sa, &sa_length); fd = accept(httpd->fd, (struct sockaddr*)&sa, &sa_length);
if (fd >= 0) { if (fd >= 0) {
/* can we allow additional client */ /* can we allow additional client */
if (!httpd->clients_max || if (httpd->open &&
httpd->clients_cnt < httpd->clients_max) (httpd->clients_max == 0 ||
httpd->clients_cnt < httpd->clients_max))
httpd_client_add(httpd, fd); httpd_client_add(httpd, fd);
else else
close(fd); close(fd);
@ -208,31 +209,56 @@ httpd_output_encoder_open(struct httpd_output *httpd,
} }
static bool static bool
httpd_output_open(void *data, struct audio_format *audio_format, httpd_output_enable(void *data, GError **error_r)
GError **error)
{ {
struct httpd_output *httpd = data; struct httpd_output *httpd = data;
bool success;
GIOChannel *channel; GIOChannel *channel;
g_mutex_lock(httpd->mutex); httpd->open = false;
/* create and set up listener socket */ /* create and set up listener socket */
httpd->fd = socket_bind_listen(PF_INET, SOCK_STREAM, 0, httpd->fd = socket_bind_listen(PF_INET, SOCK_STREAM, 0,
(struct sockaddr *)&httpd->address, (struct sockaddr *)&httpd->address,
httpd->address_size, httpd->address_size,
16, error); 16, error_r);
if (httpd->fd < 0) { if (httpd->fd < 0)
g_mutex_unlock(httpd->mutex);
return false; return false;
}
g_mutex_lock(httpd->mutex);
channel = g_io_channel_unix_new(httpd->fd); channel = g_io_channel_unix_new(httpd->fd);
httpd->source_id = g_io_add_watch(channel, G_IO_IN, httpd->source_id = g_io_add_watch(channel, G_IO_IN,
httpd_listen_in_event, httpd); httpd_listen_in_event, httpd);
g_io_channel_unref(channel); g_io_channel_unref(channel);
g_mutex_unlock(httpd->mutex);
return true;
}
static void
httpd_output_disable(void *data)
{
struct httpd_output *httpd = data;
g_mutex_lock(httpd->mutex);
g_source_remove(httpd->source_id);
close(httpd->fd);
g_mutex_unlock(httpd->mutex);
}
static bool
httpd_output_open(void *data, struct audio_format *audio_format,
GError **error)
{
struct httpd_output *httpd = data;
bool success;
g_mutex_lock(httpd->mutex);
/* open the encoder */ /* open the encoder */
success = httpd_output_encoder_open(httpd, audio_format, error); success = httpd_output_encoder_open(httpd, audio_format, error);
@ -249,6 +275,8 @@ httpd_output_open(void *data, struct audio_format *audio_format,
httpd->clients_cnt = 0; httpd->clients_cnt = 0;
httpd->timer = timer_new(audio_format); httpd->timer = timer_new(audio_format);
httpd->open = true;
g_mutex_unlock(httpd->mutex); g_mutex_unlock(httpd->mutex);
return true; return true;
} }
@ -267,6 +295,8 @@ static void httpd_output_close(void *data)
g_mutex_lock(httpd->mutex); g_mutex_lock(httpd->mutex);
httpd->open = false;
timer_free(httpd->timer); timer_free(httpd->timer);
g_list_foreach(httpd->clients, httpd_client_delete, NULL); g_list_foreach(httpd->clients, httpd_client_delete, NULL);
@ -277,9 +307,6 @@ static void httpd_output_close(void *data)
encoder_close(httpd->encoder); encoder_close(httpd->encoder);
g_source_remove(httpd->source_id);
close(httpd->fd);
g_mutex_unlock(httpd->mutex); g_mutex_unlock(httpd->mutex);
} }
@ -478,6 +505,8 @@ const struct audio_output_plugin httpd_output_plugin = {
.name = "httpd", .name = "httpd",
.init = httpd_output_init, .init = httpd_output_init,
.finish = httpd_output_finish, .finish = httpd_output_finish,
.enable = httpd_output_enable,
.disable = httpd_output_disable,
.open = httpd_output_open, .open = httpd_output_open,
.close = httpd_output_close, .close = httpd_output_close,
.send_tag = httpd_output_tag, .send_tag = httpd_output_tag,