File: server_settings.hpp

package info (click to toggle)
snapcast 0.34.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,252 kB
  • sloc: cpp: 40,067; python: 3,260; sh: 455; makefile: 16
file content (258 lines) | stat: -rw-r--r-- 8,077 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/***
    This file is part of snapcast
    Copyright (C) 2014-2025  Johannes Pohl

    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, either version 3 of the License, or
    (at your option) any later version.

    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, see <http://www.gnu.org/licenses/>.
***/

#pragma once


// local headers
#include "common/snap_exception.hpp"
#include "common/utils/string_utils.hpp"

// standard headers
#include <algorithm>
#include <cstdint>
#include <filesystem>
#include <memory>
#include <string>
#include <vector>

/// Server settings
struct ServerSettings
{
    /// Launch settings
    struct Server
    {
        /// Number of worker threads
        int threads{-1};
        /// PID file, if running as daemon
        std::string pid_file{"/var/run/snapserver/pid"};
        /// User when running as deaemon
        std::string user{"snapserver"};
        /// Group when running as deaemon
        std::string group;
        /// Server data dir
        std::string data_dir;
        /// Enable mDNS to publish services
        bool mdns_enabled{true};
    };

    /// SSL settings
    struct Ssl
    {
        /// Certificate file
        std::filesystem::path certificate;
        /// Private key file
        std::filesystem::path certificate_key;
        /// Password for encrypted key file
        std::string key_password;
        /// Verify client certificates
        bool verify_clients = false;
        /// Client CA certificates
        std::vector<std::filesystem::path> client_certs;

        /// @return if SSL is enabled
        bool enabled() const
        {
            return !certificate.empty() && !certificate_key.empty();
        }
    };

    /// Authorization settings
    struct Authorization
    {
        /// c'tor
        Authorization() = default;

        /// Init with @p conf_roles and @p conf_users
        void init(const std::vector<std::string>& conf_roles, const std::vector<std::string>& conf_users)
        {
            roles.clear();
            users.clear();

            for (const auto& role : conf_roles)
                roles.emplace_back(std::make_shared<ServerSettings::Authorization::Role>(role));

            auto empty_role = std::make_shared<ServerSettings::Authorization::Role>();
            for (const auto& conf_user : conf_users)
            {
                users.emplace_back(conf_user);
                ServerSettings::Authorization::User& user = users.back();
                if (user.role_name.empty())
                {
                    user.role = empty_role;
                }
                else
                {
                    const auto& role_iter = std::find_if(roles.begin(), roles.end(), [&](const auto& role) { return role->role == user.role_name; });
                    if (role_iter != roles.end())
                        user.role = *role_iter;
                }
                if (user.role == nullptr)
                    throw SnapException("Role '" + user.role_name + "' for user '" + user.name + "' not found");
            }
        }

        /// Role settings
        struct Role
        {
            /// c'tor
            Role() = default;

            /// c'tor
            explicit Role(const std::string& role_permissions)
            {
                std::string perm;
                role = utils::string::split_left(role_permissions, ':', perm);
                permissions = utils::string::split(perm, ',');
            }

            /// role name
            std::string role;
            /// permissions
            std::vector<std::string> permissions;
        };

        /// User settings
        struct User
        {
            /// c'tor
            explicit User(const std::string& user_password_role)
            {
                std::string perm;
                name = utils::string::split_left(user_password_role, ':', perm);
                password = utils::string::split_right(perm, ':', role_name);
            }

            /// user name
            std::string name;
            /// password
            std::string password;
            /// role
            std::string role_name;
            /// role
            std::shared_ptr<Role> role;
        };

        /// is auth enabled
        bool enabled{false};
        /// users
        std::vector<User> users;
        /// roles
        std::vector<std::shared_ptr<Role>> roles;
    };

    /// HTTP settings
    struct Http
    {
        /// enable HTTP server
        bool enabled{true};
        /// enable HTTPS
        bool ssl_enabled{false};
        /// HTTP port
        size_t port{1780};
        /// HTTPS port
        size_t ssl_port{1788};
        /// HTTP listen address
        std::vector<std::string> bind_to_address{{"::"}};
        /// HTTPS listen address
        std::vector<std::string> ssl_bind_to_address{{"::"}};
        /// doc root directory
        std::string doc_root;
        /// HTTP server host name
        std::string host{"<hostname>"};
        /// URL prefix when serving album art
        std::string url_prefix;
        /// Publish HTTP service via mDNS as '_snapcast-http._tcp'
        bool publish_http{true};
        /// Publish HTTPS service via mDNS as '_snapcast-https._tcp'
        bool publish_https{true};
    };

    /// TCP control client settings
    struct TcpControl
    {
        /// enable plain TCP control
        bool enabled{true};
        /// TCP port
        size_t port{1705};
        /// TCP listen addresses
        std::vector<std::string> bind_to_address{{"::"}};
        /// Publish TCP control service via mDNS as '_snapcast-ctrl._tcp'
        bool publish{true};
    };

    /// TCP streaming client settings
    struct TcpStream
    {
        /// enable plain TCP audio streaming
        bool enabled{true};
        /// TCP port
        size_t port{1704};
        /// TCP listen addresses
        std::vector<std::string> bind_to_address{{"::"}};
        /// Publish TCP streaming service via mDNS as '_snapcast._tcp'
        bool publish{true};
    };

    /// Stream settings
    struct Stream
    {
        /// Directory for stream plugins
        std::filesystem::path plugin_dir{"/usr/share/snapserver/plug-ins"};
        /// Directory for executable process stream sources
        std::filesystem::path sandbox_dir{"/usr/share/snapserver/sandbox"};
        /// Stream sources
        std::vector<std::string> sources;
        /// Default codec
        std::string codec{"flac"};
        /// Default end to end delay
        int32_t bufferMs{1000};
        /// Default sample format
        std::string sampleFormat{"48000:16:2"};
        /// Default read size for stream sources
        size_t streamChunkMs{20};
        /// Send audio to muted clients?
        bool sendAudioToMutedClients{false};
    };

    /// Client settings
    struct StreamingClient
    {
        /// Initial volume of new clients
        uint16_t initialVolume{100};
    };

    /// Logging settings
    struct Logging
    {
        /// log sink
        std::string sink;
        /// log filter
        std::string filter{"*:info"};
    };

    Server server;                   ///< Server settings
    Ssl ssl;                         ///< SSL settings
    Authorization auth;              ///< Auth settings
    Http http;                       ///< HTTP settings
    TcpControl tcp_control;          ///< TCP-Control settings
    TcpStream tcp_stream;            ///< TCP-Stream settings
    Stream stream;                   ///< Stream settings
    StreamingClient streamingclient; ///< Client settings
    Logging logging;                 ///< Logging settings
};