aboutsummaryrefslogtreecommitdiffstats
path: root/src/output/plugins/httpd
diff options
context:
space:
mode:
Diffstat (limited to 'src/output/plugins/httpd')
-rw-r--r--src/output/plugins/httpd/HttpdClient.cxx4
-rw-r--r--src/output/plugins/httpd/HttpdClient.hxx10
-rw-r--r--src/output/plugins/httpd/HttpdInternal.hxx33
-rw-r--r--src/output/plugins/httpd/HttpdOutputPlugin.cxx80
-rw-r--r--src/output/plugins/httpd/HttpdOutputPlugin.hxx2
-rw-r--r--src/output/plugins/httpd/IcyMetaDataServer.cxx58
-rw-r--r--src/output/plugins/httpd/IcyMetaDataServer.hxx2
-rw-r--r--src/output/plugins/httpd/Page.cxx2
-rw-r--r--src/output/plugins/httpd/Page.hxx2
9 files changed, 83 insertions, 110 deletions
diff --git a/src/output/plugins/httpd/HttpdClient.cxx b/src/output/plugins/httpd/HttpdClient.cxx
index 3797c3d26..99210c1fd 100644
--- a/src/output/plugins/httpd/HttpdClient.cxx
+++ b/src/output/plugins/httpd/HttpdClient.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -23,7 +23,7 @@
#include "util/ASCII.hxx"
#include "Page.hxx"
#include "IcyMetaDataServer.hxx"
-#include "system/SocketError.hxx"
+#include "net/SocketError.hxx"
#include "Log.hxx"
#include <assert.h>
diff --git a/src/output/plugins/httpd/HttpdClient.hxx b/src/output/plugins/httpd/HttpdClient.hxx
index f94f05769..6646ddf4c 100644
--- a/src/output/plugins/httpd/HttpdClient.hxx
+++ b/src/output/plugins/httpd/HttpdClient.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,8 @@
#include "event/BufferedSocket.hxx"
#include "Compiler.h"
+#include <boost/intrusive/list.hpp>
+
#include <queue>
#include <list>
@@ -31,7 +33,9 @@
class HttpdOutput;
class Page;
-class HttpdClient final : BufferedSocket {
+class HttpdClient final
+ : BufferedSocket,
+ public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
/**
* The httpd output object this client is connected to.
*/
@@ -124,7 +128,7 @@ class HttpdClient final : BufferedSocket {
public:
/**
* @param httpd the HTTP output device
- * @param fd the socket file descriptor
+ * @param _fd the socket file descriptor
*/
HttpdClient(HttpdOutput &httpd, int _fd, EventLoop &_loop,
bool _metadata_supported);
diff --git a/src/output/plugins/httpd/HttpdInternal.hxx b/src/output/plugins/httpd/HttpdInternal.hxx
index 20ff15e42..01498dfcd 100644
--- a/src/output/plugins/httpd/HttpdInternal.hxx
+++ b/src/output/plugins/httpd/HttpdInternal.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,7 @@
#ifndef MPD_OUTPUT_HTTPD_INTERNAL_H
#define MPD_OUTPUT_HTTPD_INTERNAL_H
+#include "HttpdClient.hxx"
#include "output/Internal.hxx"
#include "output/Timer.hxx"
#include "thread/Mutex.hxx"
@@ -33,16 +34,10 @@
#include "util/Cast.hxx"
#include "Compiler.h"
-#ifdef _LIBCPP_VERSION
-/* can't use incomplete template arguments with libc++ */
-#include "HttpdClient.hxx"
-#endif
-
-#include <forward_list>
#include <queue>
#include <list>
-struct config_param;
+struct ConfigBlock;
class Error;
class EventLoop;
class ServerSocket;
@@ -135,7 +130,8 @@ private:
* A linked list containing all clients which are currently
* connected.
*/
- std::forward_list<HttpdClient> clients;
+ boost::intrusive::list<HttpdClient,
+ boost::intrusive::constant_time_size<true>> clients;
/**
* A temporary buffer for the httpd_output_read_page()
@@ -147,13 +143,13 @@ private:
* The maximum and current number of clients connected
* at the same time.
*/
- unsigned clients_max, clients_cnt;
+ unsigned clients_max;
public:
HttpdOutput(EventLoop &_loop);
~HttpdOutput();
-#if defined(__clang__) || GCC_CHECK_VERSION(4,7)
+#if CLANG_OR_GCC_VERSION(4,7)
constexpr
#endif
static HttpdOutput *Cast(AudioOutput *ao) {
@@ -162,16 +158,16 @@ public:
using DeferredMonitor::GetEventLoop;
- bool Init(const config_param &param, Error &error);
+ bool Init(const ConfigBlock &block, Error &error);
- bool Configure(const config_param &param, Error &error);
+ bool Configure(const ConfigBlock &block, Error &error);
- AudioOutput *InitAndConfigure(const config_param &param,
+ AudioOutput *InitAndConfigure(const ConfigBlock &block,
Error &error) {
- if (!Init(param, error))
+ if (!Init(block, error))
return nullptr;
- if (!Configure(param, error))
+ if (!Configure(block, error))
return nullptr;
return &base;
@@ -250,7 +246,7 @@ public:
bool EncodeAndPlay(const void *chunk, size_t size, Error &error);
- void SendTag(const Tag *tag);
+ void SendTag(const Tag &tag);
size_t Play(const void *chunk, size_t size, Error &error);
@@ -259,8 +255,7 @@ public:
private:
virtual void RunDeferred() override;
- virtual void OnAccept(int fd, const sockaddr &address,
- size_t address_length, int uid) override;
+ void OnAccept(int fd, SocketAddress address, int uid) override;
};
extern const class Domain httpd_output_domain;
diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.cxx b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
index e3ba7727d..765a72d92 100644
--- a/src/output/plugins/httpd/HttpdOutputPlugin.cxx
+++ b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,9 +22,11 @@
#include "HttpdInternal.hxx"
#include "HttpdClient.hxx"
#include "output/OutputAPI.hxx"
+#include "encoder/EncoderInterface.hxx"
#include "encoder/EncoderPlugin.hxx"
#include "encoder/EncoderList.hxx"
-#include "system/Resolver.hxx"
+#include "net/SocketAddress.hxx"
+#include "net/ToString.hxx"
#include "Page.hxx"
#include "IcyMetaDataServer.hxx"
#include "system/fd_util.h"
@@ -32,6 +34,7 @@
#include "event/Call.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
+#include "util/DeleteDisposer.hxx"
#include "Log.hxx"
#include <assert.h>
@@ -63,7 +66,7 @@ HttpdOutput::~HttpdOutput()
metadata->Unref();
if (encoder != nullptr)
- encoder_finish(encoder);
+ encoder->Dispose();
}
@@ -90,17 +93,17 @@ HttpdOutput::Unbind()
}
inline bool
-HttpdOutput::Configure(const config_param &param, Error &error)
+HttpdOutput::Configure(const ConfigBlock &block, Error &error)
{
/* read configuration */
- name = param.GetBlockValue("name", "Set name in config");
- genre = param.GetBlockValue("genre", "Set genre in config");
- website = param.GetBlockValue("website", "Set website in config");
+ name = block.GetBlockValue("name", "Set name in config");
+ genre = block.GetBlockValue("genre", "Set genre in config");
+ website = block.GetBlockValue("website", "Set website in config");
- unsigned port = param.GetBlockValue("port", 8000u);
+ unsigned port = block.GetBlockValue("port", 8000u);
const char *encoder_name =
- param.GetBlockValue("encoder", "vorbis");
+ block.GetBlockValue("encoder", "vorbis");
const auto encoder_plugin = encoder_plugin_get(encoder_name);
if (encoder_plugin == nullptr) {
error.Format(httpd_output_domain,
@@ -108,11 +111,11 @@ HttpdOutput::Configure(const config_param &param, Error &error)
return false;
}
- clients_max = param.GetBlockValue("max_clients", 0u);
+ clients_max = block.GetBlockValue("max_clients", 0u);
/* set up bind_to_address */
- const char *bind_to_address = param.GetBlockValue("bind_to_address");
+ const char *bind_to_address = block.GetBlockValue("bind_to_address");
bool success = bind_to_address != nullptr &&
strcmp(bind_to_address, "any") != 0
? AddHost(bind_to_address, port, error)
@@ -122,7 +125,7 @@ HttpdOutput::Configure(const config_param &param, Error &error)
/* initialize encoder */
- encoder = encoder_init(*encoder_plugin, param, error);
+ encoder = encoder_init(*encoder_plugin, block, error);
if (encoder == nullptr)
return false;
@@ -135,17 +138,17 @@ HttpdOutput::Configure(const config_param &param, Error &error)
}
inline bool
-HttpdOutput::Init(const config_param &param, Error &error)
+HttpdOutput::Init(const ConfigBlock &block, Error &error)
{
- return base.Configure(param, error);
+ return base.Configure(block, error);
}
static AudioOutput *
-httpd_output_init(const config_param &param, Error &error)
+httpd_output_init(const ConfigBlock &block, Error &error)
{
HttpdOutput *httpd = new HttpdOutput(io_thread_get());
- AudioOutput *result = httpd->InitAndConfigure(param, error);
+ AudioOutput *result = httpd->InitAndConfigure(block, error);
if (result == nullptr)
delete httpd;
@@ -167,9 +170,9 @@ httpd_output_finish(AudioOutput *ao)
inline void
HttpdOutput::AddClient(int fd)
{
- clients.emplace_front(*this, fd, GetEventLoop(),
- encoder->plugin.tag == nullptr);
- ++clients_cnt;
+ auto *client = new HttpdClient(*this, fd, GetEventLoop(),
+ encoder->plugin.tag == nullptr);
+ clients.push_front(*client);
/* pass metadata to client */
if (metadata != nullptr)
@@ -200,16 +203,14 @@ HttpdOutput::RunDeferred()
}
void
-HttpdOutput::OnAccept(int fd, const sockaddr &address,
- size_t address_length, gcc_unused int uid)
+HttpdOutput::OnAccept(int fd, SocketAddress address, gcc_unused int uid)
{
/* the listener socket has become readable - a client has
connected */
#ifdef HAVE_LIBWRAP
- if (address.sa_family != AF_UNIX) {
- const auto hostaddr = sockaddr_to_string(&address,
- address_length);
+ if (address.GetFamily() != AF_UNIX) {
+ const auto hostaddr = ToString(address);
// TODO: shall we obtain the program name from argv[0]?
const char *progname = "mpd";
@@ -229,14 +230,13 @@ HttpdOutput::OnAccept(int fd, const sockaddr &address,
}
#else
(void)address;
- (void)address_length;
#endif /* HAVE_WRAP */
const ScopeLock protect(mutex);
if (fd >= 0) {
/* can we allow additional client */
- if (open && (clients_max == 0 || clients_cnt < clients_max))
+ if (open && (clients_max == 0 || clients.size() < clients_max))
AddClient(fd);
else
close_socket(fd);
@@ -294,7 +294,7 @@ httpd_output_disable(AudioOutput *ao)
inline bool
HttpdOutput::OpenEncoder(AudioFormat &audio_format, Error &error)
{
- if (!encoder_open(encoder, audio_format, error))
+ if (!encoder->Open(audio_format, error))
return false;
/* we have to remember the encoder header, i.e. the first
@@ -320,7 +320,6 @@ HttpdOutput::Open(AudioFormat &audio_format, Error &error)
/* initialize other attributes */
- clients_cnt = 0;
timer = new Timer(audio_format);
open = true;
@@ -348,13 +347,13 @@ HttpdOutput::Close()
delete timer;
BlockingCall(GetEventLoop(), [this](){
- clients.clear();
+ clients.clear_and_dispose(DeleteDisposer());
});
if (header != nullptr)
header->Unref();
- encoder_close(encoder);
+ encoder->Close();
}
static void
@@ -369,17 +368,10 @@ httpd_output_close(AudioOutput *ao)
void
HttpdOutput::RemoveClient(HttpdClient &client)
{
- assert(clients_cnt > 0);
+ assert(!clients.empty());
- for (auto prev = clients.before_begin(), i = std::next(prev);;
- prev = i, i = std::next(prev)) {
- assert(i != clients.end());
- if (&*i == &client) {
- clients.erase_after(prev);
- clients_cnt--;
- break;
- }
- }
+ clients.erase_and_dispose(clients.iterator_to(client),
+ DeleteDisposer());
}
void
@@ -499,10 +491,8 @@ httpd_output_pause(AudioOutput *ao)
}
inline void
-HttpdOutput::SendTag(const Tag *tag)
+HttpdOutput::SendTag(const Tag &tag)
{
- assert(tag != nullptr);
-
if (encoder->plugin.tag != nullptr) {
/* embed encoder tags */
@@ -538,7 +528,7 @@ HttpdOutput::SendTag(const Tag *tag)
TAG_NUM_OF_ITEM_TYPES
};
- metadata = icy_server_metadata_page(*tag, &types[0]);
+ metadata = icy_server_metadata_page(tag, &types[0]);
if (metadata != nullptr) {
const ScopeLock protect(mutex);
for (auto &client : clients)
@@ -548,7 +538,7 @@ HttpdOutput::SendTag(const Tag *tag)
}
static void
-httpd_output_tag(AudioOutput *ao, const Tag *tag)
+httpd_output_tag(AudioOutput *ao, const Tag &tag)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.hxx b/src/output/plugins/httpd/HttpdOutputPlugin.hxx
index df99e2b43..8280d9fb2 100644
--- a/src/output/plugins/httpd/HttpdOutputPlugin.hxx
+++ b/src/output/plugins/httpd/HttpdOutputPlugin.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/output/plugins/httpd/IcyMetaDataServer.cxx b/src/output/plugins/httpd/IcyMetaDataServer.cxx
index 146df23d1..fe841ac11 100644
--- a/src/output/plugins/httpd/IcyMetaDataServer.cxx
+++ b/src/output/plugins/httpd/IcyMetaDataServer.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,8 +22,8 @@
#include "Page.hxx"
#include "tag/Tag.hxx"
#include "util/FormatString.hxx"
-
-#include <glib.h>
+#include "util/StringUtil.hxx"
+#include "util/Macros.hxx"
#include <string.h>
@@ -57,16 +57,13 @@ icy_server_metadata_header(const char *name,
static char *
icy_server_metadata_string(const char *stream_title, const char* stream_url)
{
- gchar *icy_metadata;
- guint meta_length;
-
// The leading n is a placeholder for the length information
- icy_metadata = FormatNew("nStreamTitle='%s';"
- "StreamUrl='%s';",
- stream_title,
- stream_url);
+ char *icy_metadata = FormatNew("nStreamTitle='%s';"
+ "StreamUrl='%s';",
+ stream_title,
+ stream_url);
- meta_length = strlen(icy_metadata);
+ size_t meta_length = strlen(icy_metadata);
meta_length--; // subtract placeholder
@@ -85,43 +82,30 @@ icy_server_metadata_string(const char *stream_title, const char* stream_url)
Page *
icy_server_metadata_page(const Tag &tag, const TagType *types)
{
- const gchar *tag_items[TAG_NUM_OF_ITEM_TYPES];
- gint last_item, item;
- guint position;
- gchar *icy_string;
- gchar stream_title[(1 + 255 - 28) * 16]; // Length + Metadata -
- // "StreamTitle='';StreamUrl='';"
- // = 4081 - 28
- stream_title[0] = '\0';
-
- last_item = -1;
+ const char *tag_items[TAG_NUM_OF_ITEM_TYPES];
+ int last_item = -1;
while (*types != TAG_NUM_OF_ITEM_TYPES) {
- const gchar *tag_item = tag.GetValue(*types++);
+ const char *tag_item = tag.GetValue(*types++);
if (tag_item)
tag_items[++last_item] = tag_item;
}
- position = item = 0;
- while (position < sizeof(stream_title) && item <= last_item) {
- gint length = 0;
-
- length = g_strlcpy(stream_title + position,
- tag_items[item++],
- sizeof(stream_title) - position);
+ int item = 0;
- position += length;
+ // Length + Metadata - "StreamTitle='';StreamUrl='';" = 4081 - 28
+ char stream_title[(1 + 255 - 28) * 16];
+ char *p = stream_title, *const end = stream_title + ARRAY_SIZE(stream_title);
+ stream_title[0] = '\0';
- if (item <= last_item) {
- length = g_strlcpy(stream_title + position,
- " - ",
- sizeof(stream_title) - position);
+ while (p < end && item <= last_item) {
+ p = CopyString(p, tag_items[item++], end - p);
- position += length;
- }
+ if (item <= last_item)
+ p = CopyString(p, " - ", end - p);
}
- icy_string = icy_server_metadata_string(stream_title, "");
+ char *icy_string = icy_server_metadata_string(stream_title, "");
if (icy_string == nullptr)
return nullptr;
diff --git a/src/output/plugins/httpd/IcyMetaDataServer.hxx b/src/output/plugins/httpd/IcyMetaDataServer.hxx
index 773b46641..38415e5bd 100644
--- a/src/output/plugins/httpd/IcyMetaDataServer.hxx
+++ b/src/output/plugins/httpd/IcyMetaDataServer.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/output/plugins/httpd/Page.cxx b/src/output/plugins/httpd/Page.cxx
index e22134bbc..ff7036645 100644
--- a/src/output/plugins/httpd/Page.cxx
+++ b/src/output/plugins/httpd/Page.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/output/plugins/httpd/Page.hxx b/src/output/plugins/httpd/Page.hxx
index 95f35d06a..88b7c2d85 100644
--- a/src/output/plugins/httpd/Page.hxx
+++ b/src/output/plugins/httpd/Page.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify