diff --git a/foo_httpcontrol/readme.html b/foo_httpcontrol/readme.html
index 86f76b6..b337cd5 100755
--- a/foo_httpcontrol/readme.html
+++ b/foo_httpcontrol/readme.html
@@ -5,13 +5,30 @@
-foo_httpcontrol 0.97.15 02 Mar 2014
+foo_httpcontrol 0.97.16 13 Jan 2016
http://code.google.com/p/foo-httpcontrol
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.
Limit access to component by defining a login/password pair. Untick to disable passwords.
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.
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.
+ Ignore files with specific extensions in file browser.
+ 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).
+Suggested value setting: http|https
Removes all files which foobar2000 core considers unplayable from built-in file browser.
Specifies path where component will look for template files. Pressing Open opens specified or default directory in Explorer. If not sure, leave it blank.
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.
@@ -73,6 +93,15 @@ Don't forget to press Apply or your changes won't have any effect until fb2k is
Discussion thread (please post all your questions and suggestions here):
http://www.hydrogenaudio.org/forums/index.php?showtopic=62218
+Changes history 2016
+v0.97.16 13 Jan
+
+- 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).
+Suggested value setting: http|https
+- add: Meaningful console error messages when Browse command refuses to add specified file / location;
+
+
+
Changes history 2014
v0.97.15 02 Mar
@@ -420,14 +449,18 @@ example: ?cmd=PlayingCommand¶m1=Playback%20Statistics%2FRating%2F3
cmd=SetFocus
param1=item starting from 0
-- Browse directory
+ - Enqueue single file or url
cmd=Browse
- param1=urlencoded path
+ param1=urlencoded file path / url
- Enqueue path
+ cmd=Browse
+ param1=urlencoded path
param2=EnqueueDir
- Enqueue path including subdirectories
+ cmd=Browse
+ param1=urlencoded path
param2=EnqueueDirSubdirs
- Put active playlist items to playback queue
diff --git a/foo_httpcontrol/readme.png b/foo_httpcontrol/readme.png
index f9c95d9..3e09309 100755
Binary files a/foo_httpcontrol/readme.png and b/foo_httpcontrol/readme.png differ
diff --git a/foo_httpcontrol/src/callbacks.cpp b/foo_httpcontrol/src/callbacks.cpp
index d0f4b17..ad3f5a5 100755
--- a/foo_httpcontrol/src/callbacks.cpp
+++ b/foo_httpcontrol/src/callbacks.cpp
@@ -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
diff --git a/foo_httpcontrol/src/commands.cpp b/foo_httpcontrol/src/commands.cpp
index e85d485..bd0023e 100755
--- a/foo_httpcontrol/src/commands.cpp
+++ b/foo_httpcontrol/src/commands.cpp
@@ -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,20 +832,36 @@ namespace control
list_t 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 (strcmp(param2, "EnqueueDir") == 0) // adding a directory without nesting;
+ 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)
{
- browser.browse(const_cast(filename.operator const char *()));
+ 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(filename.operator const char *()));
- t_size l = browser.entries.get_count();
- for(unsigned int i = 0; i < l; ++i)
- if (browser.entries[i].type != foo_browsefiles::ET_DIR)
- files.add_item(browser.entries[i].path);
+ t_size l = browser.entries.get_count();
+ for(unsigned int i = 0; i < l; ++i)
+ 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
{
static_api_ptr_t()->activeplaylist_undo_backup();
diff --git a/foo_httpcontrol/src/config.cpp b/foo_httpcontrol/src/config.cpp
index c73d938..84cc62d 100755
--- a/foo_httpcontrol/src/config.cpp
+++ b/foo_httpcontrol/src/config.cpp
@@ -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())
diff --git a/foo_httpcontrol/src/config.h b/foo_httpcontrol/src/config.h
index c3c2b95..bf3b875 100755
--- a/foo_httpcontrol/src/config.h
+++ b/foo_httpcontrol/src/config.h
@@ -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); }
diff --git a/foo_httpcontrol/src/foo_httpcontrol_preferences.rc b/foo_httpcontrol/src/foo_httpcontrol_preferences.rc
index 0a6ecc9..3226131 100755
--- a/foo_httpcontrol/src/foo_httpcontrol_preferences.rc
+++ b/foo_httpcontrol/src/foo_httpcontrol_preferences.rc
@@ -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
}
diff --git a/foo_httpcontrol/src/httpcontrol.cpp b/foo_httpcontrol/src/httpcontrol.cpp
index 6cd0e9a..96192a8 100755
--- a/foo_httpcontrol/src/httpcontrol.cpp
+++ b/foo_httpcontrol/src/httpcontrol.cpp
@@ -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");
diff --git a/foo_httpcontrol/src/resource.h b/foo_httpcontrol/src/resource.h
index ce9aa6b..e92d117 100755
--- a/foo_httpcontrol/src/resource.h
+++ b/foo_httpcontrol/src/resource.h
@@ -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
diff --git a/foo_httpcontrol/src/state.cpp b/foo_httpcontrol/src/state.cpp
index a205641..4156dac 100755
--- a/foo_httpcontrol/src/state.cpp
+++ b/foo_httpcontrol/src/state.cpp
@@ -61,6 +61,7 @@ namespace httpc {
pfc::string_simple control_credentials_auth_hash;
pfc::list_t extensions; // registered extensions
pfc::list_t extension_names;// registered extension names
+ pfc::list_t allowed_protocols; // allowed protocols
pfc::string8 restrict_mask; // restrict mask based on registered extensions
pfc::list_t playlist_list; // list of playlists
pfc::string8 fb2k_profile_path;
@@ -568,13 +569,13 @@ 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)
- return true;
+ 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 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;
diff --git a/foo_httpcontrol/src/state.h b/foo_httpcontrol/src/state.h
index eda2d35..898e9e8 100755
--- a/foo_httpcontrol/src/state.h
+++ b/foo_httpcontrol/src/state.h
@@ -95,6 +95,7 @@ namespace httpc {
extern pfc::string_simple control_credentials_auth_hash;
extern pfc::list_t extensions;
extern pfc::list_t extension_names;
+ extern pfc::list_t allowed_protocols;
extern pfc::string8 restrict_mask;
extern pfc::list_t 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();