Como a web funciona: HTTP explicados

Introdução

Sobre este tutorial


Eu li um artigo muito bem escrito sobre como a internet funciona e decidi traduzir ele.
Algumas partes estão um pouco obsoletas pois o artigo é antigo, mas é interessante conhecer a internet de 20 anos atrás e como ela se desenvolveu, além de que o principal mantém-se igual.
Também vale para a nostalgia:)


Eu acrescentei alguns pontos sobre  a internet hoje em dia como na parte do CGI.


O autor começa a introdução aqui:
Esta é uma tentativa de dar uma compreensão básica de como a web funciona e foi escrita porque vi muitos artigos em vários grupos de notícias que mostravam claramente que as pessoas precisavam aprender isso. Não sabendo de nenhum lugar para encontrar essa informação, decidi coletá-la em um artigo. Espero que você ache útil!

Quero abrangir o protocolo HTTP, que é usado para transmitir e receber páginas da web, bem como algumas tecnologias e script de servidor. Supõe-se que você já saiba como criar páginas da web e, de preferência, algum HTML também. Também é assumido que você tem algum conhecimento básico de URLs. (Um URL é o endereço de um site)

Eu não estou totalmente feliz com isso, então o feedback seria muito bem vindo. Se você não é realmente uma pessoa técnica e este tutorial deixa você confuso ou não responde a todas as suas perguntas, eu gostaria muito de ouvir sobre isso. Correções e opiniões também são bem vindas.

Uma pequena introdução


Quando você navega na Web, a situação é basicamente a seguinte: você se senta em seu computador e deseja ver um documento em algum lugar na Web, no qual você tem o URL.

Como o documento que você quer ler está em algum outro lugar do mundo e, provavelmente, muito longe de você, são necessários mais alguns detalhes para torná-lo disponível para você. O primeiro detalhe é o seu navegador. Você começa e digita o URL nele (pelo menos você diz ao navegador de alguma forma onde você quer ir, talvez clicando em um link).

No entanto, a imagem ainda não está completa, pois o navegador não consegue ler o documento diretamente do disco onde está armazenado, se esse disco estiver em outro continente. Portanto, para que você possa ler o documento, o computador que contém o documento deve executar um servidor da Web. Um servidor da Web é apenas um programa de computador que ouve solicitações de navegadores e as executa.

Então, o que acontece a seguir é que o navegador entra em contato com o servidor e solicita que o servidor entregue o documento a ele. O servidor então fornece uma resposta que contém o documento e o navegador exibe isso alegremente para o usuário. O servidor também informa ao navegador que tipo de documento é esse (arquivo HTML, arquivo PDF, arquivo ZIP, etc.) e o navegador mostra o documento com o programa que ele configurou para usar nesse tipo de documento.

O navegador exibirá documentos HTML diretamente e, se houver referências a imagens, applets Java, clipes de som, etc., e o navegador tiver sido configurado para exibi-los, os solicitará também dos servidores em que residem. (Normalmente, o mesmo servidor do documento, mas nem sempre.) É importante notar que essas solicitações serão separadas e adicionarão carga adicional ao servidor e à rede. Quando o usuário segue outro link, toda a sequência começa de novo.

Essas solicitações e respostas são emitidas em um idioma especial chamado HTTP , abreviatura de HyperText Transfer Protocol. O que este artigo basicamente faz é descrever como isso funciona. Outros protocolos comuns que funcionam de maneira semelhante são o FTP e o Gopher, mas também há protocolos que funcionam de maneiras completamente diferentes. Nenhum destes é coberto aqui, desculpe. (Há um link para mais alguns detalhes sobre FTP nas referências .)

É importante notar que o HTTP só define o que o navegador e o servidor da web dizem uns aos outros, não como eles se comunicam. O trabalho real de mover bits e bytes para frente e para trás na rede é feito por TCP e IP , que também são usados ​​por FTP e Gopher (assim como a maioria dos outros protocolos da Internet).

Ao continuar, observe que qualquer programa de software que faz o mesmo que um navegador da Web (isto é, recuperar documentos de servidores) é chamado de cliente na terminologia de rede e um agente do usuário na terminologia da web. Observe também que o servidor é adequadamente o programa do servidor e não o computador no qual o servidor é um programa aplicativo. (Às vezes chamado de máquina do servidor .)

O que acontece quando eu sigo um link?

Etapa 1: analisando o URL

A primeira coisa que o navegador precisa fazer é examinar a URL do novo documento para descobrir como obter o novo documento. A maioria dos URLs tem esta forma básica: "protocol://server/request-URI". A parte do protocolo descreve como informar ao servidor qual documento você deseja e como adquirir-lo. A parte do servidor informa ao navegador qual servidor deve entrar em contato, e a solicitação-URI é o nome usado pelo servidor da web para identificar o documento.

Etapa 2: enviando a solicitação
Normalmente, o protocolo é "http". Para recuperar um documento via HTTP, o navegador transmite a seguinte solicitação ao servidor: "GET /request-URI HTTP/version", em que a versão informa ao servidor qual versão HTTP é usada. (Normalmente, o navegador inclui mais algumas informações também. Os detalhes são abordados posteriormente.)

Um ponto importante aqui é que essa string de solicitação é tudo que o servidor já viu. Portanto, o servidor não se importa se a solicitação veio de um navegador, um verificador de links, um validador, um robô do mecanismo de pesquisa ou se você digitou manualmente. Apenas realiza o pedido e retorna o resultado.

Etapa 3: a resposta do servidor
Quando o servidor recebe a solicitação HTTP, ele localiza o documento apropriado e o retorna. No entanto, uma resposta HTTP é necessária para ter um formulário específico. Deve ser assim:

HTTP/[VER] [CODE] [TEXT]
Field1: Value1
Field2: Value2

...Document content here...

