summaryrefslogtreecommitdiffstats
path: root/xbmc/filesystem/test/TestHTTPDirectory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/filesystem/test/TestHTTPDirectory.cpp')
-rw-r--r--xbmc/filesystem/test/TestHTTPDirectory.cpp301
1 files changed, 301 insertions, 0 deletions
diff --git a/xbmc/filesystem/test/TestHTTPDirectory.cpp b/xbmc/filesystem/test/TestHTTPDirectory.cpp
new file mode 100644
index 0000000..7736307
--- /dev/null
+++ b/xbmc/filesystem/test/TestHTTPDirectory.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2015-2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "FileItem.h"
+#include "URL.h"
+#include "filesystem/CurlFile.h"
+#include "filesystem/HTTPDirectory.h"
+#include "network/WebServer.h"
+#include "network/httprequesthandler/HTTPVfsHandler.h"
+#include "settings/MediaSourceSettings.h"
+#include "test/TestUtils.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "utils/XTimeUtils.h"
+
+#include <random>
+#include <stdlib.h>
+
+#include <gtest/gtest.h>
+
+using namespace XFILE;
+
+#define WEBSERVER_HOST "localhost"
+
+#define SOURCE_PATH "xbmc/filesystem/test/data/httpdirectory/"
+
+#define TEST_FILE_APACHE_DEFAULT "apache-default.html"
+#define TEST_FILE_APACHE_FANCY "apache-fancy.html"
+#define TEST_FILE_APACHE_HTML "apache-html.html"
+#define TEST_FILE_BASIC "basic.html"
+#define TEST_FILE_BASIC_MULTILINE "basic-multiline.html"
+#define TEST_FILE_LIGHTTP_DEFAULT "lighttp-default.html"
+#define TEST_FILE_NGINX_DEFAULT "nginx-default.html"
+#define TEST_FILE_NGINX_FANCYINDEX "nginx-fancyindex.html"
+
+#define SAMPLE_ITEM_COUNT 6
+
+#define SAMPLE_ITEM_1_LABEL "folder1"
+#define SAMPLE_ITEM_2_LABEL "folder2"
+#define SAMPLE_ITEM_3_LABEL "sample3: the sampling.mpg"
+#define SAMPLE_ITEM_4_LABEL "sample & samplability 4.mpg"
+#define SAMPLE_ITEM_5_LABEL "sample5.mpg"
+#define SAMPLE_ITEM_6_LABEL "sample6.mpg"
+
+#define SAMPLE_ITEM_1_SIZE 0
+#define SAMPLE_ITEM_2_SIZE 0
+#define SAMPLE_ITEM_3_SIZE 123
+#define SAMPLE_ITEM_4_SIZE 125952 // 123K
+#define SAMPLE_ITEM_5_SIZE 128974848 // 123M
+#define SAMPLE_ITEM_6_SIZE 132070244352 // 123G
+
+// HTTPDirectory ignores the seconds component of parsed date/times
+#define SAMPLE_ITEM_1_DATETIME "2019-01-01 01:01:00"
+#define SAMPLE_ITEM_2_DATETIME "2019-02-02 02:02:00"
+#define SAMPLE_ITEM_3_DATETIME "2019-03-03 03:03:00"
+#define SAMPLE_ITEM_4_DATETIME "2019-04-04 04:04:00"
+#define SAMPLE_ITEM_5_DATETIME "2019-05-05 05:05:00"
+#define SAMPLE_ITEM_6_DATETIME "2019-06-06 06:06:00"
+
+class TestHTTPDirectory : public testing::Test
+{
+protected:
+ TestHTTPDirectory() : m_sourcePath(XBMC_REF_FILE_PATH(SOURCE_PATH))
+ {
+ std::random_device rd;
+ std::mt19937 mt(rd());
+ std::uniform_int_distribution<uint16_t> dist(49152, 65535);
+ m_webServerPort = dist(mt);
+
+ m_baseUrl = StringUtils::Format("http://" WEBSERVER_HOST ":{}", m_webServerPort);
+ }
+
+ ~TestHTTPDirectory() override = default;
+
+protected:
+ void SetUp() override
+ {
+ SetupMediaSources();
+
+ m_webServer.Start(m_webServerPort, "", "");
+ m_webServer.RegisterRequestHandler(&m_vfsHandler);
+ }
+
+ void TearDown() override
+ {
+ if (m_webServer.IsStarted())
+ m_webServer.Stop();
+
+ m_webServer.UnregisterRequestHandler(&m_vfsHandler);
+
+ TearDownMediaSources();
+ }
+
+ void SetupMediaSources()
+ {
+ CMediaSource source;
+ source.strName = "WebServer Share";
+ source.strPath = m_sourcePath;
+ source.vecPaths.push_back(m_sourcePath);
+ source.m_allowSharing = true;
+ source.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
+ source.m_iLockMode = LOCK_MODE_EVERYONE;
+ source.m_ignore = true;
+
+ CMediaSourceSettings::GetInstance().AddShare("videos", source);
+ }
+
+ void TearDownMediaSources() { CMediaSourceSettings::GetInstance().Clear(); }
+
+ std::string GetUrl(const std::string& path)
+ {
+ if (path.empty())
+ return m_baseUrl;
+
+ return URIUtils::AddFileToFolder(m_baseUrl, path);
+ }
+
+ std::string GetUrlOfTestFile(const std::string& testFile)
+ {
+ if (testFile.empty())
+ return "";
+
+ std::string path = URIUtils::AddFileToFolder(m_sourcePath, testFile);
+ path = CURL::Encode(path);
+ path = URIUtils::AddFileToFolder("vfs", path);
+
+ return GetUrl(path);
+ }
+
+ void CheckFileItemTypes(CFileItemList const& items)
+ {
+ ASSERT_EQ(items.GetObjectCount(), SAMPLE_ITEM_COUNT);
+
+ // folders
+ ASSERT_TRUE(items[0]->m_bIsFolder);
+ ASSERT_TRUE(items[1]->m_bIsFolder);
+
+ // files
+ ASSERT_FALSE(items[2]->m_bIsFolder);
+ ASSERT_FALSE(items[3]->m_bIsFolder);
+ ASSERT_FALSE(items[4]->m_bIsFolder);
+ ASSERT_FALSE(items[5]->m_bIsFolder);
+ }
+
+ void CheckFileItemLabels(CFileItemList const& items)
+ {
+ ASSERT_EQ(items.GetObjectCount(), SAMPLE_ITEM_COUNT);
+
+ ASSERT_STREQ(items[0]->GetLabel().c_str(), SAMPLE_ITEM_1_LABEL);
+ ASSERT_STREQ(items[1]->GetLabel().c_str(), SAMPLE_ITEM_2_LABEL);
+ ASSERT_STREQ(items[2]->GetLabel().c_str(), SAMPLE_ITEM_3_LABEL);
+ ASSERT_STREQ(items[3]->GetLabel().c_str(), SAMPLE_ITEM_4_LABEL);
+ ASSERT_STREQ(items[4]->GetLabel().c_str(), SAMPLE_ITEM_5_LABEL);
+ ASSERT_STREQ(items[5]->GetLabel().c_str(), SAMPLE_ITEM_6_LABEL);
+ }
+
+ void CheckFileItemDateTimes(CFileItemList const& items)
+ {
+ ASSERT_EQ(items.GetObjectCount(), SAMPLE_ITEM_COUNT);
+
+ ASSERT_STREQ(items[0]->m_dateTime.GetAsDBDateTime().c_str(), SAMPLE_ITEM_1_DATETIME);
+ ASSERT_STREQ(items[1]->m_dateTime.GetAsDBDateTime().c_str(), SAMPLE_ITEM_2_DATETIME);
+ ASSERT_STREQ(items[2]->m_dateTime.GetAsDBDateTime().c_str(), SAMPLE_ITEM_3_DATETIME);
+ ASSERT_STREQ(items[3]->m_dateTime.GetAsDBDateTime().c_str(), SAMPLE_ITEM_4_DATETIME);
+ ASSERT_STREQ(items[4]->m_dateTime.GetAsDBDateTime().c_str(), SAMPLE_ITEM_5_DATETIME);
+ ASSERT_STREQ(items[5]->m_dateTime.GetAsDBDateTime().c_str(), SAMPLE_ITEM_6_DATETIME);
+ }
+
+ void CheckFileItemSizes(CFileItemList const& items)
+ {
+ ASSERT_EQ(items.GetObjectCount(), SAMPLE_ITEM_COUNT);
+
+ // folders
+ ASSERT_EQ(items[0]->m_dwSize, SAMPLE_ITEM_1_SIZE);
+ ASSERT_EQ(items[1]->m_dwSize, SAMPLE_ITEM_2_SIZE);
+
+ // files - due to K/M/G conversions provided by some formats, allow for
+ // non-zero values that are less than or equal to the expected file size
+ ASSERT_NE(items[2]->m_dwSize, 0);
+ ASSERT_LE(items[2]->m_dwSize, SAMPLE_ITEM_3_SIZE);
+ ASSERT_NE(items[3]->m_dwSize, 0);
+ ASSERT_LE(items[3]->m_dwSize, SAMPLE_ITEM_4_SIZE);
+ ASSERT_NE(items[4]->m_dwSize, 0);
+ ASSERT_LE(items[4]->m_dwSize, SAMPLE_ITEM_5_SIZE);
+ ASSERT_NE(items[5]->m_dwSize, 0);
+ ASSERT_LE(items[5]->m_dwSize, SAMPLE_ITEM_6_SIZE);
+ }
+
+ void CheckFileItems(CFileItemList const& items)
+ {
+ CheckFileItemTypes(items);
+ CheckFileItemLabels(items);
+ }
+
+ void CheckFileItemsAndMetadata(CFileItemList const& items)
+ {
+ CheckFileItems(items);
+ CheckFileItemDateTimes(items);
+ CheckFileItemSizes(items);
+ }
+
+ CWebServer m_webServer;
+ uint16_t m_webServerPort;
+ std::string m_baseUrl;
+ std::string const m_sourcePath;
+ CHTTPVfsHandler m_vfsHandler;
+ CHTTPDirectory m_httpDirectory;
+};
+
+TEST_F(TestHTTPDirectory, IsStarted)
+{
+ ASSERT_TRUE(m_webServer.IsStarted());
+}
+
+TEST_F(TestHTTPDirectory, ApacheDefaultIndex)
+{
+ CFileItemList items;
+
+ ASSERT_TRUE(m_httpDirectory.Exists(CURL(GetUrlOfTestFile(TEST_FILE_APACHE_DEFAULT))));
+ ASSERT_TRUE(
+ m_httpDirectory.GetDirectory(CURL(GetUrlOfTestFile(TEST_FILE_APACHE_DEFAULT)), items));
+
+ CheckFileItems(items);
+}
+
+TEST_F(TestHTTPDirectory, ApacheFancyIndex)
+{
+ CFileItemList items;
+
+ ASSERT_TRUE(m_httpDirectory.Exists(CURL(GetUrlOfTestFile(TEST_FILE_APACHE_FANCY))));
+ ASSERT_TRUE(m_httpDirectory.GetDirectory(CURL(GetUrlOfTestFile(TEST_FILE_APACHE_FANCY)), items));
+
+ CheckFileItemsAndMetadata(items);
+}
+
+TEST_F(TestHTTPDirectory, ApacheHtmlIndex)
+{
+ CFileItemList items;
+
+ ASSERT_TRUE(m_httpDirectory.Exists(CURL(GetUrlOfTestFile(TEST_FILE_APACHE_HTML))));
+ ASSERT_TRUE(m_httpDirectory.GetDirectory(CURL(GetUrlOfTestFile(TEST_FILE_APACHE_HTML)), items));
+
+ CheckFileItemsAndMetadata(items);
+}
+
+TEST_F(TestHTTPDirectory, BasicIndex)
+{
+ CFileItemList items;
+
+ ASSERT_TRUE(m_httpDirectory.Exists(CURL(GetUrlOfTestFile(TEST_FILE_BASIC))));
+ ASSERT_TRUE(m_httpDirectory.GetDirectory(CURL(GetUrlOfTestFile(TEST_FILE_BASIC)), items));
+
+ CheckFileItems(items);
+}
+
+TEST_F(TestHTTPDirectory, BasicMultilineIndex)
+{
+ CFileItemList items;
+
+ ASSERT_TRUE(m_httpDirectory.Exists(CURL(GetUrlOfTestFile(TEST_FILE_BASIC_MULTILINE))));
+ ASSERT_TRUE(
+ m_httpDirectory.GetDirectory(CURL(GetUrlOfTestFile(TEST_FILE_BASIC_MULTILINE)), items));
+
+ CheckFileItems(items);
+}
+
+TEST_F(TestHTTPDirectory, LighttpDefaultIndex)
+{
+ CFileItemList items;
+
+ ASSERT_TRUE(m_httpDirectory.Exists(CURL(GetUrlOfTestFile(TEST_FILE_LIGHTTP_DEFAULT))));
+ ASSERT_TRUE(
+ m_httpDirectory.GetDirectory(CURL(GetUrlOfTestFile(TEST_FILE_LIGHTTP_DEFAULT)), items));
+
+ CheckFileItemsAndMetadata(items);
+}
+
+TEST_F(TestHTTPDirectory, NginxDefaultIndex)
+{
+ CFileItemList items;
+
+ ASSERT_TRUE(m_httpDirectory.Exists(CURL(GetUrlOfTestFile(TEST_FILE_NGINX_DEFAULT))));
+ ASSERT_TRUE(m_httpDirectory.GetDirectory(CURL(GetUrlOfTestFile(TEST_FILE_NGINX_DEFAULT)), items));
+
+ CheckFileItemsAndMetadata(items);
+}
+
+TEST_F(TestHTTPDirectory, NginxFancyIndex)
+{
+ CFileItemList items;
+
+ ASSERT_TRUE(m_httpDirectory.Exists(CURL(GetUrlOfTestFile(TEST_FILE_NGINX_FANCYINDEX))));
+ ASSERT_TRUE(m_httpDirectory.GetDirectory(CURL(GetUrlOfTestFile(TEST_FILE_NGINX_FANCYINDEX)), items));
+
+ CheckFileItemsAndMetadata(items);
+}