Campainha da Fita Azul pela Livre Expressão Notas de rodapé para "CGI Realmente Fácil"

Voltar à Página Principal Ir para Outros Tutoriais

  1. Programas-exemplo em CGI
  2. Script CGI para um Mailer
  3. Segurança com Scripts CGI
  4. Colocando seu Script no Servidor
  5. Enviando um Arquivo Existente como Resposta
  6. Outras Variáveis de Ambiente CGI Úteis
  7. Retornando uma Imagem ou Outra Resposta Não-HTML a partir de um Script CGI
  8. Qual é a diferença entre GET e POST?
  9. Adquirindo Maior Controle com Scripts para Header Não-desmembrado


Programas-exemplo em CGI

Atendendo a pedidos, aqui vão alguns programas CGI "alô, mundo" para você começar. A versão simples demonstra apenas a saída CGI, e a versão maior (tal como está) ecoará de volta quaisquer campos de entrada que você passar para ele. Versões Perl e C são fornecidas, com código fonte.

Voltar ao topo da página


Script CGI para um Mailer

Um dos usos mais comuns para um script CGI é enviar dados de um form para um endereço de e-mail. Aqui está script simples que faz exatamente isso, escrito em Perl, chamado mailer.pl.

Faça estas alterações no script antes de colocá-lo no lugar:

Enviando Dados de Form por Mail Sem Usar CGI

Existe um jeito "pobre" de enviar dados de um form usando apenas HTML: na tag <form>, indique em action "mailto:" e a URL, e no atributo enctype, "text/plain". A maioria dos browsers trata isso corretamente, ou seja, envia os dados do form numa mensagem de e-mail. Por exemplo,

<form action="mailto:me@myhost.com" enctype="text/plain">

Há desvantagens: você não pode controlar o formato do texto enviado, e não pode enviar uma resposta de volta para o usuário. Além disso, nem todos os browsers suportam esse estilo da tag <form>.

Voltar ao topo da página


Segurança com Scripts CGI

Pense no seguinte -- um script CGI é um programa que qualquer pessoa no mundo pode executar no seu computador. Portanto, fique atento para falhas na segurança quando escrever seu script.

Principalmente, não confie no input do usuário. Particularmente, não alimente dados fornecidos pelo usuário a um comando shell sem antes verificar esses dados cuidadosamente, ou um hacker poderá entrar com um caminhão virtual através desse buraco na segurança.

Digamos que você tem um programa CGI que deixa o usuário executar "finger" em seu host. Um script Perl como esse pode ter uma linha tal como

system "finger $username" ;

Mas se um usuário mal-intencionado entrar "james; rm -rf /" como username, seu programa executará

system "finger james; rm -rf /" ;
que apagará o máximo possível dos seus arquivos, o que provavelmente não é o que você pretendia. Portanto, verifique que o username seja válido, com algo do tipo
$username!~ /[^\w.-]/ || die "Ops!  Bela tentativa, amigo." ;
ou use uma forma diferente do comando system:
system("finger", $username) ;
ou invente algum outro meio de resolver o problema.

Para um hacker é fácil enviar qualquer variável do form para o seu script contendo qualquer valor (inclusive caracteres não-imprimíveis). Sua segurança não deverá confiar em campos contendo certos valores, até mesmo se existentes ou não-existentes.

Voltar ao topo da página


Colocando seu Script no Servidor

Diferentes Web servers são configurados diferentemente. Alguns lhe permitem colocar seus scripts CGI no mesmo diretório que suas páginas Web, com nomes de arquivos terminando em ".cgi". Outros servidores exigem que você coloque todos os scripts CGI em um diretório específico, geralmente chamado "cgi-bin". Seu webmaster lhe dirá.

Você precisa colocar as permissões corretas no arquivo do programa. Em Unix, o servidor Web (como qualquer processo) roda sob algum username. Seu programa CGI precisa ser executável por esse username, e deve ter permissão de leitura se for um script Perl ou shell. Em Unix, dê as permissões corretas com "chmod 750 *.cgi" (ou "chmod 755 *.cgi", se seu servidor não tiver acesso de grupo para seus arquivos -- tente ambos, ou pergunte ao seu webmaster).