A primeira linha mostra a versão HTTP usada, seguida por um número de três dígitos (o código de status HTTP) e uma frase de motivo para humanos.

Geralmente o código é 200 (o que basicamente significa que tudo está bem) e a frase "OK".

A primeira linha é seguida por algumas linhas chamadas header(cabeçalho), que contêm informações sobre o documento.

O header termina com uma linha em branco, seguida pelo conteúdo do documento. Este é um cabeçalho típico:

HTTP/1.0 200 OK
Server: Netscape-Communications/1.1
Date: Tuesday, 25-Nov-97 01:22:04 GMT
Last-modified: Thursday, 20-Nov-97 10:44:53 GMT
Content-length: 6372
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
...followed by document content...

  1. Vimos desde a primeira linha que o pedido foi bem sucedido.
  2. A segunda linha é opcional e nos informa que o servidor executa o servidor da Web Netscape Communications, versão 1.1.
  3. Em seguida, obtemos o que o servidor acha que é a data atual e quando o documento foi modificado por último, seguido pelo tamanho do documento em bytes e o campo mais importante: "Content-type"(Tipo de conteúdo).

O campo Content-type é usado pelo navegador para informar em qual formato o documento que recebe está. HTML é identificado com "text/html", texto comum com "text/plain", um GIF é "image/gif" etc.... A vantagem disso é que o URL pode ter qualquer final e o navegador ainda vai conseguir.

(Um conceito importante aqui é que, para o navegador, o servidor funciona como uma caixa preta. Ou seja: o navegador solicita um documento específico e o documento é retornado ou uma mensagem de erro é retornada. Como o servidor produz o documento permanece desconhecido para o navegador. Isto significa que o servidor pode lê-lo a partir de um arquivo, rodar um programa que o gera, compilar analisando algum tipo de arquivo de comando ou (muito improvável, mas em princípio possível) tê-lo ditado pelo administrador do servidor via software de reconhecimento de voz. Isso dá ao administrador do servidor uma grande liberdade para experimentar diferentes tipos de serviços, pois os usuários não se importam (nem sequer sabem) como as páginas são produzidas.)

O que o servidor faz
Quando o servidor é configurado, ele geralmente é configurado para usar um diretório em algum lugar no disco como seu root(diretório raiz) e que haja um nome de arquivo padrão (digamos, "index.html") para cada diretório.

Isso significa que, se você solicitar ao servidor o arquivo "/" (como em "http: //www.domain.tld/"), ele obterá o arquivo index.html no diretório no root do servidor.

Normalmente, pedir "/foo/bar.html" lhe dará o arquivo bar.html do diretório foo diretamente abaixo da raiz do servidor.

Geralmente  é isso. O servidor pode ser configurado para mapear "/foo/" em algum outro diretório em outro lugar no disco ou até mesmo para usar programas do lado do servidor para responder a todos os pedidos que solicitam esse diretório. O servidor nem precisa mapear solicitações em uma estrutura de diretórios, ele pode usar algum outro esquema.

Versões HTTP
Até agora, existem três versões do HTTP. O primeiro foi HTTP / 0.9, que era verdadeiramente primitivo e nunca foi especificado em nenhum padrão. Isso foi corrigido pelo HTTP/1.0, que foi emitido como um padrão na RFC 1945. (Consulte as referências ). HTTP/1.0 é a versão do HTTP que está em uso comum atualmente (geralmente com algumas extensões 1.1), enquanto o HTTP/0.9 raramente, ou nunca, é usado pelos navegadores. (Alguns clientes HTTP mais simples ainda o usam, pois não precisam das extensões posteriores.)

A RFC 2068 descreve o HTTP/1.0, que estende e melhora o HTTP/1.0 em várias áreas. Muito poucos navegadores o suportam (o MSIE 4.0 é o único conhecido pelo autor), mas os servidores estão começando a fazê-lo.

As principais diferenças são algumas extensões no HTTP/1.1 para a criação de documentos on-line via HTTP e um recurso que permite que os clientes solicitem que a conexão seja mantida aberta após uma solicitação, para que ela não precise ser restabelecida para a próxima solicitação. Isso pode economizar alguma carga de espera e de servidor se várias solicitações tiverem que ser emitidas rapidamente.

Este documento descreve o HTTP/1.0, exceto algumas seções que cobrem as extensões HTTP/1.1. Aqueles serão explicitamente rotulados.

O pedido enviado pelo cliente

A forma de um Request (pedido)

Basicamente, todas as solicitações são assim:

[METH] [REQUEST-URI] HTTP/[VER]
[fieldname1]: [field-value1]
[fieldname2]: [field-value2]

[request body, if any]


O METH (para o método de solicitação) fornece o método de solicitação usado, do qual existem vários, e todos fazem coisas diferentes.

O exemplo acima usado GET, mas abaixo alguns mais são explicados. O REQUEST-URI é o identificador do documento no servidor, como "/index.html" ou o que for. VER é a versão HTTP, como na resposta. Os campos de cabeçalho também são os mesmos que na resposta do servidor.

O corpo da solicitação é usado apenas para solicitações que transferem dados para o servidor, como POST e PUT. (Descrito abaixo.)

GETting a document - COMO OBTER UM DOCUMENTO
Existem vários tipos de pedidos, sendo o mais comum GET. Uma requisição GET basicamente significa "me envie este documento" e se parece com isto: "GET document_path HTTP / version". (Como foi descrito acima.)

Para o URL "http://www.yahoo.com/", o document_path seria "/" (index.html)
e para "http://www.w3.org/Talks/General.html" é "/Talks/General.html".

No entanto, essa primeira linha não é a única coisa que um user agent (UA) geralmente envia, embora seja a única coisa realmente necessária. O UA pode incluir vários campos de cabeçalho na solicitação para fornecer mais informações ao servidor. Esses campos têm o formato "fieldname: value" e são colocados em linhas separadas após a primeira linha de solicitação.

