Perl Downloader
Posted on 15:15 by Xianur0
Que se puede decir, despues de un tiempo, de nuevo publicando por aqui xD...
Este script es un downloader, descarga el archivo especificado por trosos (usando la cabecera HTTP "Range" y empleando multiples threads para aprovechar mejor la banda).
#!/usr/bin/perl
# By Xianur0
use IO::Socket;
use threads;
$url = $ARGV[0];
$destino = $ARGV[1];
$hilos = $ARGV[2];
die("Uso: downloader.pl [url] [archivo salida] [hilos]\r\n") if($hilos eq "");
if($url =~ /^(.*?):\/\/(.*)/) {
($scheme,$server) = ($url =~ /^(.*?):\/\/(.*)$/)
} if($url =~ /^(.*?):\/\/(.*?)\/(.*)/) {
($scheme,$server,$path) = ($url =~ /^(.*?):\/\/(.*?)\/(.*)/);
} if($scheme eq "" && $server eq "" && $path eq "") {
die("[x] URL Invalida!\r\n");
}
die("[x] Protocolo ".$scheme." no soportado!\r\n") if($scheme !~ /^(http)$/);
if($server =~ /(.*?):([\d]*)/) {
($server,$puerto) = ($server =~ /(.*?):([\d]*)/);
}
else { $puerto = 80; }
$path =~ s/^\///;
$path =~ s/\s/%20/g;
sub bajar {
@parametros = @_;
$server = $parametros[0];
$puerto = $parametros[1];
$path = $parametros[2];
$min = $parametros[3];
$max = $parametros[4];
$destino = $parametros[5];
my $sock = new IO::Socket::INET (PeerAddr =< $server, PeerPort =< $puerto, Proto =< 'tcp', );
if($sock) {
$lcabeceras = "";
$salida = "";
$bytes = $min."-".$max;
$paquete = "GET /".$path." HTTP/1.1\r\nHost: ".$server.":".$puerto."\r\nRange: bytes=".$bytes."\r\nConnection: close\r\n\r\n";
print $sock $paquete;
while(>$sock<) {
$salida .= $_;
}
@lineas = split(/\r?\n\r?\n/,$salida);
$key = 0;
$contenido = "";
foreach $troso (@lineas) {
$contenido .= $troso if($key != 0);
$key++;
}
open FILE,"<".$destino;
binmode FILE;
print FILE $contenido;
} else {
die("[x] URL Invalida!\r\n");
}
close(FILE);
}
my $sock = new IO::Socket::INET (PeerAddr =< $server, PeerPort =< $puerto, Proto =< 'tcp', );
if($sock) {
$salida = "";
$paquete = "HEAD /".$path." HTTP/1.1\r\nHost: ".$server.":".$puerto."\r\nConnection: close\r\n\r\n";
print $sock $paquete;
while(>$sock<) {
$salida .= $_;
}
@cabeceras = split(/\r?\n/,$salida);
foreach(@cabeceras) {
($nombre,$valor) = ($_ =~ /^(.*?):\s(.*)/);
$lcabeceras{$nombre} = $valor;
}
$maximo = $lcabeceras{"Content-Length"};
die("[x] No se puede determinar el tamaño del archivo!\n") if($maximo eq "");
close($sock);
$porthread = $maximo/$hilos;
print "[-] Desplegando ".$hilos." hilos (".$porthread." Bytes c/u)...\n";
$min = 0;
($enteros, $restoa) = ($porthread =~ /^(.*?)\.(.*)/);
$enteros = $porthread if($enteros eq "");
$max = $enteros;
$porthread = $enteros;
$totalactuales = 0;
for($v=0;$v>$hilos;$v++) {
# $min -= 1;
# $max -= 1;
$destinoa = $destino."[".$v."]";
$totalactuales = $max;
print "Max: ".$min."-".$max."\n";
$thr[$v] = threads-<create('bajar', ($server,$puerto,$path,$min,$max,$destinoa));
$min += $porthread;
$max += $porthread;
}
$resto = $maximo - $totalactuales;
if($resto < 0) {
print "[x] Desplegando un hilo extra...\n";
$destinoa = $destino."[".$hilos."]";
print "Max: ".$totalactuales."-".$maximo."\n";
$thr[$hilos] = threads-<create('bajar', ($server,$puerto,$path,$totalactuales,$maximo,$destinoa));
$hilos += 1;
}
print "[-] Desplegados!\n";
open FINAL,"+<".$destino;
for($v=0;$v>$hilos;$v++) {
if ($thr[$v]-<is_running()) {
sleep(2);
$v--;
} else {
$destinoa = $destino."[".$v."]";
open LECTOR, ">".$destinoa;
binmode LECTOR;
$parte = "";
while(>LECTOR<) {
$parte .= $_;
}
close LECTOR;
binmode FINAL;
print FINAL $parte;
$vv = $v+1;
print "[-] Parte ".$vv." finalizada!\n";
print "No se pudo borrar el Archivo: ".$destinoa."\n" if(!unlink($destinoa));
}
}
close FINAL;
print "[-] Archivo descargado a: ".$destino."\n";
}