Se o seu script não rodar:

Voltar ao topo da página


Enviando um Arquivo Existente como Resposta

Se sua resposta em HTML for sempre a mesma, ou se você quiser responder com um de vários arquivos existentes, o header de resposta "Location:" poderá lhe ser útil. Use-o para redirecionar o browser para outro URL.

Como exemplo, se seu script CGI imprime em STDOUT a seguinte linha:

Location: resposta.html
seguida de uma linha vazia, então o browser remoto recebe resposta.html e o trata como a resposta de seu script CGI. Você pode redirecionar o browser para um URL relativo ou absoluto.

Nessa situação, não escreva o header de resposta "Content-type:".

Voltar ao topo da página


Outras Variáveis de Ambiente CGI Úteis

Os scripts CGI têm acesso a umas 20 variáveis de ambiente, tais como QUERY_STRING e CONTENT_LENGTH mencionadas na página principal. A lista completa está na NCSA.

Algumas outras que você poderá achar úteis:

REQUEST_METHOD
O método HTTP com que esse script foi chamado. Geralmente "GET", "POST", ou "HEAD".

HTTP_REFERER
O URL do form submetido. Ela nem sempre é setada, por isso não confie. Também não a use para invadir a privacidade dos outros.

PATH_INFO
Informação extra sobre o caminho. É possível passar informações adicionais para seu script no URL, após o nome do arquivo do script CGI. Por exemplo, chamar o URL
http://www.meuhost.com/meucaminho/meuscript.cgi/caminho/info/aqui
colocará o valor "/caminho/info/aqui" em PATH_INFO. Comumente usada para dados como caminho, mas pode ser usada para qualquer finalidade.

SERVER_NAME
O hostname ou endereço IP de seu Web server (pelo menos para essa solicitação).
SERVER_PORT
A porta do seu Web server (pelo menos para essa solicitação).
SCRIPT_NAME
O URL local do script em execução. O padrão CGI não deixa claro se a barra inicial é incluída, mas a maioria dos servers atuais a incluem. Você pode contemplar os dois casos com esta linha de Perl, que garante uma barra inicial:
$ENV{'SCRIPT_NAME'}=~ s#^/?#/# ;

Assim, o URL do script que está sendo executado é, em Perl,

"http://$ENV{'SERVER_NAME'}:$ENV{'SERVER_PORT'}$ENV{'SCRIPT_NAME'}"

O URL completo com que o script foi chamado pode também ter PATH_INFO e QUERY_STRING no final.

Repetindo, elas estão todas na lista completa da NCSA.

Voltar ao topo da página


Retornando uma Imagem ou Outra Resposta Não-HTML a partir de um Script CGI

A maioria dos scripts CGI retorna dados HTML, mas você pode retornar qualquer tipo de dado que desejar. Basta usar o tipo MIME correto na linha "Content-type:", seguida da necessária linha vazia, seguida dos dados puros do recurso que você está retornando. No caso de arquivos HTML, esses dados são o texto HTML. No caso de imagens, áudio ou vídeo, são dados binários puros. Por exemplo, para responder com um arquivo GIF, use:

Content-type: image/gif

GIF89a&%*$@#--- conteúdo binário do arquivo GIF aqui ---$(*&%(*@#......

Seu arquivo HTML pode carregar uma imagem gerada por script com

<img src="gifmaker.cgi?param1=valor1&param2=valor2">

Um dos meus exemplos favoritos disso era o Interactive Graphics Renderer, que renderiza ícones 3-D de acordo com as cores, forma, textura, iluminação, etc. que você definir. Você pode usar os ícones resultantes nas suas Web pages, como melhores bullets de listas e linhas horizontais. Nota: Esse site perdeu temporariamente sua locação; o autor diz que este link deverá futuramente apontar para a nova locação.

Tipos MIME

Os tipos MIME são strings padrão, indiferentes à caixa (maiúscula ou minúscula), que identificam um tipo de dado, usadas em toda a Internet para muitas finalidades. Elas iniciam com o tipo geral de dado (como text, image, ou audio), seguido de uma barra, e terminam com o tipo específico de dados (como html, gif ou jpeg). Os arquivos HTML são identificados com text/html, e GIFs e JPEGs são identificados com image/gif e image/jpeg.

