diff options
Diffstat (limited to 'xbmc/network/httprequesthandler/HTTPVfsHandler.cpp')
-rw-r--r-- | xbmc/network/httprequesthandler/HTTPVfsHandler.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/xbmc/network/httprequesthandler/HTTPVfsHandler.cpp b/xbmc/network/httprequesthandler/HTTPVfsHandler.cpp new file mode 100644 index 0000000..ef2f7a6 --- /dev/null +++ b/xbmc/network/httprequesthandler/HTTPVfsHandler.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011-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 "HTTPVfsHandler.h" + +#include "MediaSource.h" +#include "ServiceBroker.h" +#include "URL.h" +#include "Util.h" +#include "media/MediaLockState.h" +#include "settings/MediaSourceSettings.h" +#include "storage/MediaManager.h" +#include "utils/FileUtils.h" +#include "utils/URIUtils.h" + +CHTTPVfsHandler::CHTTPVfsHandler(const HTTPRequest &request) + : CHTTPFileHandler(request) +{ + std::string file; + int responseStatus = MHD_HTTP_BAD_REQUEST; + + if (m_request.pathUrl.size() > 5) + { + file = m_request.pathUrl.substr(5); + + if (CFileUtils::Exists(file)) + { + bool accessible = false; + if (file.substr(0, 8) == "image://") + accessible = true; + else + { + std::string sourceTypes[] = { "video", "music", "pictures" }; + unsigned int size = sizeof(sourceTypes) / sizeof(std::string); + + std::string realPath = URIUtils::GetRealPath(file); + // for rar:// and zip:// paths we need to extract the path to the archive instead of using the VFS path + while (URIUtils::IsInArchive(realPath)) + realPath = CURL(realPath).GetHostName(); + + // Check manually configured sources + VECSOURCES *sources = NULL; + for (unsigned int index = 0; index < size && !accessible; index++) + { + sources = CMediaSourceSettings::GetInstance().GetSources(sourceTypes[index]); + if (sources == NULL) + continue; + + for (const auto& source : *sources) + { + if (accessible) + break; + + // don't allow access to locked / disabled sharing sources + if (source.m_iHasLock == LOCK_STATE_LOCKED || !source.m_allowSharing) + continue; + + for (const auto& path : source.vecPaths) + { + std::string realSourcePath = URIUtils::GetRealPath(path); + if (URIUtils::PathHasParent(realPath, realSourcePath, true)) + { + accessible = true; + break; + } + } + } + } + + // Check auto-mounted sources + if (!accessible) + { + bool isSource; + VECSOURCES removableSources; + CServiceBroker::GetMediaManager().GetRemovableDrives(removableSources); + int sourceIndex = CUtil::GetMatchingSource(realPath, removableSources, isSource); + if (sourceIndex >= 0 && sourceIndex < static_cast<int>(removableSources.size()) && + removableSources.at(sourceIndex).m_iHasLock != LOCK_STATE_LOCKED && + removableSources.at(sourceIndex).m_allowSharing) + accessible = true; + } + } + + if (accessible) + responseStatus = MHD_HTTP_OK; + // the file exists but not in one of the defined sources so we deny access to it + else + responseStatus = MHD_HTTP_UNAUTHORIZED; + } + else + responseStatus = MHD_HTTP_NOT_FOUND; + } + + // set the file and the HTTP response status + SetFile(file, responseStatus); +} + +bool CHTTPVfsHandler::CanHandleRequest(const HTTPRequest &request) const +{ + return request.pathUrl.find("/vfs") == 0; +} |