-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtorrent.php
139 lines (107 loc) · 4.27 KB
/
torrent.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
/* Torrent Scraper Base Class
v1.0
&
Torrent UDP Scraper
v1.2
2010 by Johannes Zinnau
Licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License
http://creativecommons.org/licenses/by-sa/3.0/
It would be very nice if you send me your changes on this class, so that i can include them if they are improve it.
Thanks!
*/
#tscraper
class ScraperException extends Exception {
private $connectionerror;
public function __construct($message,$code=0,$connectionerror=false){
$this->connectionerror = $connectionerror;
parent::__construct($message, $code);
}
public function isConnectionError(){
return($this->connectionerror);
}
}
abstract class tscraper {
protected $timeout;
public function __construct($timeout=2){
$this->timeout = $timeout;
}
}
#tscraper End
#udptscraper
class udptscraper extends tscraper{
/* $url: Tracker url like: udp://tracker.tld:port or udp://tracker.tld:port/announce
$infohash: Infohash string or array (max 74 items). 40 char long infohash.
*/
public function scrape($url,$infohash){
if(!is_array($infohash)){ $infohash = array($infohash); }
foreach($infohash as $hash){
if(!preg_match('#^[a-f0-9]{40}$#i',$hash)){ throw new ScraperException('Invalid infohash: ' . $hash . '.'); }
}
if(count($infohash) > 74){ throw new ScraperException('Too many infohashes provided.'); }
if(!preg_match('%udp://([^:/]*)(?::([0-9]*))?(?:/)?%si', $url, $m)){ throw new ScraperException('Invalid tracker url.'); }
$tracker = 'udp://' . $m[1];
$port = isset($m[2]) ? $m[2] : 80;
$transaction_id = mt_rand(0,65535);
$fp = fsockopen($tracker, $port, $errno, $errstr);
if(!$fp){ throw new ScraperException('Could not open UDP connection: ' . $errno . ' - ' . $errstr,0,true); }
stream_set_timeout($fp, $this->timeout);
$current_connid = "\x00\x00\x04\x17\x27\x10\x19\x80";
//Connection request
$packet = $current_connid . pack("N", 0) . pack("N", $transaction_id);
fwrite($fp,$packet);
//Connection response
$ret = fread($fp, 16);
if(strlen($ret) < 1){ throw new ScraperException('No connection response.',0,true); }
if(strlen($ret) < 16){ throw new ScraperException('Too short connection response.'); }
$retd = unpack("Naction/Ntransid",$ret);
if($retd['action'] != 0 || $retd['transid'] != $transaction_id){
throw new ScraperException('Invalid connection response.');
}
$current_connid = substr($ret,8,8);
//Scrape request
$hashes = '';
foreach($infohash as $hash){ $hashes .= pack('H*', $hash); }
$packet = $current_connid . pack("N", 2) . pack("N", $transaction_id) . $hashes;
fwrite($fp,$packet);
//Scrape response
$readlength = 8 + (12 * count($infohash));
$ret = fread($fp, $readlength);
if(strlen($ret) < 1){ throw new ScraperException('No scrape response.',0,true); }
if(strlen($ret) < 8){ throw new ScraperException('Too short scrape response.'); }
$retd = unpack("Naction/Ntransid",$ret);
// Todo check for error string if response = 3
if($retd['action'] != 2 || $retd['transid'] != $transaction_id){
throw new ScraperException('Invalid scrape response.');
}
if(strlen($ret) < $readlength){ throw new ScraperException('Too short scrape response.'); }
$torrents = array();
$index = 8;
foreach($infohash as $hash){
$retd = unpack("Nseeders/Ncompleted/Nleechers",substr($ret,$index,12));
$retd['infohash'] = $hash;
$torrents[$hash] = $retd;
$index = $index + 12;
}
return($torrents);
}
}
#udptscraper End
#Test code By Sharon
try{
$timeout = 2;
$scraper = new udptscraper($timeout);
$ret = $scraper->scrape('udp://tracker.coppersurfer.tk:6969/announce',array('A2E7EA58534C1769D50EAD2DA2778836E407084C'));
print_r($ret); //for debug
foreach ($ret as $key => $value) {
echo 'INFO HASH :' .$value['infohash'].'<br />';
echo 'SEEDS :' .$value['seeders'].'<br />';
echo 'LEECHES :' .$value['leechers'].'<br />';
echo 'COMPLETED :' .$value['completed'].'<br />';
}
}catch(ScraperException $e){
echo('Error: ' . $e->getMessage() . "<br />\n");
echo('Connection error: ' . ($e->isConnectionError() ? 'yes' : 'no') . "<br />\n");
}
?>