mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-10-23 02:11:43 +00:00
update torrent info and save .torent file from BEP9 metadata
This commit is contained in:
1 parent
d608d3f5b2
commit
d203db13a7
4 files changed
+57
-16
No files matched your search
@@ -373,7 +373,6 @@ namespace torrents
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
size_t Torrent::ParseInfo (std::string_view buf)
|
||||
{
|
||||
size_t len = ParseDictionary (buf, [this](std::string_view key, std::string_view buf)->size_t
|
||||
@@ -423,6 +422,12 @@ namespace torrents
|
||||
return len;
|
||||
}
|
||||
|
||||
std::string Torrent::CreateTorrentFileContent () const
|
||||
{
|
||||
if (m_Info.empty ()) return "";
|
||||
return CreateDictionary ( {{ "info", std::string_view ((const char *)m_Info.data (), m_Info.size ()) }} );
|
||||
}
|
||||
|
||||
bool Torrent::IsSafeName (std::string_view name)
|
||||
{
|
||||
if (name.empty () || name == "." || name == "..") return false;
|
||||
@@ -1279,7 +1284,7 @@ namespace torrents
|
||||
|
||||
void PeerConnection::HandleBitfieldMsg (const uint8_t * buf, size_t len)
|
||||
{
|
||||
if (!m_Torrent) return;
|
||||
if (!m_Torrent || !m_Torrent->GetLength ()) return; // we are magnet and don't have torrent info yet
|
||||
m_IsInterested = false;
|
||||
size_t numPieces = m_Torrent->GetNumPieces ();
|
||||
m_RemoteBitfield.resize (numPieces);
|
||||
@@ -1640,6 +1645,9 @@ namespace torrents
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
if (!m_Torrent->GetLength () && m_RemoteMetadataSize) // torrent is magnet and peer supports BEP9
|
||||
// request first piece of info
|
||||
SendExtendedMsg (EXTENSION_MSGID_UT_METADATA, CreateDictionary ({{ "msg_type", CreateInteger (0) }, { "piece", CreateInteger (0) }}));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1748,11 +1756,10 @@ namespace torrents
|
||||
uint8_t digest[SHA_DIGEST_LENGTH];
|
||||
SHA1 (m_RemoteMetadata.data (), m_RemoteMetadata.size (), digest);
|
||||
if (memcmp (m_Torrent->GetInfoHash ().data (), digest, SHA_DIGEST_LENGTH))
|
||||
GetTorrentsTunnel ()->UpdateTorrentInfo (m_Torrent, std::string_view ((const char *)m_RemoteMetadata.data (), m_RemoteMetadata.size ()));
|
||||
else
|
||||
LogPrint (eLogError, "Torrents: ut_metadata info doesn't match infoHash");
|
||||
// TODO: update torrent
|
||||
// cleanup
|
||||
std::vector<uint8_t> tmp;
|
||||
m_RemoteMetadata.swap (tmp);
|
||||
Close (); // we need to reconnect to receive bitfield
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -162,6 +162,8 @@ namespace torrents
|
||||
|
||||
Torrent (std::string_view buf);
|
||||
Torrent (const InfoHash& infoHash);
|
||||
size_t ParseInfo (std::string_view buf);
|
||||
std::string CreateTorrentFileContent () const;
|
||||
void ParseTrackerResponse (size_t trackerID, std::string_view buf);
|
||||
void HandleDatagramTrackerResponse (size_t trackerID, uint32_t interval,
|
||||
const uint8_t * hashes, size_t hashesLen, int numSeeders, int numLeechers);
|
||||
@@ -230,7 +232,6 @@ namespace torrents
|
||||
|
||||
Torrent ();
|
||||
size_t ParsePieces (std::string_view buf);
|
||||
size_t ParseInfo (std::string_view buf);
|
||||
size_t ParsePeers (size_t trackerID, std::string_view buf);
|
||||
size_t ParseFiles (std::string_view buf);
|
||||
static bool IsSafeName (std::string_view name); // a name from a torrent file before it becomes a path
|
||||
|
||||
@@ -134,6 +134,20 @@ namespace torrents
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentsTunnel::SaveTorrentFile (std::shared_ptr<Torrent> torrent)
|
||||
{
|
||||
if (!torrent) return;
|
||||
auto torrentFilePath = torrent->GetFullPath (); torrentFilePath += ".torrent";
|
||||
std::ofstream f(torrentFilePath, std::ofstream::binary);
|
||||
if (f)
|
||||
{
|
||||
auto content = torrent->CreateTorrentFileContent ();
|
||||
f.write (content.data (), content.size ());
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "TorrentsTunnel: Can't open ", torrentFilePath);
|
||||
}
|
||||
|
||||
void TorrentsTunnel::InitTorrentFiles (std::shared_ptr<Torrent> torrent)
|
||||
{
|
||||
if (!torrent) return;
|
||||
@@ -315,15 +329,20 @@ namespace torrents
|
||||
if (m_Torrents.find (torrent->GetInfoHash ()) == m_Torrents.end ())
|
||||
{
|
||||
torrent->SetFullPath (m_TorrentsDir/std::filesystem::path (torrent->GetName ()));
|
||||
{
|
||||
auto torrentFilePath = torrent->GetFullPath (); torrentFilePath += ".torrent";
|
||||
std::ofstream f(torrentFilePath, std::ofstream::binary);
|
||||
if (f)
|
||||
f.write (torrentFileContent.data (), torrentFileContent.size ());
|
||||
else
|
||||
return { torrent, 0 };
|
||||
}
|
||||
InitTorrentFiles (torrent);
|
||||
std::string content (torrentFileContent);
|
||||
boost::asio::post (GetDiskIOService (), [this, torrent, content]()
|
||||
{
|
||||
auto torrentFilePath = torrent->GetFullPath (); torrentFilePath += ".torrent";
|
||||
{
|
||||
// TODO: replace by SaveTorrentFile
|
||||
std::ofstream f(torrentFilePath, std::ofstream::binary);
|
||||
if (f)
|
||||
f.write (content.data (), content.size ());
|
||||
else
|
||||
LogPrint (eLogError, "TorrentsTunnel: Can't open ", torrentFilePath);
|
||||
}
|
||||
InitTorrentFiles (torrent);
|
||||
});
|
||||
return { torrent, InsertTorrent (torrent) };
|
||||
}
|
||||
return { torrent, 0 };
|
||||
@@ -502,6 +521,18 @@ namespace torrents
|
||||
return true;
|
||||
}
|
||||
|
||||
void TorrentsTunnel::UpdateTorrentInfo (std::shared_ptr<Torrent> torrent, std::string_view info)
|
||||
{
|
||||
if (!torrent) return;
|
||||
torrent->ParseInfo (info);
|
||||
torrent->SetFullPath (m_TorrentsDir/std::filesystem::path (torrent->GetName ()));
|
||||
boost::asio::post (GetDiskIOService (), [this, torrent]()
|
||||
{
|
||||
SaveTorrentFile (torrent);
|
||||
InitTorrentFiles (torrent);
|
||||
});
|
||||
}
|
||||
|
||||
void TorrentsTunnel::Accept ()
|
||||
{
|
||||
auto localDestination = GetLocalDestination ();
|
||||
|
||||
@@ -100,6 +100,7 @@ namespace torrents
|
||||
std::vector<int> GetTorrentIDs () const;
|
||||
std::pair<std::shared_ptr<Torrent>, int> AddTorrent (std::string_view torrentFileContent); // retrun (torrent, id)
|
||||
std::pair<std::shared_ptr<Torrent>, int> AddMagnet (std::string_view magnet); // return (torrent, id)
|
||||
void UpdateTorrentInfo (std::shared_ptr<Torrent> torrent, std::string_view info); // magnet
|
||||
bool RemoveTorrent (int id, bool deleteFiles);
|
||||
bool StopTorrent (int id);
|
||||
bool StartTorrent (int id);
|
||||
@@ -112,6 +113,7 @@ namespace torrents
|
||||
|
||||
void Accept ();
|
||||
void ReadTorrentFile (const std::filesystem::path& torrentFilePath);
|
||||
void SaveTorrentFile (std::shared_ptr<Torrent> torrent);
|
||||
void InitTorrentFiles (std::shared_ptr<Torrent> torrent);
|
||||
int InsertTorrent (std::shared_ptr<Torrent> torrent); // returns id > 0 if success and 0 if failed
|
||||
void RemoveTorrent (std::shared_ptr<Torrent> torrent, bool deleteFiles);
|
||||
|
||||
Reference in new issue
Block a user