Example #1
0
 public function actionQuery($query, $page = 1, $pageSize = 100)
 {
     Yii::$app->response->format = Response::FORMAT_JSON;
     $provider = new ActiveDataProvider(['query' => Torrent::find()->match($query)]);
     $pagination = $provider->pagination;
     $pagination->page = $page;
     $pagination->pageSize = $pageSize;
     $models = $provider->getModels();
     return ['data' => $models, 'pagination' => ['page' => $pagination->page, 'pageSize' => $pagination->pageSize, 'pageCount' => $pagination->pageCount, 'totalCount' => $pagination->totalCount]];
 }
Example #2
0
 /**
  * Builds tracker announce response in bencoded format
  *
  * @param Torrent $torrent
  * @param PeerTorrent $peerTorrent
  * @param $compact
  * @param int $no_peer_id
  * @return string
  */
 public static function buildAnnounceResponse(Torrent $torrent, PeerTorrent $peerTorrent, $compact, $no_peer_id = 0)
 {
     // Compact mode
     if ($compact != 1) {
         $resp = "d" . self::bencodeString("interval") . "i" . self::__INTERVAL . "e" . self::bencodeString("peers") . "l";
     } else {
         $resp = "d" . self::bencodeString("interval") . "i" . self::__INTERVAL . "e" . self::bencodeString("min interval") . "i" . 300 . "e5:" . "peers";
     }
     $peer = array();
     $peer_num = 0;
     foreach ($torrent->getPeersArray() as $row) {
         if ($compact != 1) {
             if ($row["peer_id"] === $peerTorrent->peerInstance()->hash) {
                 continue;
             }
             $resp .= "d" . self::bencodeString("ip") . self::bencodeString($row['ip']);
             if ($no_peer_id == 0) {
                 $resp .= self::bencodeString("peer id") . self::bencodeString($row["peer_id"]);
             }
             $resp .= self::bencodeString("port") . "i" . $row["port"] . "e" . "e";
         } else {
             $peer_ip = explode('.', $row["ip"]);
             $peer_ip = pack("C*", $peer_ip[0], $peer_ip[1], $peer_ip[2], $peer_ip[3]);
             $peer_port = pack("n*", (int) $row["port"]);
             $time = intval(time() % 7680 / 60);
             if ($peerTorrent->left == 0) {
                 $time += 128;
             }
             $time = pack("C", $time);
             $peer[] = $time . $peer_ip . $peer_port;
             $peer_num++;
         }
     }
     if ($compact != 1) {
         $resp .= "ee";
     } else {
         $o = "";
         for ($i = 0; $i < $peer_num; $i++) {
             $o .= substr($peer[$i], 1, 6);
         }
         $resp .= strlen($o) . ':' . $o . 'e';
     }
     return $resp;
 }
 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']);
 }
 /**
  * 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);
 }