[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