Alguns dos campos de cabeçalho que podem ser usados ​​com GET são:
User-Agent (Agente de usuário)
Esta é uma string que identifica o User-Agent. Como por exemplo Mozilla/5.0
Referer
O campo de referência (sim, é escrito incorretamente no padrão) informa ao servidor de onde o usuário veio, o que é muito útil para registrar e acompanhar quem vincula as páginas.
If-Modified-Since
Se um navegador já tiver uma versão do documento em seu cache, ele poderá incluir esse campo e configurá-lo para o horário em que recuperou essa versão. O servidor pode então verificar se o documento foi modificado desde a última vez que o navegador o baixou e enviá-lo novamente, se necessário. O ponto principal é claro que, se o documento não for alterado, o servidor poderá apenas dizer isso e economizar algum tráfego de espera e de rede.
From
Esse campo head é um sonho de spammers que se torna realidade: ele deve conter o endereço de email de quem controla o agente do usuário. Poucos navegadores, se algum, o usam, em parte devido à ameaça de spammers. No entanto, robôs da Web devem usá-lo, para que os webmasters possam contatar as pessoas responsáveis ​​pelo robô caso ele se comporte mal.
Authorization
Este campo pode conter nome de usuário e senha se o documento em questão exigir autorização para ser acessado.

Para juntar todas estas peças: esta é uma típica requisição GET

Head: verificação de documentos

Pode-se, às vezes, querer ver os headers retornados pelo servidor para um determinado documento, sem fazer o download do documento. Isso é exatamente o que o método de solicitação HEAD fornece. O HEAD parece e funciona exatamente como o GET, apenas com a diferença de que o servidor retorna apenas os cabeçalhos e não o conteúdo do documento.

Isso é muito útil para programas como verificadores de link, pessoas que desejam ver os cabeçalhos de resposta (para ver qual servidor é usado ou para verificar se estão corretos) e muitos outros tipos de uso.

A resposta retornada pelo servidor

Esboço

O que o servidor retorna consiste em uma linha com o código de status, uma lista de campos de cabeçalho, uma linha em branco e, em seguida, o documento solicitado, se ele for retornado. Mais ou menos assim:

HTTP/1.0 code text
Field1: Value1
Field2: Value2

...Document content here...

Os códigos de status
Os códigos de status são todos os números de três dígitos agrupados pelo primeiro dígito em 5 grupos. A razão pela qual as frases fornecidas com os códigos de status abaixo são apenas sugestões. O servidor pode retornar qualquer frase que deseje.

1xx: Informativo

Nenhum código de status 1xx é definido e eles são reservados apenas para fins experimentais.

2xx: bem sucedido

Significa que a solicitação foi processada com sucesso.
200 OK
Significa que o servidor fez o que o cliente queria, e está tudo bem.
Outras
O restante dos códigos de status 2xx são principalmente destinados ao processamento de scripts e não são usados ​​com frequência.

3xx: redirecionamento

Significa que o recurso está em outro lugar e que o cliente deve tentar novamente em um novo endereço.
301 mudou-se permanentemente
O recurso que o cliente solicitou está em outro lugar, e o cliente deve ir até lá para obtê-lo. Quaisquer links ou outras referências a este recurso devem ser atualizados.
302 Movido temporariamente
Isso significa o mesmo que a resposta 301, mas os links agora não devem ser atualizados, pois o recurso pode ser movido novamente no futuro.
304 Não modificado
Essa resposta pode ser retornada se o cliente usou o campo de cabeçalho if-modified-since e o recurso não foi modificado desde o momento especificado. Simplesmente significa que a versão em cache deve ser exibida para o usuário.

4xx: erro do cliente

Significa que o cliente errou de alguma forma, geralmente pedindo algo que não deveria ter pedido.
400: pedido incorreto
A solicitação enviada pelo cliente não tinha a sintaxe correta.
401 não autorizado
Significa que o cliente não tem permissão para acessar o recurso. Isso pode mudar se o cliente tentar novamente com um cabeçalho de autorização .
403: Proibido
O cliente não tem permissão para acessar o recurso e a autorização não ajudará.
404 não encontrado
Já vi isso antes? :) Isso significa que o servidor não ouviu falar do recurso e não tem mais pistas sobre o que o cliente deve fazer sobre isso. Em outras palavras: link morto.

5xx: erro do servidor

Isso significa que o servidor estragou ou não conseguiu fazer o que o cliente solicitou.
500: Erro interno do servidor
Algo deu errado no servidor.
501: não implementado
O método de solicitação não é suportado pelo servidor.
503 serviço indisponível
Isso às vezes acontece se o servidor estiver muito carregado e não puder atender à solicitação. Normalmente, a solução é para o cliente esperar um pouco e tentar novamente.

Os campos de resposta do header

Esses são os campos de cabeçalho que um servidor pode retornar em resposta a uma solicitação.
Location
Isso informa ao agente do usuário onde o recurso solicitado pode ser encontrado. O valor é apenas o URL do novo recurso.
Server
Isso informa ao agente do usuário qual servidor da web é usado. Quase todos os servidores da web retornam esse cabeçalho, embora alguns o deixem de fora.
Content-length
Isso dá o tamanho do documento, em bytes.
Content-type
Isso descreve o formato de arquivo do recurso.
Content-encoding
Isso significa que o recurso foi codificado de alguma forma e deve ser decodificado antes de ser usado.
Expires
Esse campo pode ser definido para dados atualizados em um horário conhecido (por exemplo, se forem gerados por um script). Ele é usado para impedir que os navegadores armazenem em cache o recurso além da data especificada.
Last-modified
Isso informa ao navegador quando o recurso foi modificado pela última vez. Pode ser útil para espelhar, atualizar notificações etc.

Cache: agentes entre o servidor e o cliente

O cache do navegador

Você deve ter notado que, quando você volta para uma página que você viu, não demora muito para que a página seja carregada muito mais rapidamente. Isso porque o navegador armazenou uma cópia local quando foi baixado pela primeira vez. Essas cópias locais são mantidas no que é chamado de cache. Geralmente, um define um tamanho máximo para o cache e um tempo máximo de armazenamento em cache para documentos.

Isso significa que, quando uma nova página é visitada, ela é armazenada no cache e, se o cache estiver cheio (perto do limite máximo de tamanho), algum documento que o navegador considere improvável de ser visitado novamente é excluído para liberar espaço.

Além disso, se você for a uma página armazenada no cache, o navegador pode descobrir que você definiu sete dias como o tempo máximo de armazenamento e oito dias já passaram desde a última visita, portanto, a página precisa ser recarregada.

Exatamente como os caches funcionam, se diferem entre os navegadores, mas essa é a ideia básica, e é boa porque economiza tempo tanto para o usuário quanto para o tráfego de rede. Há também alguns detalhes HTTP envolvidos, mas serão abordados posteriormente.

Caches de proxy
Caches de navegador são um bom recurso, mas quando muitos usuários navegam no mesmo site, este, geralmente acaba armazenando o mesmo documento em muitos caches diferentes e atualizando-o várias vezes para diferentes usos. Claramente, isso não é o ideal.

A solução é permitir que os usuários compartilhem um cache, e isso é exatamente o que os caches de proxy são. Os navegadores ainda têm seus caches locais, mas as solicitações HTTP para documentos que não estão no cache do navegador não são mais enviadas ao servidor, em vez disso, elas são enviadas para o cache do proxy. Se o proxy tiver o documento em seu cache, ele apenas retornará o documento (como faria o cache do navegador) e, se não o fizer, enviará a solicitação em nome do navegador, armazenará o resultado e o retransmitirá para o navegador.

Portanto, o proxy é realmente um cache comum para vários usuários e pode reduzir o tráfego de rede de forma bastante drástica. Ele também pode distorcer muito as estatísticas baseadas em log. :)

Uma solução mais avançada que um cache de proxy único é uma hierarquia de caches de proxy. Imagine um grande provedor de serviços de Internet pode ter um cache de proxy para cada parte do país e configurar cada um dos proxies regionais para usar um cache de proxy nacional em vez de ir diretamente para os servidores da Web de origem. Essa solução pode reduzir ainda mais o tráfego de rede. Mais detalhes sobre isso estão ligados nas referências .

Programação do Server-side (lado do servidor)

O que é e por que fazer isso?

Server-side Scripts são simplesmente programas que são executados no servidor da Web em resposta a solicitações do cliente. Esses scripts produzem HTML normal (e às vezes cabeçalhos HTTP também) como saída, que é retornada ao cliente como se o cliente tivesse solicitado uma página comum. Na verdade, não há como o software cliente informar se o script foi usado ou não.

Tecnologias como JavaScript, VBScript e Java applets são executados no cliente e, portanto, não são exemplos disso.

Há uma grande diferença entre os scripts do lado do servidor e do lado do cliente, pois o cliente e o servidor são geralmente computadores diferentes. Portanto, se todos os dados que o programa precisa estiverem localizados no servidor, talvez faça sentido usar o script do lado do servidor em vez do lado do cliente. (Há também o problema de o cliente não ter um navegador que suporte a tecnologia de script ou pode estar desativado.) Se o programa e o usuário precisarem interagir frequentemente, o script do lado do cliente provavelmente é o melhor, para reduzir o número de solicitações enviado para o servidor.

Portanto, em geral, se o programa precisar de muitos dados e interações pouco frequentes com o servidor, o script do lado do servidor provavelmente será o melhor. Aplicativos que usam menos dados e mais interação são melhor colocados no cliente. Além disso, aplicativos que coletam dados ao longo do tempo precisam estar no servidor onde o arquivo de dados é mantido.

Um exemplo do primeiro seria motores de busca como o Altavista(quem lembra daquela época :)). Obviamente, não é viável baixar todos os documentos que o Altavista coletou para pesquisá-los localmente. Um exemplo do último seria um simples jogo de tabuleiro. Nenhum dado é necessário e ter que enviar uma nova solicitação para o servidor para cada movimento que você faz rapidamente se torna tedioso.

Há um tipo de uso que foi deixado de fora aqui: o que você faz quando quer que um programa trabalhe em dados com muita interação com o usuário? Não há uma boa solução no momento, mas existe uma no horizonte chamada XML. (Veja as referências para mais informações.)

Como funciona

Os detalhes de como o script do lado do servidor funciona variam muito com a técnica usada (e há muitas delas). No entanto, algumas coisas permanecem as mesmas. O servidor da Web recebe uma solicitação como qualquer outra, mas observa que essa URL não é mapeada para um arquivo simples, mas, de alguma forma, para uma área de script.

O servidor, em seguida, inicia o script, alimentando todas as informações contidas nos cabeçalhos e na URL da solicitação. Em seguida, o script é executado e produz como saída os cabeçalhos HTML e HTTP a serem retornados para o cliente, do qual o servidor cuida.

CGI


O CGI (Common Gateway Interface) foi introduzido em 1993 para permitir a execução de scripts por um servidor web. Um usuário solicitaria um URL como http://www.example.com/cgi-bin/hello.pl e o servidor da web (em example.com, por este exemplo) localizaria e executaria o script hello.pl , passando a solicitação parâmetros como variáveis ​​de ambiente e retornando a stout (saída padrão) no corpo da resposta.

A CGI conectou o mundo da web e o mundo do UNIX, permitindo a criação de verdadeiros aplicativos da web.

