twisted, http headers

Nhac. Não costumava usar o twisted pra quase nada. Normalmente, fazia tudo na mão ou usava asyncore com asynchat nativos do python.

Nos últimos meses passei a usar twisted pra algumas coisas, e nos últimos dias precisei ler os cabeçalhos provenientes do servidor web para identificar o tipo do conteúdo fornecido na resposta (content-type), usando getPage.

Descobri duas coisas:

  1. o getPage simplesmente não fornece os cabeçalhos (twisted 8.1.0)
  2. empresas fazem oferta de emprego nos cabeçalhos http de sites

O primeiro item acima foi resolvido com um hack usando o próprio código do twisted, e umas pequenas modificações. Basicamente, re-rescrevi apenas um método do HTTPClientFactory usado pelo getPage, e sobrescrevi no próprio módulo client do twisted. Uma alternativa seria copiar o código do getPage e fazê-lo usar o novo factory, mas teria que escrever muito.

Apenas um detalhe, é que depois disso feito, o comportamento do programa inteiro se torna diferente quando o getPage for chamado, e os callbacks dele retornam um tuple ao invés de uma string com o conteúdo fornecido pelo web server.

#!/usr/bin/env python
# coding: utf-8
# 20090118 - AF

from twisted.web import client
from twisted.internet import reactor

class _HTTPClientFactory(client.HTTPClientFactory):
    def page(self, page):
        if self.waiting:
            self.waiting = 0
            self.deferred.callback((self.response_headers, page))

def callback(response):
    headers, contents = response
    print headers
    reactor.stop()

if __name__ == '__main__':
    client.HTTPClientFactory = _HTTPClientFactory
    deferred = client.getPage('https://fiorix.wordpress.com')
    deferred.addCallback(callback)
    reactor.run()

Ao executar o programa, fiquei impressionado não por ele ter funcionado, mas sim pelo conteúdo nos cabeçalhos http do wordpress.com:

$ python headers.py
{‘x-nananana’: [‘Batcache’], ‘vary’: [‘Cookie’], ‘x-hacker’: [“If you’re reading this, you should visit automattic.com/jobs and apply to join the fun, mention this header.”], ‘last-modified’: [‘Sun, 18 Jan 2009 17:38:11 +0000’], ‘connection’: [‘close’], ‘cache-control’: [‘max-age=300, must-revalidate’], ‘date’: [‘Sun, 18 Jan 2009 17:38:11 GMT’], ‘server’: [‘nginx’], ‘content-type’: [‘text/html; charset=UTF-8’], ‘x-pingback’: [‘https://fiorix.wordpress.com/xmlrpc.php’%5D}

Mandaram muito bem.