Prefácio
Rapidshare, MegaUpload, EasyShare, Zupload, Uploading, 4Shared… Quem nunca usou nenhum destes serviços que atire a primeira pedra. Não é tão intrigante o modo como eles conseguem fazer com que baixemos apenas um arquivo por vez? É muito bom saber que você consegue poupar uma porção de banda limitando o número de downloads cabeça!
Esta solução também provê um fim para o download utilizando aceleradores! :)
Os mais puristas irão indicar o módulo mod_limitipconn do Apache, mas se você estiver em uma hospedagem compartilhada, na maioria das vezes você não poderá mexer nos módulos do Apache.
Nessa dica iremos utilizar o mod_rewrite e um scriptzinho que irá gerenciar os downloads. Este também poderá ser adaptado para funcionar da mesma forma que o script gerenciador de downloads que foi desenvolvido em um dos últimos artigos, Forçar download ao invés da exibição.
Quem irá cuidar dos acessos de cada usuário será o nosso bom e velho MySQL (claro que você pode adaptar para PostgreSQL, Oracle, MS SQL Server, etc).
Mão na massa
A primeira coisa de todas é criar a nossa querida tabela. Vamos dar à ela o nome de baixando.
CREATE TABLE `baixando` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `arquivo` VARCHAR(255) NOT NULL, `ip` CHAR(15) NOT NULL, `ultimoacesso` DATETIME NOT NULL, ) ENGINE=InnoDB
Agora precisamos do arquivo .htaccess. Caso você ainda não o conheça, você pode ler mais sobre ele neste artigo: Sobrescrevendo as configurações do php.ini com Apache e .htaccess.
Bom… Vamos supor que todos os arquivos estejam dentor da pasta arquivos. Você irá salvar o arquivo .htaccess neste diretório contendo as seguintes linhas:
RewriteEngine on RewriteRule (.*)(zip|rar|pdf|exe)$ /arquivos/baixar.php [QSA]
Esta regra irá capturar todos os arquivos que forem acessados neste diretório, terminados em (zip|rar|pdf|exe), e irá cuidar para que todos eles sejam redirecionados para o arquivo baixar.php. É neste arquivo que devemos fazer a configuração para verificar se o fulano que está acessando tem permissão para tal.
E vamos à parte que estamos “acostumados”:
<?php
// Aqui você deve fazer a conexão com o banco! :P
// Caminho do arquivo que está sendo requisitado
$caminho = mysql_real_escape_string($_SERVER['REQUEST_URI']);
// IP do indivíduo que está requisitando o arquivo
$ip = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
// Está baixando?
$baixando = false;
// Seleciona o último acesso em formato UNIX, equivalente ao mktime()
$sql = "SELECT UNIX_TIMESTAMP(ultimoacesso) AS ultimavez FROM baixando WHERE arquivo = '$caminho' AND ip = '$ip' ORDER BY ultimoacesso DESC LIMIT 1";
$rs = mysql_query($sql);
if (mysql_num_rows($rs)) {
$ultimaVez = mysql_result($rs, 0, 'ultimoacesso') + 1800;
if ($ultimaVez < time()) {
mysql_query("REPLACE baixando SET caminho = '$caminho', ip = '$ip', ultimoacesso = NOW()");
$baixando = true;
}
} else {
$sql = "REPLACE baixando SET caminho = '$caminho', ip = '$ip', ultimoacesso = NOW()";
mysql_query($sql);
$baixando = true;
}
?>
Neste exemplo é utilizado um intervalo de 1800 segundos (meia hora) antes que o usuário possa baixar este arquivo novamente. Se o valor de $baixando for true.
E então segue o código que irá gerenciar o download! :)
<?php
if ($baixar) {
$caminhoCompleto = $_SERVER['DOCUMENT_ROOT'].$path;
if ($fp = fopen($caminhoCompleto, 'r')) {
header ('Content-disposition:attachment;filename="'.basename($caminhoCompleto).'";');
header ('Content-Length: '.filesize($caminhoCompleto));
readfile($caminhoCompleto);
exit;
}
} else {
header('HTTP/1.0 503 Service Unavailable');
print '<h1>503 Service Unavailable</h1><p>Você já baixou este arquivo demais!</p>';
exit;
}
?>
Com este código, o download só será possível se já tiver passado meia hora após a última vez em que este IP efetuou o download. E daí é só correr pro abraço! :P
Conclusão
Não é difícil de montar um sistema assim. Como em todos os tutoriais aqui, você pode desenvolver novas implementações e aumentar o potencial do script. Caso você utilize estes scripts como base ou caso você encontre algum erro, adoraria receber um comentário ou um e-mail seu!
Um grande abraço e fiquem com Deus.
Bah cara… que massa isso aí, eu fazia idéia de mais ou menos como fazer, mas não imagina que seriam somente esses passos =)
GENIAL
A ideia é boa mas o seu codigo ……………..
Olá Forbidencode.
Proponha uma abordagem melhor, por favor! :)
Um abraço!
Tentei executar o script funciona tudo, porém quando vou baixar, ele me retorno esse erro:
[function.fopen]: failed to open stream: No such file or directory in C:siteaixar.php on line 35
Oq pode ser?
Valeu
Provavelmente não está encontrando o arquivo… Você pode tentar verificar se o caminho está certo no .htaccess e também nos diretórios do seu site! :)
Consegui resolver o problema, porém estou com outro hehee
Quando acesso o script diretamente pelo browser. ex:
http://www.site.com.br/baixar.php
Ele pede para baixar o fonte do php hehe.
Porém o server está funcionando, rodando php normal o script está acessando o banco de dados, bloquecando a cada meia hora, tudo funciona.
Oq pode estár acontecendo?
Valeu
Você fechou os parênteses sem ter aberto nenhum e vai dar merda ;D
$sql = "REPLACE baixando SET caminho = '$caminho', ip = '$ip', ultimoacesso = NOW()");
Isso que dá escrever artigo na corrida! :P
Obrigado pelo comentário! Já arrumei! :)
Olá, bom tuto, eu tenho um sistema gerador de link megaupload e gostaria de fazer algo do tipo. Usuario não pago pode gerar um link somente por dia. Como eu poderia fazer isto? Meu sistema é com curl. Gostaria de bloquear por usuario e não por IP, só meio leigo em PHP ainda. Você pode me dar uma luz? Obrigado
Cara nao entendi nada do que li acima sou novo nesse negocio de internet mas viciado em jogos de pc assinei um serviço de net via radio e quando tento fazer download de jogos da uma msg "Impossivel fazer odownload desse arquivo HTTP/1.0 503 Service Unavailable" o que e isso e tem como resolver esse problema?