Mais detalhado CGI é uma maneira de interagir com servidores da Web e programas do lado do servidor. O CGI é completamente independente da linguagem de programação, sistema operacional e servidor da web. Atualmente, é a técnica de programação mais comum do lado do servidor e também é suportada por quase todos os servidores da web existentes. Além disso, todos os servidores implementam-no (quase) da mesma forma, para que você possa criar um script CGI para um servidor e depois distribuí-lo para ser executado em qualquer servidor web.

Como escrevi acima, o servidor precisa de uma maneira de saber quais URLs mapeiam para scripts e quais URLs apenas mapeiam para arquivos HTML comuns. Para CGI isso geralmente é feito criando diretórios CGI no servidor. Isso é feito na configuração do servidor e informa ao servidor que todos os arquivos em um determinado diretório de nível superior são scripts CGI (localizados em algum lugar no disco) a serem executados quando solicitados. (O diretório padrão é geralmente /cgi-bin/, portanto, pode-se dizer que URLs como esta: http://www.varsity.edu/cgi-bin/search apontam para um script CGI. Observe que o diretório pode ser chamado de qualquer coisa. .) Alguns servidores também podem ser configurados para não usar diretórios CGI e, em vez disso, exigem que todos os programas CGI tenham nomes de arquivos terminados em .cgi.

Os programas CGI são apenas programas executáveis ​​comuns (ou programas interpretados escritos em, digamos, Perl ou Python, desde que o servidor saiba como iniciar o programa), para que você possa usar praticamente qualquer linguagem de programação desejada. Antes do programa CGI ser iniciado, o servidor da web define várias variáveis ​​de ambiente que contêm as informações que o servidor da web recebeu na solicitação. Exemplos disso são o endereço IP do cliente, os cabeçalhos da solicitação etc. Além disso, se a URL solicitada continha um "?", Tudo após o "?" é colocado em uma variável de por si só.

Isso significa que informações adicionais sobre a solicitação podem ser colocadas na URL no link. Uma forma de usá-lo é pelos contadores de acessos de vários usuários para informar qual usuário foi atingido neste momento. Assim, o usuário pode inserir uma imagem em sua página e ter o atributo SRC como um link para o script CGI como este: SRC = "http://stats.vendor.com/cgi-bin/counter.pl?username ". Em seguida, o script pode informar qual usuário foi atingido e incrementado e exibir a contagem correta. (Ou seja: o de Pedro e não o de Paulo)

A forma como o CGI retorna sua saída (cabeçalhos HTTP e documento HTML) para o servidor é extremamente simples: ele é gravado no padrão. Em outras palavras, em um script Perl ou Python você apenas usa a instrução print. Em C você usa printf ou algum equivalente (C ++ usa cout <<) enquanto Java usaria System.out.println.
Mais informações sobre o CGI estão disponíveis nas referências .

O que foi tão bom em cgi-bin?
Sem o CGI, não haveria aplicações web. Se você olhar de perto os URLs de alguns aplicativos da web antigos, como Yahoo ou eBay, você ainda verá as letras cgi-bin . Provavelmente, os aplicativos já estão equipados com outras tecnologias, e as URLs são relíquias, apontando para os alicerces tecnológicos de uma época passada.

O CGI foi enganosamente fácil de desenvolver: basta soltar um script no diretório cgi-bin e você estava pronto para rodar. O “apenas” escondeu uma série de desafios para o aspirante a desenvolvedor em 1993, incluindo obter acesso a uma máquina UNIX, saber como codificar em linguagens estranhas como Perl e entender como definir permissões para garantir que o script fosse realmente executado. A CGI disponibilizou o desenvolvimento da web para uma nova classe de desenvolvedores.

Talvez o mais importante, a CGI abriu as portas para a inovação. Tecnologias como o PHP, agora uma das 5 principais linguagens de programação, começaram com pouco mais que um script CGI. Muitas das tecnologias mais poderosas começam com pouco mais do que brinquedos interessantes, antes de evoluírem para versões mais versáteis, seguras e escaláveis ​​de si mesmas.

Por que a web largou o cgi-bin?
Apesar de continuar a popularidade em URLs (!), O CGI hoje é essencialmente uma tecnologia obsoleta. Em 2016, parece que houve cerca de 400 perguntas sobre o CGI no Stack Overflow , enquanto houve aproximadamente 340mil para o PHP.

Quando você olha para as razões pelas quais a Web avançou, três se destacam: segurança, desempenho e capacidade de absorver a complexidade.

As questões de desempenho e segurança são facilmente explicadas: cada script ou programa CGI seria executado em seu próprio processo, como um programa próprio. Isso adicionaria sobrecarga de desempenho porque para cada solicitação, o script precisaria ser analisado, o intérprete iniciado, o script executado, etc. Além disso, cada script CGI era um programa completo que tinha todos os privilégios do processo pai (geralmente o servidor web).

O cgi-bin teve uma combinação drástica: inicie facilmente (apenas solte um script no local correto) e, de repente, obtenha o poder de acesso ilimitado ao sistema. Como dizemos, com grande poder, vem uma grande responsabilidade. Infelizmente, muitos desenvolvedores não agiram - e talvez nem saibam como agir - com responsabilidade. Isso levou a sistemas inseguros e propensos a erros.

A falta de capacidade da CGI para absorver a complexidade significa que foi fácil começar a construir uma aplicação CGI, mas difícil construir aplicações complexas robustas e escaláveis. Embora as técnicas de gerenciamento de modularidade de aplicativos estivessem presentes nas linguagens de programação na época, elas não eram populares nas linguagens de script usadas com o CGI.

Outras técnicas

O CGI certamente não é a única maneira de fazer programas no lado do servidor e tem sido muito criticado pela ineficiência. Esta última afirmação tem algum peso, uma vez que o programa CGI deve ser carregado na memória e re-executado a partir do zero sempre que for solicitado.

Uma alternativa muito mais rápida é programar para a própria API do servidor. Ou seja: criar um programa que essencialmente se torne parte do processo do servidor e use uma API exposta pelo servidor. O problema com esta técnica é que a API é, naturalmente, dependente do servidor e que, se você usar C / C++ (o que é comum), erros de programação podem travar o servidor inteiro.

A principal vantagem da programação da API do servidor é que ela é muito mais rápida, pois quando a solicitação chega, o programa já está carregado na memória junto com os dados necessários.

Alguns servidores permitem o script em linguagens à prova de falhas. Um exemplo é o AOLServer, que usa tcl. Há também módulos disponíveis para servidores como o Apache, que permitem que você faça a programação da API do servidor em Perl ou Python, o que efetivamente elimina o risco de erros de programação que causam falhas no servidor.
Há também muitas e muitas linguagens e técnicas proprietárias (e não proprietárias) de scripts para vários servidores web. Alguns dos mais conhecidos são ASP, MetaHTML e PHP3.

Envio de formulários GET e POST

A maneira mais comum de os programas do lado do servidor se comunicarem com o servidor da Web é através de formulários HTML comuns. O usuário preenche o formulário e clica no botão de envio, no qual os dados são enviados ao servidor. Se o autor do formulário especificou que os dados devem ser enviados por meio de uma solicitação GET, os dados do formulário serão codificados no URL, usando o ? sintaxe que eu descrevi acima. A codificação usada é de fato muito simples. Se o formulário consistir no nome e no email dos campos e o usuário os preencher como Joe e joe@hotmail.com, o URL resultante será semelhante ao seguinte:
http://www.domain.tld/cgi-bin/script?name=joe&email=joe@hotmail.com

Se os dados contiverem caracteres que não são permitidos em URLs, esses caracteres serão codificados por URL. Isso basicamente significa que o caractere (digamos ~) é substituído por um % seguido por seu número ASCII de dois dígitos (digamos %7E). Os detalhes estão disponíveis na RFC 1738 sobre URLs, que está vinculado nas referências .

POST: envia dados para o servidor
GET não é a única maneira de enviar dados de um formulário, no entanto. Também é possível usar o POST, caso em que a solicitação contém head e um corpo. (Isso é como a resposta do servidor.) O corpo é, então, os dados do formulário codificados como se estivessem no URL, se tivéssemos usado o GET.

Primeiramente, o POST deve ser usado quando a solicitação causar uma mudança permanente de estado no servidor (como adicionar a uma lista de dados) e GET quando este não for o caso (como ao fazer uma pesquisa).

Se os dados puderem ser longos (mais de 256 caracteres), é um pouco arriscado usar GET, pois o URL pode acabar sendo recortado em trânsito. Alguns Sistemas Operacionais não permitem que variáveis ​​de ambiente tenham mais de 256 caracteres, portanto, a variável de ambiente que contém a parte ? Da solicitação pode ser silenciosamente truncada. Esse problema é evitado com o POST, pois os dados não são enviados por meio de uma variável de ambiente.

Alguns scripts que lidam com solicitações POST causam problemas usando um código de status 302 e um head Location para redirecionar os navegadores para uma página de confirmação. No entanto, de acordo com o padrão, isso não significa que o navegador deve recuperar a página referenciada, mas sim que deve reenviar os dados para o novo destino. Veja as referências para detalhes sobre isso.

Vantagens de GET
URLs podem ser guardados com segurança

URLs podem ser armazenados em cache

As desvantagens dos
dados do formulário GET são enviadas usando o URL como a string de consulta, que é um risco de segurança, pois qualquer pessoa pode vê-lo.

Somente 2048 caracteres podem ser enviados, que é o tamanho máximo do URL

Apenas caracteres ASCII são permitidos

Vantagens do POST
Os dados do formulário são enviados usando o corpo da mensagem. Portanto, mais seguro que o GET

Nenhuma limitação no tamanho dos dados do formulário

Nenhuma restrição no tipo de dados. Dados binários também são permitidos

Desvantagens do POST
Não pode ser guardado.

Não pode ser armazenado em cache.

Outros métodos HTTP
HEAD Isso recupera as informações meta do URI solicitado
PUT Substitui todos os recursos atuais pelo novo recurso.
DELETE Remove o URI

Mais detalhes

Negociação de conteúdo

Imagine que você acabou de ouvir falar do novo formato de imagem PNG, e quer usar isso para suas imagens, em vez do GIF mais antigo. No entanto, o GIF é suportado por todos os navegadores com algum auto-respeito, enquanto o PNG é suportado apenas pelos mais modernos. (kkk, bem antigo isso) Então, se você substituir todos os seus GIFs por PNGs, apenas um número limitado de usuários poderá realmente ver suas imagens.

Para evitar isso, pode-se configurar um link para um local imaginário (vamos chamá-lo /foo/imgbar). Então, quando os navegadores solicitarem essa imagem depois de ver o local em um elemento IMG, eles adicionarão um campo de cabeçalho Aceitar à solicitação deles. (A maioria dos navegadores faz isso com todas as solicitações.)

O cabeçalho de aceitação seria então definido como "image/*, image/png", o que significaria: Eu prefiro imagens PNG, mas se você não puder entregar isso, envie-me qualquer imagem que você tenha.

Isso seria em um mundo baseado em padrões. Nós, no entanto, vivemos em um mundo decididamente não-padrão. A maioria dos navegadores simplesmente envia o cabeçalho "Aceitar: * / *", que realmente não diz nada ao servidor. Isso pode mudar no futuro, mas, por enquanto, esse é um recurso interessante, mas inútil.

Cookies

Um cookie é um pedaço de texto que um servidor Web pode armazenar no disco rígido do usuário. São utilizados pelos sites principalmente para identificar e armazenar informações sobre os visitantes. Para se ter uma idéia, um site pode gerar um número de ID exclusivo para cada visitante e armazenar o número de identificação em cada máquina do usuário usando um arquivo de cookie. Um exemplo é aquele cookie que um site cria para que você não precise digitar sua senha novamente quando for ao site outra vez.

Quando estamos navegando na WEB usando o Internet Explorer da Microsoft, é possível ver todos os cookies que são armazenados no computador. O lugar para localizá-los é em um diretório chamado C:\Windows\Cookies (No Vista e Windows 7, ficam em C:\Users\Usuario\AppData\Roaming\Microsoft\Windows\Cookies) . Nesta pasta que são armazenadas arquivos simples de texto dos sites navegados.

O cookie é enviado como um cabeçalho HTTP por um servidor da Web para um navegador da Web e, em seguida, é enviado de volta inalterado pelo navegador cada vez que acessa esse servidor. Um cookie pode ser usado para autenticação, controle de sessão, para armazenar as preferências do usuário, ou qualquer outra coisa que pode ser realizado através de armazenamento de dados textuais.

Os sites de comércio eletrônico utilizam bastante os Cookies por causa dos seus carrinhos de compra. Eles podem recomendar produtos com base nas suas buscas da última visita, ou armazenar os produtos que você adicionou no carrinho e não comprou. Também são utilizados para criar uma camada de sessão de usuário sobre HTTP que é sem estado.

Muitas pessoas acham que os cookies violam a privacidade, pelo fato de armazenar informações do usuário, como também sobre a possibilidade de passar estas informações a terceiros. Além disto, eles podem coletar informações sobre o comportamento do usuário e gerar spams com as informações mais solicitadas. Por isso, a maioria dos navegadores modernos permite a seus usuários decidirem se querem ou não aceitar cookies em suas máquinas, a fim de evitar qualquer tipo de inconveniência.

Logs do servidor
A maioria dos servidores (se não todos) cria logs de seu uso. Isso significa que toda vez que o servidor receber uma solicitação, ele adicionará uma linha em seu log, que fornece informações sobre a solicitação. Abaixo um trecho de um registro real:

rip.axis.se - - [04/Jan/1998:21:24:46 +0100] "HEAD /ftp/pub/software/ HTTP/1.0" 200 6312 - "Mozilla/4.04 [en] (WinNT; I)"
tide14.microsoft.com - - [04/Jan/1998:21:30:32 +0100] "GET /robots.txt HTTP/1.0" 304 158 - "Mozilla/4.0 (compatible; MSIE 4.0; MSIECrawler; Windows 95)"
microsnot.HIP.Berkeley.EDU - - [04/Jan/1998:22:28:21 +0100] "GET /cgi-bin/wwwbrowser.pl HTTP/1.0" 200 1445 "http://www.ifi.uio.no/~larsga/download/stats/" "Mozilla/4.03 [en] (Win95; U)"
isdn69.ppp.uib.no - - [05/Jan/1998:00:13:53 +0100] "GET /download/RFCsearch.html HTTP/1.0" 200 2399 "http://www.kvarteret.uib.no/~pas/" "Mozilla/4.04 [en] (Win95; I)"
isdn69.ppp.uib.no - - [05/Jan/1998:00:13:53 +0100] "GET /standard.css HTTP/1.0" 200 1064 - "Mozilla/4.04 [en] (Win95; I)"

Esse log está no formato de log comum estendido, que é suportado pela maioria dos servidores da web. O primeiro hit é do Netscape 4.04, o segundo de alguma versão do robô do MSIE 4.0, enquanto três a cinco são novamente do Netscape 4.04. (Observe que o MSIECrawler recebeu uma resposta 304, o que significa que, se usado, o cabeçalho If-modified-since).

Um log do servidor pode ser útil ao depurar aplicativos e scripts ou a configuração do servidor. Ele também pode ser executado por meio de um analisador de log, que pode criar vários tipos de relatórios de uso. Deve-se, no entanto, estar ciente de que esses relatórios não são 100% precisos devido ao uso de caches .

Um exemplo de cliente HTTP
Apenas para ilustrar, caso alguns estejam interessados, aqui está um simples cliente HTTP escrito como uma função Python que usa um nome de host e um caminho como parâmetros e emite uma solicitação GET, imprimindo os resultados retornados. (Isso pode ser ainda mais simples usando a biblioteca de URLs do Python, mas isso tornaria o exemplo inútil).

# Simple Python function that issues an HTTP request

from socket import *

def http_req(server, path):

   # Creating a socket to connect and read from
   s=socket(AF_INET,SOCK_STREAM)

   # Finding server address (assuming port 80)
   adr=(gethostbyname(server),80)

   # Connecting to server
   s.connect(adr)

   # Sending request
   s.send("GET "+path+" HTTP/1.0\n\n")

   # Printing response
   resp=s.recv(1024)
   while resp!="":
print resp
resp=s.recv(1024)
Aqui está a entrada de log do servidor resultante dessa chamada:

http_req("birk105.studby.uio.no","/")
birk105.studby.uio.no - - [26 / Jan / 1998: 12: 01: 51 +0100] "GET / HTTP / 1.0" 200 2272 - -
Os "- -" s no final são os campos do referenciador e do agente do usuário, que estão vazios porque a solicitação não continha essa informação.

Autenticação

Um servidor pode ser configurado para impedir o acesso a determinadas URLs, a menos que o usuário possa confirmar sua identidade. Isso geralmente é feito com uma combinação de nome de usuário / senha especificada na configuração, mas também há outros métodos.

Quando essa página é solicitada, o servidor geralmente retorna um código de status "401 Não autorizado", conforme mencionado acima. O navegador geralmente solicita ao usuário um nome de usuário e senha, que o usuário fornece (se for conhecido!). O navegador então tenta novamente, desta vez adicionando um cabeçalho "Autorização" com o nome de usuário e senha como o valor.

Se isso for aceito pelo servidor, o recurso é retornado exatamente como em uma solicitação comum. Caso contrário, o servidor responde novamente com um código de status 401.

Extensões HTML do lado do servidor

Alguns servidores, como os servidores Roxen e MetaHTML, permitem que os usuários incorporem comandos não HTML em seus arquivos HTML. Esses comandos são processados ​​quando o arquivo é solicitado e gera o HTML que é enviado ao cliente. Isso pode ser usado para adaptar o conteúdo da página e / ou acessar um banco de dados para entregar o conteúdo a partir dele.

O que essas linguagens têm em comum é que elas estão vinculadas a um único servidor e produzem uma combinação de cabeçalhos HTTP comuns e conteúdo HTML como saída.
Isso é importante porque significa que o cliente não percebe o que está acontecendo e, portanto, pode usar qualquer navegador.

Autoria / manutenção: extensões HTTP para isso
O HTTP / 1.0 definiu apenas os métodos GET, HEAD e POST e, para a navegação normal, isso é suficiente. No entanto, pode-se querer usar HTTP para editar e manter arquivos diretamente no servidor, em vez de ter que passar por um servidor FTP como é comum hoje em dia. O HTTP / 1.1 adiciona vários novos métodos para isso.
Esses são:
PUT
PUT carrega um novo resource (arquivo) para o servidor sob o URL fornecido. Exatamente o que acontece no servidor não é definido pela especificação HTTP / 1.1, mas programas de autoria como o Netscape Composer usam PUT para fazer upload de um arquivo para o servidor da Web e armazená-lo lá. As solicitações PUT não devem ser armazenadas em cache.
DELETE
Bem, é óbvio, não é? O método DELETE solicita que o servidor exclua o recurso identificado pelo URL. Nos sistemas UNIX, isso pode falhar se o servidor não puder excluir o arquivo pelo sistema de arquivos.

META HTTP-EQUIV
Nem todos os servidores da Web são criados de maneira que seja fácil definir, digamos, o campo de Head Expires ou algum outro campo de cabeçalho que você queira definir para um arquivo específico. Existe uma maneira de contornar esse problema. Em HTML, há um elemento chamado META que pode ser usado para definir campos de cabeçalho HTTP. Era realmente para ser analisado pelo servidor web e inserido nos cabeçalhos de resposta, mas poucos servidores realmente fazem isso, então os navegadores começaram a implementá-lo. Não é suportado em todos os navegadores, mas ainda pode ser de alguma ajuda.
O uso é basicamente este: coloque-o no elemento HEAD do arquivo HTML e faça com que ele fique assim:
<META HTTP-EQUIV="header field name" CONTENT="field value">
O campo de cabeçalho do host
Muitos hotéis da Web permitem que uma única máquina física sirva o que o usuário se parece com vários servidores diferentes. Por exemplo, http://www.foo.com/, http://www.bar.com/ e http://www.baz.com/ podem muito bem ser servidos no mesmo servidor web. Ainda assim, o usuário visualizaria páginas diferentes acessando cada uma das URLs diferentes. Para permitir isso, era necessária uma extensão para o protocolo HTTP para permitir que o servidor da Web soubesse qual desses diferentes servidores da web o usuário desejava acessar.

A solução é o campo de cabeçalho do host. Quando o usuário solicitar o site http://www.bar.com/, o servidor da Web receberá um cabeçalho definido como "Host: www.bar.com" e, assim, saberá qual página principal deve ser entregue. Ele também geralmente cria logs separados para os diferentes servidores virtuais.

Respostas para algumas perguntas comuns

Posso impedir que pessoas vejam minha fonte de HTML?

Não. Depois de permitir que as pessoas enviem uma solicitação HTTP que recupere seu documento, elas podem fazer o que quiserem com ele. Nenhuma tag HTML pode parar isso porque é possível usar um programa em Python como o que eu incluí acima e deixá-lo salvar o arquivo em HTML sem nem mesmo olhar para ele. Tampouco essa tag é reconhecida pelos navegadores.

Algumas pessoas tentam ofuscar o HTML, colocando toda a marcação em uma única linha, mas isso é facilmente corrigido, executando o HTML através de uma impressora bonita.

Existem programas que podem embaralhar seu código, tornando difícil (não impossível) ler. Novamente, isso não impedirá que alguém visualize seu código.

Em suma: desista. Não há como proteger as informações em seu HTML e não há motivo para tentar, a menos que você coloque informações vitais em controles de forma oculta, e você não deve fazer isso de qualquer maneira.

Posso impedir que pessoas roubem minhas imagens?
A resposta é a mesma para isso, pois é para HTML: você não pode fazer isso. Você pode dar uma marca d'água e provar que eles pertencem a você e inserir comentários que digam isso em texto não criptografado, mas isso ainda não impede que as pessoas façam uma solicitação HTTP e salvem a imagem.

Como posso passar um parâmetro para uma página da web?

Se a página da web é um arquivo HTML simples: esqueça. Os arquivos HTML são exibidos apenas e nada mais é feito com eles, então o conceito de um parâmetro simplesmente não se aplica.
O que você pode fazer é usar o script do lado do servidor da maneira descrita em outro lugar neste documento.

Como posso evitar que os navegadores armazenem minha página / script em cache?

Isso é feito configurando os cabeçalhos HTTP corretos. Se o cabeçalho Expiration for definido para uma data / hora no passado, a saída da solicitação não será armazenada em cache. (Observe que o HTTP exige que os navegadores mantenham o resultado no histórico do navegador, para que voltar a uma página não armazenada em cache não cause uma nova solicitação.)

O tempo de expiração pode ser definido com um script de servidor ou possivelmente configurando o servidor corretamente.

Comentários

Mais visitadas

Usando GPU para Brute-Force com HashCat

Ataque Evil Twin

XSS - Cross-site scripting

Man-in-the-Middle e MITMf - DNS Spoofing e suas defesas

Mitmproxy 1 - Conhecendo

Ataque pelo servidor - Metasploit - Nexpose