Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Torrent File Laravel Package

arokettu/torrent-file

A PHP library for reading, creating, and editing BitTorrent .torrent files. It handles bencoding, v1 and v2 (and hybrid) torrents, and metadata, making it easy to generate or inspect torrents in your PHP applications.

Deep Wiki
Context7

Getting Started

arokettu/torrent-file is a focused bencode/metainfo library, not a Laravel package. There is no service provider, config file, migration, or facade. You install it with Composer and use its classes directly:

composer require arokettu/torrent-file

Start with the README and the Arokettu\Torrent\TorrentFile factory API. The two entry points you will use daily are:

use Arokettu\Torrent\TorrentFile;

// Parse an existing .torrent
$torrent = TorrentFile::load($path);
$name = $torrent->getName();
$announce = $torrent->getAnnounce();

// Build a new v1 torrent
$torrent = TorrentFile::v1()
    ->setName('release.zip')
    ->setPieceLength(1024 * 1024)
    ->setAnnounce('https://tracker.example/announce')
    ->addFile(storage_path('app/releases/release.zip'), 'release.zip');

$bytes = $torrent->toString();

The first practical use case is either:

  1. Accepting a torrent upload and extracting display metadata, trackers, file list, and info hash; or
  2. Generating a torrent for a file or directory already stored by Laravel.

For a Laravel app, bind a small wrapper service in AppServiceProvider rather than injecting TorrentFile everywhere. Treat torrent parsing/creation as an application service with DTOs, not as model logic.

Implementation Patterns

Parse uploaded torrents behind a FormRequest and service. Do not trust the file extension or MIME type. Validate size limits, then parse and catch library exceptions:

final class TorrentInspector
{
    public function inspect(UploadedFile $file): TorrentMetadata
    {
        $torrent = TorrentFile::load($file->getRealPath());

        return new TorrentMetadata(
            name: $torrent->getName(),
            announce: $torrent->getAnnounce(),
            files: $torrent->getFiles(),
            infoHash: $torrent->getInfoHash(),
        );
    }
}

Persist a normalized JSON representation if you need to query torrents later. Store the original .torrent bytes separately on a disk; do not rely on being able to reconstruct them byte-for-byte.

Generate torrents in a queued job. Hashing pieces is CPU- and I/O-heavy. A release-generation job should discover files, sort them deterministically, build the torrent, write it atomically, and only then update the database:

Storage::disk('torrents')->put(
    "{$release->id}.torrent",
    $torrent->toString()
);

For local disks use Storage::disk('local')->path($relativePath). For S3 or other remote disks, copy files to a temporary local file first because piece hashing needs stable random access.

Choose v1, v2, or hybrid deliberately. v1 has the broadest client support; v2 gives SHA-256 info hashes and more efficient verification; hybrid produces both hashes and is the safest compatibility choice when you can afford the extra metadata. Keep the strategy in configuration, not scattered through controllers.

Editing metadata is usually safe; editing content is not. Changing announce, comment, created by, web seeds, or tracker tiers does not normally change the info hash. Adding, removing, renaming, or reordering files changes it and invalidates existing magnets and peer references. If your app edits torrents, record the old and new info hashes and make the distinction explicit.

Build magnet links from the library’s hash accessors. For v1:

$magnet = sprintf(
    'magnet:?xt=urn:btih:%s&dn=%s',
    $infoHash,
    rawurlencode($torrent->getName())
);

Append &tr= parameters with rawurlencode() per tracker. For hybrid torrents, expose both v1 and v2 hashes and let the UI display the appropriate one.

Use a service wrapper with narrow methods. A practical interface looks like:

interface TorrentService
{
    public function inspect(string $path): TorrentMetadata;
    public function createFromFiles(array $files, TorrentOptions $options): string;
    public function updateTrackers(string $path, array $trackers): void;
}

This keeps Laravel code testable and makes a future package swap less painful.

Test with real fixture torrents. Keep small v1, v2, and hybrid .torrent fixtures in tests/Fixtures. Assert parsed names, file lists, tracker tiers, and hash values. Use Storage::fake() for creation tests, but note that piece hashing still needs real temporary files.

Gotchas and Tips

  • The info hash must come from the original bencoded info dictionary bytes. If you decode and re-encode a non-canonical torrent, key ordering or integer formatting can change and produce a different hash. Use the library’s info-hash accessor rather than hashing a rebuilt string yourself.
  • This is not a tracker client, peer protocol implementation, or seeder. It reads and writes torrent metadata only. Announcing, DHT, PEX, and downloading require separate components.
  • Piece length matters. Too-small pieces create enormous piece tables and slow hashing; too-large pieces reduce verification granularity. Common values are 256 KiB to 4 MiB. BitTorrent v2 has stricter piece-length rules, including power-of-two constraints, so validate before building.
  • Large torrents can exhaust memory. Parsing a torrent with huge v2 piece layers or building a multi-terabyte torrent may hold significant data in memory. Run generation in a queue with an appropriate memory_limit and timeout.
  • Do not assume the uploaded file is small. Apply Laravel upload limits and parse limits before calling into the library.
  • Remote filesystems are not random-access. Hashing a file on S3 directly is not practical with this package. Download to a temp path, hash, then delete.
  • Changing file order changes the info hash. Sort files explicitly and consistently. Do not depend on filesystem iteration order.
  • Set the private flag for private trackers. A private torrent should disable DHT/PEX via the metainfo flag; otherwise your release may leak beyond the tracker.
  • Handle Unicode metadata carefully. Prefer the library’s UTF-8-aware setters and avoid manually writing name.utf-8 or path.utf-8 unless the API exposes them.
  • Sanitize names before display or filesystem use. Torrent file paths are untrusted input and can contain ../, absolute-looking paths, or unusual characters. The library parses metadata; it does not make those names safe for your application.
  • Catch parse exceptions and return a validation error. Malformed bencode, missing required keys, unsupported torrent versions, and truncated files should not become 500 responses.
  • Write torrent files atomically. Generate to a temporary path and rename into place so a failed job does not leave a partial .torrent that clients may fetch.
  • Tracker URLs are not automatically normalized. Validate schemes, deduplicate tiers, and decide whether to preserve the original announce alongside announce-list.
  • Creation timestamps are Unix timestamps. Set them explicitly for reproducible builds; otherwise regenerated torrents differ at the top level even when the content is identical.
  • Pin the package version in composer.json. The package is actively maintained, but torrent metainfo details are compatibility-sensitive. Upgrade deliberately and rerun fixture tests.
  • There are few extension points. For nonstandard top-level keys, you may need to compose with the underlying bencode package or post-process the decoded structure. Keep such work isolated in one adapter.
  • Use the library as a dependency, not a domain model. Wrap it, validate around it, queue it, and keep its objects out of Eloquent models and controllers.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource