foo_httpcontrol: Customizable allowed protocols setting; Meaningful Browse command console error messages; 0.97.16 released

This commit is contained in:
oblikoamorale
2016-01-13 23:04:08 +03:00
parent 76c9b2d546
commit 8d2ef73b06
11 changed files with 119 additions and 30 deletions

View File

@@ -5,13 +5,30 @@
<style type="text/css">
body{ font: 0.75em "Arial", sans-serif; margin: 10px; background-color: #ffffff; max-width: 800px; }
ul#commands li { margin-bottom: 0.5em; }
ol {
list-style-type: none;
counter-reset: li-counter;
}
ol li:before {
font-weight: bold;
font-size: 2em;
color: red;
content: counter(li-counter);
counter-increment: li-counter;
padding-right: 0.5em;
margin-top: 0.5em;
}
ol li {
vertical-align: middle;
margin-bottom: 1em;
}
h2 {border-bottom: 1px solid gray}
h2#warn {color: red; border: 0px;}
p {text-indent: 2em; }
</style>
</head>
<body>
<h2>foo_httpcontrol 0.97.15 02 Mar 2014</h2>
<h2>foo_httpcontrol 0.97.16 13 Jan 2016</h2>
<p><a href="http://code.google.com/p/foo-httpcontrol/">http://code.google.com/p/foo-httpcontrol</a></p>
<h2 id="warn">Warning/disclaimer: this software comes without any warranties at all. It is still in the very early development stage, and so on, and so forth, blah-blah-blah.
@@ -60,6 +77,9 @@ customizing any template you are using, or even writing your very own one.</p>
<li>Limit access to component by defining a login/password pair. Untick to disable passwords.</li>
<li>Built-in file browser can be limited to certain paths of your file system. It is useful to simplify the browsing process or hide your secret files from prying eyes. For example, setting Allowed paths to d:\music|c:\temp\music|e:\ permits browsing only in these three file system branches.</li>
<li>You can specify additional file extensions to be treated as playable files by built-in file browser. It is required for opening archives containing playable files.</li>
<li>Ignore files with specific extensions in file browser.</li>
<li>Urls of specified protocols are allowed to be enqueued by Browse command. Enables enqueueing of urls handled by 3rd party components like foo_youtube (3dydfy protocol).<br>
Suggested value setting: http|https</li>
<li>Removes all files which foobar2000 core considers unplayable from built-in file browser.</li>
<li>Specifies path where component will look for template files. Pressing Open opens specified or default directory in Explorer. If not sure, leave it blank. </li>
<li>Enables gzip compression of component output. Enabling it is usually harmless and quite beneficial as component generates a lot of text which is very compressible. Disable if you are using some funky browser and having unexpected problems.</li>
@@ -73,6 +93,15 @@ Don't forget to press Apply or your changes won't have any effect until fb2k is
<p>Discussion thread (please post all your questions and suggestions here):
<a href="http://www.hydrogenaudio.org/forums/index.php?showtopic=62218">http://www.hydrogenaudio.org/forums/index.php?showtopic=62218</a></p>
<h2>Changes history 2016</h2>
<p>v0.97.16 13 Jan</p>
<ul>
<li>add: Allowed protocols GUI setting: urls of specified protocols are allowed to be enqueued by Browse command. Previously the only hardcoded protocol was http. New setting also enables enqueueing of urls handled by 3rd party components like foo_youtube (3dydfy protocol).<br>
Suggested value setting: http|https</li>
<li>add: Meaningful console error messages when Browse command refuses to add specified file / location;</li>
</ul>
<h2>Changes history 2014</h2>
<p>v0.97.15 02 Mar</p>
<ul>
@@ -420,14 +449,18 @@ example: ?cmd=PlayingCommand&amp;param1=Playback%20Statistics%2FRating%2F3</li>
cmd=SetFocus<br/>
param1=item starting from 0</li>
<li>Browse directory<br/>
<li>Enqueue single file or url<br/>
cmd=Browse<br/>
param1=urlencoded path</li>
param1=urlencoded file path / url</li>
<li>Enqueue path<br/>
cmd=Browse<br/>
param1=urlencoded path<br/>
param2=EnqueueDir</li>
<li>Enqueue path including subdirectories<br/>
cmd=Browse<br/>
param1=urlencoded path<br/>
param2=EnqueueDirSubdirs</li>
<li>Put active playlist items to playback queue <br/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -229,6 +229,9 @@ public:
// get registered extensions list
httpc::get_registered_extensions();
httpc::set_allowed_protocols();
httpc::control_credentials_auth_hash_update();
// getting hang of where do we get templates and stuff

View File

@@ -27,8 +27,10 @@ namespace control
{
const char *item_path = p_items[i]->get_path();
if (httpc::is_extension_registered(item_path) != -1 || httpc::is_protocol_registered(item_path))
if (httpc::is_extension_registered(item_path) != -1 || httpc::is_protocol_allowed(item_path))
p_items_toadd.add_item(p_items[i]);
else
foo_error(pfc::string8() << "skipping \"" << item_path << "\": unrecognized extension or not allowed protocol");
}
plm->activeplaylist_add_items(p_items_toadd, bit_array_true());
@@ -754,7 +756,7 @@ namespace control
}
catch (pfc::exception &e)
{
console::error(e.what());
foo_error(e.what());
}
if (apm->is_client_present(playlist))
@@ -830,10 +832,25 @@ namespace control
list_t<const char *> files; // files/dirs to be enqueued
pfc::string8 filename = param1;
if (( httpc::is_extension_registered(filename) != pfc::infinite_size || httpc::is_protocol_registered(filename) ) && param2.get_length() == 0 // adding a single file
|| strcmp(param2, "EnqueueDirSubdirs") == 0) // adding a nested directory
if (param1.get_length() == 0)
foo_error("param1 cannot be empty");
if (param2.get_length() > 0 &&
(strcmp(param2, "EnqueueDir") != 0 && strcmp(param2, "EnqueueDirSubdirs") != 0))
foo_error(pfc::string8() << "unsupported param2 value: \"" << param2 << "\"");
if (( httpc::is_extension_registered(filename) != pfc::infinite_size || httpc::is_protocol_allowed(filename) ) && param2.get_length() == 0) // adding a single file
files.add_item(filename);
else
if (param2.get_length() == 0)
foo_error(pfc::string8() << "skipping \"" << filename << "\": unrecognized extension or not allowed protocol");
if (param1.get_length() != 0 && param2.get_length() != 0)
{
if (strcmp(param2, "EnqueueDirSubdirs") == 0) // adding a nested directory
{
files.add_item(filename);
}
if (strcmp(param2, "EnqueueDir") == 0) // adding a directory without nesting;
{
browser.browse(const_cast<char *>(filename.operator const char *()));
@@ -843,6 +860,7 @@ namespace control
if (browser.entries[i].type != foo_browsefiles::ET_DIR)
files.add_item(browser.entries[i].path);
}
}
if (files.get_count()) // if there is anything to enqueue
{

View File

@@ -28,6 +28,7 @@ void config_main::copy(const config_main &cfg)
gzip_enable = cfg.gzip_enable;
extra_formats = cfg.extra_formats;
ignored_formats = cfg.ignored_formats;
allowed_protocols = cfg.allowed_protocols;
}
void config_main::reset()
@@ -50,6 +51,7 @@ void config_main::reset()
gzip_enable = false;
extra_formats = "zip|rar";
ignored_formats = "";
allowed_protocols = "http|https|3dydfy";
}
void config_main::get_data_raw(stream_writer * p_stream,abort_callback & p_abort)
@@ -72,6 +74,7 @@ void config_main::get_data_raw(stream_writer * p_stream,abort_callback & p_abort
p_stream->write_lendian_t(gzip_enable, p_abort);
p_stream->write_string(extra_formats, p_abort);
p_stream->write_string(ignored_formats, p_abort);
p_stream->write_string(allowed_protocols, p_abort);
}
void config_main::set_data_raw(stream_reader * p_stream,unsigned p_sizehint,abort_callback & p_abort)
@@ -94,6 +97,7 @@ void config_main::set_data_raw(stream_reader * p_stream,unsigned p_sizehint,abor
p_stream->read_lendian_t(gzip_enable, p_abort);
p_stream->read_string(extra_formats, p_abort);
p_stream->read_string(ignored_formats, p_abort);
p_stream->read_string(allowed_protocols, p_abort);
}
bool config_main::operator == (const config_main &c)
@@ -115,7 +119,8 @@ bool config_main::operator == (const config_main &c)
&&(c.stop_after_queue_enable == stop_after_queue_enable)
&&(c.gzip_enable == gzip_enable)
&&(c.extra_formats == extra_formats)
&&(c.ignored_formats == ignored_formats));
&&(c.ignored_formats == ignored_formats)
&&(c.allowed_protocols == allowed_protocols));
}
void config_misc::reset()
@@ -285,6 +290,10 @@ void preferences_page_main::OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl)
cfg_main_new.ignored_formats = string_utf8_from_window(GetDlgItem(nID));
cfg_main_new.ignored_formats = trim(cfg_main_new.ignored_formats);
break;
case IDC_ALLOWED_PROTOCOLS | (EN_CHANGE << 16):
cfg_main_new.allowed_protocols = string_utf8_from_window(GetDlgItem(nID));
cfg_main_new.allowed_protocols = trim(cfg_main_new.allowed_protocols);
break;
case IDC_STOP_AFTER_QUEUE_ENABLE | (BN_CLICKED << 16):
cfg_main_new.stop_after_queue_enable = IsDlgButtonChecked(nID) == BST_CHECKED;
break;
@@ -339,6 +348,7 @@ void preferences_page_main::updateDialog()
uSetDlgItemText(m_hWnd,IDC_CONTROL_PATH,cfg_main_new.restrict_to_path);
uSetDlgItemText(m_hWnd,IDC_EXTRA_FORMATS,cfg_main_new.extra_formats);
uSetDlgItemText(m_hWnd,IDC_IGNORED_FORMATS,cfg_main_new.ignored_formats);
uSetDlgItemText(m_hWnd,IDC_ALLOWED_PROTOCOLS,cfg_main_new.allowed_protocols);
uSetDlgItemText(m_hWnd,IDC_SERVER_ROOT,cfg_main_new.server_root);
CheckDlgButton(IDC_STOP_AFTER_QUEUE_ENABLE,cfg_main_new.stop_after_queue_enable);
CheckDlgButton(IDC_GZIP_ENABLE,cfg_main_new.gzip_enable);
@@ -382,6 +392,8 @@ void preferences_page_main::apply() {
httpc::get_registered_extensions();
httpc::set_allowed_protocols();
httpc::build_restrict_to_path_list();
if (cfg.main.startserver != httpc::control::is_active())

View File

@@ -45,6 +45,7 @@ public:
bool gzip_enable;
pfc::string8 extra_formats;
pfc::string8 ignored_formats;
pfc::string8 allowed_protocols;
config_main() { reset(); }
config_main(const config_main &cfg) { copy(cfg); }

View File

@@ -27,9 +27,9 @@ FONT 8, "MS Shell Dlg", 400, 0, 1
AUTOCHECKBOX "Credentials", IDC_CONTROL_CREDENTIALS, 37, 84, 51, 8, BS_LEFTTEXT | BS_NOTIFY, WS_EX_RIGHT
EDITTEXT IDC_CONTROL_USERNAME, 81, 99, 74, 13, WS_DISABLED | ES_AUTOHSCROLL
EDITTEXT IDC_CONTROL_PASSWORD, 220, 99, 73, 13, WS_DISABLED | ES_AUTOHSCROLL | ES_PASSWORD
EDITTEXT IDC_CONTROL_PATH, 81, 138, 212, 13, ES_AUTOHSCROLL
EDITTEXT IDC_EXTRA_FORMATS, 81, 158, 70, 13, ES_AUTOHSCROLL
AUTOCHECKBOX "Hide non-playable files", IDC_HIDE_NONPLAYABLES, 160, 179, 133, 15, BS_LEFTTEXT | BS_NOTIFY, WS_EX_RIGHT
EDITTEXT IDC_CONTROL_PATH, 92, 138, 201, 13, ES_AUTOHSCROLL
EDITTEXT IDC_EXTRA_FORMATS, 92, 158, 70, 13, ES_AUTOHSCROLL
AUTOCHECKBOX "Hide non-playable files", IDC_HIDE_NONPLAYABLES, 200, 179, 93, 15, BS_LEFTTEXT | BS_NOTIFY, WS_EX_RIGHT
EDITTEXT IDC_SERVER_ROOT, 81, 203, 183, 13, ES_AUTOHSCROLL
PUSHBUTTON "Open", IDC_SERVER_ROOT_BTN, 267, 203, 34, 12
AUTOCHECKBOX "HTTP compression (gzip)", IDC_GZIP_ENABLE, 37, 226, 116, 10, BS_LEFTTEXT, WS_EX_RIGHT
@@ -40,14 +40,16 @@ FONT 8, "MS Shell Dlg", 400, 0, 1
RTEXT "Remote IP", IDC_STATIC, 26, 67, 51, 11, SS_RIGHT
RTEXT "Username", IDC_STATIC_USERNAME, 26, 102, 51, 13, WS_DISABLED | SS_RIGHT
RTEXT "Password", IDC_STATIC_PASSWORD, 164, 102, 52, 13, WS_DISABLED | SS_RIGHT
RTEXT "Allowed paths", IDC_STATIC, 15, 141, 62, 15, SS_RIGHT
RTEXT "Allowed paths", IDC_STATIC, 24, 141, 62, 15, SS_RIGHT
RTEXT "Home directory", IDC_STATIC, 15, 205, 62, 12, SS_RIGHT
CTEXT ":", IDC_STATIC, 181, 11, 8, 12, SS_CENTER
GROUPBOX "File browser", IDC_STATIC, 15, 126, 286, 70
RTEXT "Extra formats", IDC_STATIC, 20, 160, 57, 15, SS_RIGHT
LTEXT """Allowed paths"", ""Extra formats"" and ""Hide formats"" fields accept several values separated by |.", IDC_STATIC, 30, 264, 260, 23, SS_LEFT
EDITTEXT IDC_IGNORED_FORMATS, 223, 159, 70, 13, ES_AUTOHSCROLL
RTEXT "Ignored formats", IDC_STATIC, 157, 161, 62, 15, SS_RIGHT
RTEXT "Extra formats", IDC_STATIC, 29, 160, 57, 15, SS_RIGHT
LTEXT """Allowed paths"", ""Extra formats"", ""Allowed protocols"" and ""Hide formats"" fields accept several values separated by |.", IDC_STATIC, 23, 262, 275, 20, SS_LEFT
EDITTEXT IDC_IGNORED_FORMATS, 235, 159, 58, 13, ES_AUTOHSCROLL
RTEXT "Ignored formats", IDC_STATIC, 169, 161, 62, 15, SS_RIGHT
RTEXT "Allowed protocols", IDC_STATIC, 17, 179, 69, 15, SS_RIGHT
EDITTEXT IDC_ALLOWED_PROTOCOLS, 92, 178, 70, 13, ES_AUTOHSCROLL
}

