Ejemplo n.º 1
0
 /**
  * Bootstrap any application services.
  *
  * @return void
  */
 public function boot()
 {
     Validator::extend('torrentFile', function ($attribute, $value, $parameters, $validator) {
         $dictionary = BencodeHelper::decodeFile($value);
         list($announce, $info) = BencodeHelper::checkDictionary($dictionary, "announce(string):info", "global dictionary");
         list($dname, $plen, $pieces) = BencodeHelper::checkDictionary($info, "name(string):piece length(integer):pieces(string)", "Info dictionary");
         $total_length = BencodeHelper::getDictionaryValue($info, "length", "integer");
         $dicttionary_is_valid = BencodeHelper::checkDictionary($dictionary, "announce(string):info", "global dictionary") == BencodeHelper::_OK;
         return $dicttionary_is_valid && (int) $total_length > 0 && (int) $plen > 0 && $pieces !== "" && $announce !== "";
     });
 }
Ejemplo n.º 2
0
 /**
  * The announce action
  * @return $this
  * @internal param Request $request
  */
 public function announce(Request $request)
 {
     Log::info($request->fullUrl());
     // GET params sent by the client
     $passkey = Input::get('passkey');
     $peer_id = base64_encode(Input::get('peer_id'));
     $info_hash = Input::get('info_hash');
     $downloaded = Input::get('downloaded') ? intval(Input::get('downloaded')) : 0;
     $uploaded = Input::get('uploaded') ? intval(Input::get('uploaded')) : 0;
     $left = Input::get('left') ? intval(Input::get('left')) : 0;
     $compact = Input::get('compact') ? intval(Input::get('compact')) : 0;
     $no_peer_id = Input::get('no_peer_id') ? intval(Input::get('no_peer_id')) : 0;
     $event = strip_tags(Input::get('event'));
     // Client IP address
     $ipAddress = '';
     // Check for X-Forwarded-For headers and use those if found
     if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && '' !== trim($_SERVER['HTTP_X_FORWARDED_FOR'])) {
         $ipAddress = trim($_SERVER['HTTP_X_FORWARDED_FOR']);
     } else {
         if (isset($_SERVER['REMOTE_ADDR']) && '' !== trim($_SERVER['REMOTE_ADDR'])) {
             $ipAddress = trim($_SERVER['REMOTE_ADDR']);
         }
     }
     // Check client ports
     $port = $_SERVER['REMOTE_PORT'];
     if (!$port || !ctype_digit($port) || intval($port) < 1 || intval($port) > 65535) {
         return BencodeHelper::bencodedResponseRaw("Invalid client port", 103);
     }
     if ($port == 999 && substr($peer_id, 0, 10) == '-TO0001-XX') {
         return BencodeHelper::bencodedResponseRaw("d8:completei0e10:incompletei0e8:intervali600e12:min intervali60e5:peersld2:ip12:72.14.194.184:port3:999ed2:ip11:72.14.194.14:port3:999ed2:ip12:72.14.194.654:port3:999eee", 103);
     }
     // Check passkey param
     if (!$passkey) {
         return BencodeHelper::bencodedResponseRaw("Missing passkey", 900);
     }
     // Find passkey-related user
     $user = User::has('passkeys', '=', $passkey)->get();
     if ($user == null) {
         return BencodeHelper::bencodedResponseRaw("Invalid passkey", 900);
     }
     // Check info_hash param
     if (!$info_hash) {
         return BencodeHelper::bencodedResponseRaw("Missing info hash", 101);
     }
     $info_hash = strtoupper(bin2hex($info_hash));
     // Check torrent hash
     $torrent = Torrent::getByInfoHash($info_hash);
     if (!$torrent || $torrent == null) {
         return BencodeHelper::bencodedResponseRaw("Torrent not registered with this tracker.", 900);
     }
     // Check if peer already exists
     $peer = Peer::getByIPAndPasskey($ipAddress, $passkey);
     // Create a new one if it does not
     if ($peer == null) {
         $attributes = ['hash' => $peer_id, 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'ip_address' => $ipAddress, 'passkey' => $passkey, 'port' => $port];
         $peer = Peer::create($attributes);
     }
     // Check info_hash (must be 20 chars long)
     if (!$info_hash) {
         return BencodeHelper::bencodedResponseRaw("Invalid info hash.", 150);
     }
     // Check if peer is already assigned to torrent
     $peer_torrent = PeerTorrent::getByPeerAndTorrent($peer, $torrent);
     // Assign it, if not
     if ($peer_torrent == null) {
         $attributes = ['peer_id' => $peer->id, 'torrent_id' => $torrent->id, 'uploaded' => $uploaded, 'downloaded' => $downloaded, 'left' => $left];
         // Event handling
         if ($event === BitTorrent::EVENT_STARTED || $event == BitTorrent::EVENT_COMPLETED) {
             $attributes['stopped'] = false;
         } else {
             $attributes['stopped'] = true;
         }
         PeerTorrent::create($attributes);
     } else {
         // Or update the existing one
         $peer_torrent->uploaded = $uploaded;
         $peer_torrent->downloaded = $downloaded;
         $peer_torrent->left = $left;
         $peer_torrent->save();
     }
     // Perform announce on the torrent
     $torrent->announce();
     // Build response
     $resp = BencodeHelper::buildAnnounceResponse($torrent, $peer_torrent, $compact, $no_peer_id);
     return BencodeHelper::bencodedResponseRaw($resp);
 }
Ejemplo n.º 3
0
 public function download($id)
 {
     $config = config('settings');
     $torrent = Torrent::getByStringID($id);
     $dictionary = $torrent->getDictionary();
     $current_user = Auth::user();
     // Get global announce urls
     $announce_url = $config['global_announce_urls'];
     $announce_url_with_passkey = array();
     foreach ($announce_url as $url) {
         $announce_url_with_passkey[] = sprintf("%s?passkey=%s", $url, $current_user->passkeys->passkey);
     }
     Log::info($dictionary);
     // Set them to the dictionary
     $dictionary["value"]["announce"] = array("type" => "string", "value" => $announce_url_with_passkey[0]);
     $encoded = BencodeHelper::bencode($dictionary);
     Log::info($dictionary);
     $temp_file_path = $config['tmp_dir'] . $current_user->passkeys->passkey . "_" . $torrent->hash . ".torrent";
     $user_file_name = $torrent->filename;
     $tmp_file = File::put($temp_file_path, $encoded);
     return Response::download($temp_file_path, $user_file_name, ['content-type' => 'application/x-bittorrent']);
 }
Ejemplo n.º 4
0
 /**
  * Returns the decoded dictionary of the torrent file
  *
  * @return array|void
  */
 public function getDictionary()
 {
     return BencodeHelper::decodeFile($this->getFilePath());
 }