bool CFTPDirectory::GetDirectory(const CURL& url2, CFileItemList &items) { CCurlFile reader; CURL url(url2); std::string path = url.GetFileName(); if( !path.empty() && !StringUtils::EndsWith(path, "/") ) { path += "/"; url.SetFileName(path); } if (!reader.Open(url)) return false; bool serverNotUseUTF8 = url.GetProtocolOption("utf8") == "0"; char buffer[MAX_PATH + 1024]; while( reader.ReadString(buffer, sizeof(buffer)) ) { std::string strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); CFTPParse parse; if (parse.FTPParse(strBuffer)) { if( parse.getName().length() == 0 ) continue; if( parse.getFlagtrycwd() == 0 && parse.getFlagtryretr() == 0 ) continue; /* buffer name */ std::string name; name.assign(parse.getName()); if( name == ".." || name == "." ) continue; // server returned filename could in utf8 or non-utf8 encoding // we need utf8, so convert it to utf8 anyway g_charsetConverter.unknownToUTF8(name); // convert got empty result, ignore it if (name.empty()) continue; if (serverNotUseUTF8 || name != parse.getName()) // non-utf8 name path, tag it with protocol option. // then we can talk to server with the same encoding in CurlFile according to this tag. url.SetProtocolOption("utf8", "0"); else url.RemoveProtocolOption("utf8"); CFileItemPtr pItem(new CFileItem(name)); pItem->m_bIsFolder = parse.getFlagtrycwd() != 0; std::string filePath = path + name; if (pItem->m_bIsFolder) URIUtils::AddSlashAtEnd(filePath); /* qualify the url with host and all */ url.SetFileName(filePath); pItem->SetPath(url.Get()); pItem->m_dwSize = parse.getSize(); pItem->m_dateTime=parse.getTime(); items.Add(pItem); } } return true; }
bool CFTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CCurlFile reader; CURL url(strPath); CStdString path = url.GetFileName(); if( !path.IsEmpty() && !path.Right(1).Equals("/") ) { path += "/"; url.SetFileName(path); } if (!reader.Open(url)) return false; char buffer[MAX_PATH + 1024]; while( reader.ReadString(buffer, sizeof(buffer)) ) { CStdString strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); CFTPParse parse; if (parse.FTPParse(strBuffer)) { if( parse.getName().length() == 0 ) continue; if( parse.getFlagtrycwd() == 0 && parse.getFlagtryretr() == 0 ) continue; /* buffer name */ CStdString name; name.assign(parse.getName()); if( name.Equals("..") || name.Equals(".") ) continue; /* this should be conditional if we ever add */ /* support for the utf8 extension in ftp client */ g_charsetConverter.unknownToUTF8(name); CFileItemPtr pItem(new CFileItem(name)); pItem->m_bIsFolder = (bool)(parse.getFlagtrycwd() != 0); CStdString filePath = path + name; if (pItem->m_bIsFolder) URIUtils::AddSlashAtEnd(filePath); /* qualify the url with host and all */ url.SetFileName(filePath); pItem->SetPath(url.Get()); pItem->m_dwSize = parse.getSize(); pItem->m_dateTime=parse.getTime(); items.Add(pItem); } } return true; }
CURL CDVDInputStreamFFmpeg::GetM3UBestBandwidthStream(const CURL &url, size_t bandwidth) { typedef CPlayListM3U M3U; using std::string; using std::map; // we may be passed a playlist that does not contain playlists of different // bitrates (eg: this playlist is really the HLS video). So, default the // return to the filename so it can be played char szLine[4096]; string strLine; size_t maxBandwidth = 0; CCurlFile file; // set the proxy configuration const string host = GetProxyHost(); if (!host.empty()) file.SetProxy(GetProxyType(), host, GetProxyPort(), GetProxyUser(), GetProxyPassword()); // open the file, and if it fails, return if (!file.Open(url)) { file.Close(); return url; } // and set the fallback value CURL subStreamUrl(url); // determine the base CURL basePlaylistUrl(URIUtils::GetParentPath(url.Get())); basePlaylistUrl.SetOptions(""); basePlaylistUrl.SetProtocolOptions(""); const string basePart = basePlaylistUrl.Get(); // convert bandwidth specified in kbps to bps used by the m3u8 bandwidth *= 1000; while (file.ReadString(szLine, 1024)) { // read and trim a line strLine = szLine; StringUtils::Trim(strLine); // skip the first line if (strLine == M3U::StartMarker) continue; else if (StringUtils::StartsWith(strLine, M3U::StreamMarker)) { // parse the line so we can pull out the bandwidth const map< string, string > params = M3U::ParseStreamLine(strLine); const map< string, string >::const_iterator it = params.find(M3U::BandwidthMarker); if (it != params.end()) { const size_t streamBandwidth = atoi(it->second.c_str()); if ((maxBandwidth < streamBandwidth) && (streamBandwidth <= bandwidth)) { // read the next line if (!file.ReadString(szLine, 1024)) continue; strLine = szLine; StringUtils::Trim(strLine); // this line was empty if (strLine.empty()) continue; // store the max bandwidth maxBandwidth = streamBandwidth; // if the path is absolute just use it if (CURL::IsFullPath(strLine)) subStreamUrl = CURL(strLine); else subStreamUrl = CURL(basePart + strLine); } } } } // if any protocol options were set, restore them subStreamUrl.SetProtocolOptions(url.GetProtocolOptions()); return subStreamUrl; }
bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CCurlFile http; CURL url(strPath); CStdString strName, strLink; CStdString strBasePath = url.GetFileName(); if(!http.Open(url)) { CLog::Log(LOGERROR, "%s - Unable to get http directory", __FUNCTION__); return false; } CRegExp reItem(true); // HTML is case-insensitive reItem.RegComp("<a href=\"(.*)\">(.*)</a>"); CRegExp reDateTime(true); reDateTime.RegComp("<td align=\"right\">([0-9]{2})-([A-Z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}) +</td>"); CRegExp reDateTimeNginx(true); reDateTimeNginx.RegComp("</a> +([0-9]{2})-([A-Z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}) "); CRegExp reSize(true); reSize.RegComp(">*([0-9.]+)(B|K|M|G| )</td>"); CRegExp reSizeNginx; reSizeNginx.RegComp("([0-9]+)$"); /* read response from server into string buffer */ char buffer[MAX_PATH + 1024]; while(http.ReadString(buffer, sizeof(buffer)-1)) { CStdString strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); if (reItem.RegFind(strBuffer.c_str()) >= 0) { strLink = reItem.GetReplaceString("\\1"); strName = reItem.GetReplaceString("\\2"); if(strLink[0] == '/') strLink = strLink.Mid(1); CStdString strNameTemp = strName.Trim(); CStdString strLinkTemp = strLink; URIUtils::RemoveSlashAtEnd(strLinkTemp); URIUtils::RemoveSlashAtEnd(strNameTemp); CURL::Decode(strLinkTemp); if (strNameTemp == strLinkTemp && strLinkTemp != "..") { CStdStringW wName, wLink, wConverted; g_charsetConverter.unknownToUTF8(strName); g_charsetConverter.utf8ToW(strName, wName, false); HTML::CHTMLUtil::ConvertHTMLToW(wName, wConverted); g_charsetConverter.wToUTF8(wConverted, strName); URIUtils::RemoveSlashAtEnd(strName); g_charsetConverter.unknownToUTF8(strLink); g_charsetConverter.utf8ToW(strLink, wLink, false); HTML::CHTMLUtil::ConvertHTMLToW(wLink, wConverted); g_charsetConverter.wToUTF8(wConverted, strLink); CFileItemPtr pItem(new CFileItem(strName)); pItem->SetProperty("IsHTTPDirectory", true); url.SetFileName(strBasePath + strLink); pItem->SetPath(url.Get()); if(URIUtils::HasSlashAtEnd(pItem->GetPath())) pItem->m_bIsFolder = true; CStdString day, month, year, hour, minute; if (reDateTime.RegFind(strBuffer.c_str()) >= 0) { day = reDateTime.GetReplaceString("\\1"); month = reDateTime.GetReplaceString("\\2"); year = reDateTime.GetReplaceString("\\3"); hour = reDateTime.GetReplaceString("\\4"); minute = reDateTime.GetReplaceString("\\5"); } else if (reDateTimeNginx.RegFind(strBuffer.c_str()) >= 0) { day = reDateTimeNginx.GetReplaceString("\\1"); month = reDateTimeNginx.GetReplaceString("\\2"); year = reDateTimeNginx.GetReplaceString("\\3"); hour = reDateTimeNginx.GetReplaceString("\\4"); minute = reDateTimeNginx.GetReplaceString("\\5"); } if (day.length() > 0 && month.length() > 0 && year.length() > 0) { pItem->m_dateTime = CDateTime(atoi(year.c_str()), CDateTime::MonthStringToMonthNum(month), atoi(day.c_str()), atoi(hour.c_str()), atoi(minute.c_str()), 0); } if (!pItem->m_bIsFolder) { if (reSize.RegFind(strBuffer.c_str()) >= 0) { double Size = atof(reSize.GetReplaceString("\\1")); CStdString strUnit = reSize.GetReplaceString("\\2"); if (strUnit == "K") Size = Size * 1024; else if (strUnit == "M") Size = Size * 1024 * 1024; else if (strUnit == "G") Size = Size * 1000 * 1024 * 1024; pItem->m_dwSize = (int64_t)Size; } else if (reSizeNginx.RegFind(strBuffer.c_str()) >= 0) { double Size = atof(reSizeNginx.GetReplaceString("\\1")); pItem->m_dwSize = (int64_t)Size; } else if (g_advancedSettings.m_bHTTPDirectoryStatFilesize) // As a fallback get the size by stat-ing the file (slow) { CCurlFile file; file.Open(url); pItem->m_dwSize=file.GetLength(); file.Close(); } } items.Add(pItem); } } } http.Close(); items.SetProperty("IsHTTPDirectory", true); return true; }