View File

@@ -3,7 +3,7 @@
DECLARE_COMPONENT_VERSION(
"HTTP Control",
"0.97.15",
"0.97.16",
"control foobar2000 via http "__DATE__)
VALIDATE_COMPONENT_FILENAME("foo_httpcontrol.dll");

View File

@@ -4,6 +4,7 @@
#define IDD_TAB1 101
#define IDD_TAB3 104
#define IDC_ALLOWED_PROTOCOLS 1000
#define IDC_INTERFACE 1001
#define IDC_PORT 1002
#define IDC_CONTROL_IP 1003

View File

@@ -61,6 +61,7 @@ namespace httpc {
pfc::string_simple control_credentials_auth_hash;
pfc::list_t<pfc::string_simple> extensions; // registered extensions
pfc::list_t<pfc::string_simple> extension_names;// registered extension names
pfc::list_t<pfc::string_simple> allowed_protocols; // allowed protocols
pfc::string8 restrict_mask; // restrict mask based on registered extensions
pfc::list_t<playlist_info> playlist_list; // list of playlists
pfc::string8 fb2k_profile_path;
@@ -568,12 +569,12 @@ namespace httpc {
return pfc::infinite_size;
}
bool is_protocol_registered(const char *path)
bool is_protocol_allowed(const char *path)
{
// hardcoding protocols since there seems to be no way of interrogating fb2k for supported protocols list
// protocol should be lowercase so no case insensitive comparision is required
size_t c = httpc::allowed_protocols.get_count();
if (strstr(path, "http://") == path)
for(size_t i = 0; i < c; ++i)
if (matchProtocol(path, allowed_protocols[i]))
return true;
return false;
@@ -674,6 +675,22 @@ namespace httpc {
}
}
void set_allowed_protocols()
{
pfc::list_t<pfc::string8> protocols;
pfc::splitStringSimple_toList(protocols, '|', cfg.main.allowed_protocols);
pfc::string8 protocol;
httpc::allowed_protocols.remove_all();
for (t_size i = 0; i < protocols.get_count(); ++i)
{
protocol = trim(protocols[i]);
if (protocol.get_length())
httpc::allowed_protocols.add_item(protocol);
}
}
void choose_srv_home_dir()
{
pfc::string8 server_root_tmp = cfg.main.server_root;

View File

@@ -95,6 +95,7 @@ namespace httpc {
extern pfc::string_simple control_credentials_auth_hash;
extern pfc::list_t<pfc::string_simple> extensions;
extern pfc::list_t<pfc::string_simple> extension_names;
extern pfc::list_t<pfc::string_simple> allowed_protocols;
extern pfc::string8 restrict_mask;
extern pfc::list_t<playlist_info> playlist_list;
extern pfc::string8 fb2k_profile_path;
@@ -122,8 +123,9 @@ namespace httpc {
extern void empty_previouslyplayed();
extern void get_registered_extensions();
extern void set_allowed_protocols();
extern size_t is_extension_registered(const char *path); // infininte if not registered, list index elsewere
extern bool is_protocol_registered(const char *path);
extern bool is_protocol_allowed(const char *path);
extern void choose_srv_home_dir();
extern void build_restrict_to_path_list();