Voltar ao topo da página


Qual é a diferença entre GET e POST?

GET e POST são dois diferentes métodos definidos em HTTP, que fazem coisas muito diferentes, mas ambos são capazes de submeter forms ao servidor.

Normalmente, GET é usado para obter um arquivo ou outro recurso, possivelmente com parâmetros especificando mais exatamente o que é necesário. No caso de entrada de form, GET o inclui integralmente no URL, como

GET é como o seu browser faz download da maioria de arquivos, como arquivos HTML e imagens. Ele também pode ser usado para a maioria das submissões de forms, se não houver dados demais (o limite varia de browser para browser).

O método GET é idempotente, ou seja, os efeitos colaterais de várias solicitações GET idênticas são os mesmos que para uma única solicitação GET. Em particular, browsers e proxies podem armazenar no cache respostas a GET, portanto duas submissões de form idênticas poderão não chegar, as duas, ao seu script CGI. Portanto, não use GET se quiser registrar cada solicitação, ou de alguma forma armazenar dados provenientes de cada solicitação.

Normalmente, POST é usado para enviar um bloco de dados ao servidor para ser processado, seja lá o que ele contenha. (O nome POST pode ter sido inspirado na idéia de enviar - "to post" - uma nota para um grupo de discussão ou de notícias.) Quando um form HTML é submetido usando POST, os dados do form são anexados ao final da solicitação POST, em seu próprio objeto. Isso não é tão rápido e fácil quanto usar GET, mas é mais versátil. Por exemplo, você pode enviar arquivos inteiros usando POST. Ainda, o tamanho dos dados não é limitado, como ocorre com GET.

Tudo isso, porém, ocorre nos bastidores. Para o programador CGI, GET e POST funcionam de modo quase idêntico, e são igualmente fáceis de usar. Algumas vantagens de POST: você não está limitado nos dados que pode submeter; e você pode ter a certeza de que seu script será executado toda vez que o form for submetido. Uma vantagem de GET: a submissão inteira do form pode ser encapsulada em um URL, como um hiperlink ou bookmark (mas veja AutoPOST, um utilitário para fazer isso com POST).

Voltar ao topo da página


Adquirindo Maior Controle com Scripts para Header Não-desmembrado

Normalmente, quando seu script CGI imprime o header "Content-type:", "Location:" ou outros, o servidor desmembra esses headers e gera uma resposta HTTP apropriada para o usuário. Ocasionalmente, você pode desejar um melhor controle sobre a resposta HTTP. A maioria dos Web servers suporta scripts para header não-desmembrado (ou "NPH", non-parsed header), os quais geram uma resposta HTTP completa e descartam o desmembramento normalmente feito pelo servidor.

Para usá-los, você precisa conhecer um pouco de HTTP -- especificamente, os formatos da linha de status e das linhas de header.

Em seu script para header não-desmembrado, apenas imprima as linhas HTTP completas de status and header onde um script normal imprimiria a linha "Content-Type:". Inclua a linha vazia final. Qualquer coisa que seu script imprima será enviada ao usuário na íntegra, como resposta HTTP completa, sem modificação pelo servidor.

Dê aos seus scripts NPH nomes começando com "nph-", como "nph-meuscript.cgi"; todo script cujo nome comece com "nph-" será tratado como um script NPH. Isso funciona na maioria dos servidores, incluindo Apache e NCSA. Outros servidores podem usar esquemas diferentes para identificar scripts NPH; leia a documentação ou pergunte ao seu webmaster.

Para um exemplo de script NPH, veja CGIProxy.

Se isso está confuso, não se preocupe. No improvável evento de você algum dia precisar de um script NPH, isso tudo fará sentido.

Voltar ao topo da página


Voltar à Página Principal


© 1996-1998 James Marshall
(comentários são bem-vindos; para perguntas, por favor verifique primeiro a FAQ)
Traduzido em 1999 por Claudio F. Chagas

Última Modificação: 18 Abril 1998 http://www.jmarshall.com/easy/cgi/portuguese/cgi_footnotes.html