Limitando o número de downloads por cliente / pessoa / usuário / IP

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.

Esta entrada foi publicada em Dicas e marcada com a tag , . Adicione o link permanente aos seus favoritos.

10 pessoas já comentaram! Tá esperando o quê?

  1.  
    Xorna disse:

    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

    Utilizando Mozilla Firefox Mozilla Firefox 2.0.0.12 no Windows Windows XP
  2.  
    Forbidencode disse:

    A ideia é boa mas o seu codigo ……………..

    Utilizando Mozilla Firefox Mozilla Firefox 3.0 no Linux Linux
  3.  
    Rafael Jaques disse:

    Olá Forbidencode.

    Proponha uma abordagem melhor, por favor! :)

    Um abraço!

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.1 no Windows Windows 2000
  4.  
    Sou disse:

    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

    Utilizando Mozilla Firefox Mozilla Firefox 2.0.0.16 no Windows Windows XP
  5.  
    Rafael Jaques disse:

    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! :)

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.1 no Windows Windows Vista
  6.  
    Sou disse:

    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

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.1 no Linux Linux
  7.  
    Cosme Fa disse:

    Você fechou os parênteses sem ter aberto nenhum e vai dar merda ;D

    $sql = "REPLACE baixando SET caminho = '$caminho', ip = '$ip', ultimoacesso = NOW()");

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.4 no Mac OS X Mac OS X 10
  8.  
    Rafael Jaques disse:

    Isso que dá escrever artigo na corrida! :P

    Obrigado pelo comentário! Já arrumei! :)

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.4 no Windows Windows 2000
  9.  
    Cristiano disse:

    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

    Utilizando Mozilla Firefox Mozilla Firefox 3.5.8 no Windows Windows 7
  10.  
    Sandro disse:

    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?

    Utilizando Internet Explorer Internet Explorer 8.0 no Windows Windows 7

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">