[Rio-pm] Lendo conteúdo de página remota

Marcos Machado listas em istf.com.br
Quarta Junho 4 10:34:43 PDT 2008


Eden,

Se você é um fã do Mechanize, me desculpe, mas para o que ele pediu isso 
é overkill. Se você pretende levar em consideração qualquer argumentação 
de simplicidade de solução, ok, vamos discutir.

Eden Cardim escreveu:
  > Ele pediu pra ler o conteúdo do arquivo status, que é bem diferente do
> que verificar o status da requisição. Além disso, a tua solução não

Niguém falou em status da requisição (acredito que estejamos falando de 
200, 304, 404, 500 etc, certo?) mas sim de um status particular 
retornado pela aplicação (por exemplo corfavorita=azul), que pode ser 
justamente apenas uma string simples.

Nesse caso o tal sistema de status apenas se aproveita de um servidor 
web que já está em operação. Se não fosse o caso, eu iria sugerir a 
abertura de um socket do lado servidor para receber a requisição do cliente.

A sugestão do Mechanize parece ter sido influenciada pelo fato do 
servidor estar ouvindo na porta 80. Mas dependendo do caso, basta tirar 
o Content-type do início da resposta e podemos voltar a uma solução 
socket simples.

Ou você iria sugerir que ele instalasse o Apache do outro lado para usar 
o Mechanize do lado de cá? Eu acho que estamos nos aprofundando demais 
em uma sugestão sem conhecer a real necessidade.


> verifica o status da requisição, ela só despeja o conteúdo da resposta
> do servidor.

Claro, a parte do meu sistema que trata esse conteúdo não é do interesse 
da lista. Isso acontece quando enviamos "exemplos básicos" que poderão 
ser incrementados de acordo com a necessidade.


> Isso é o que eu chamaria de "fake kiss", sua solução presume que as
> condições são ideais: que o socket não vai falhar, que o servidor
> existe, que ele está "vivo", que ele não vai redirecionar, etc...

 > Quando alguma adversidade aparecer, se esse script estiver localizado
 > no contexto de um sistema maior, vai ser difícil e caro localizar a
 > raíz do erro.

Quando quaisquer desses problemas levantados aparecerem, o fato de abrir 
um socket ou usar o Mechanize não me parece fazer nenhuma diferença. Ou 
o Mechanize utiliza alguma magia negra para se conectar em um servidor 
que não existe?

A parte de conexão dele é construída sobre o LWP que usa IO::Socket 
(sim, eu acabei de checar!) só acrescentando uma enorme camada de opções 
que podem ou não serem úteis.

Minha "solução" (se é que podemos chamá-la assim, pois não passa de uma 
sugestão simples) está funcionando em mais de 50 sistemas diferentes, em 
um contexto bem grande, sob as mais adversas condições de rede, e todos 
os problemas dessa natureza são tratados de forma bem elegante.

Quer ver um exemplo que me deu dor de cabeça? Sabe aqueles \r\n\r\n do 
final da requisição GET? Pois é, se usarmos só um \n funciona 
maravilhosamente bem para a maioria dos servidores web. Só que em alguns 
ambientes, que estão atrás de certos tipos de proxy transparente, essa 
requisição estava dando timeout.

Cerca de uma hora foi o tempo que levei para descobrir (via comparação 
byte a byte de um dump da conexão) qual a diferença do meu socket para 
uma requisição do wget.

O Mechanize resolveria? Sim, resolveria. Mas essa questão não é 
resolvida por ele e sim pelo LWP, neste trecho, que está escrevendo no 
socket:

<code>
print $sock join("\015\012" =>
	"GET $path HTTP/1.0",
	"Host: $netloc",
	"User-Agent: lwp-trivial/$VERSION",
	"", "");
</code>

Isto resolvido, voltei para casa feliz, já que só precisei atualizar um 
script ao invés de instalar o Mechanize e seus pré-requisitos em 50 
servidores (alguns deles com sérias restrições de espaço, memória e 
processamento).

Mas, como já disse, não temos os pré-requisitos da solução, motivo pelo 
qual prefiro sugerir por baixo e ir crescendo só o necessário.

[]s, MM


Mais detalhes sobre a lista de discussão Rio-pm