Content-Type: unknown; charset=UTF-16LE
Content-Disposition: attachment; filename=report.csv
El problema está en la forma en que Mechanize parsea los datos recibidos. Decide que clase va a utilizar en función del Content Type. Para texto y html utiliza la clase WWW::Mechanize::Page, y si no sabe que utilizar, por defecto utiliza WWW::Mechanize::File.
En mi caso como no reconoce el Content-Type unknown, me devuelve un objeto de tipo WWW::Mechanize::File, a partir del cual no puedo parsear correctamente el CSV, ya que me devuelve un objeto binario sin ningún método fácil para procesarlo.
La primera solución que se me ocurrió a partir de la documentación de la clase PluggableParser es añadir unknown en la lista de Content-Type soportados por Page
agent.pluggable_parser['unknown'] = WWW::Mechanize::Page
Pero eso no vale, porque dentro de WWW::Mechanize::Page hay un chequeo adicional:
response['content-type'] =~ /^(text\/html)|(application\/xhtml\+xml)/i
Así que la solución para mi caso ha sido crearme una nueva clase que extiende a Page en la que su initialize es tan simple (y tan ñapa) como llamar a super y ignorar la excepción de content type inválido
require 'mechanize'
module WWW
class Mechanize
class Unknown < WWW::Mechanize::Page
def initialize(uri=nil, response=nil, body=nil, code=nil, mech=nil)
begin
super(uri, response, body, code)
rescue Mechanize::ContentTypeError
# Do nothing
end
end
end
end
end
Y hacer que el Content-Type unkown lo procese esta clase
agent.pluggable_parser['unknown'] = WWW::Mechanize::Unknown
Y con esto arreglado. Ya me devuelve un objeto que puedo parsear sin problema con FasterCSV.
Bastante interesante, creo que esto me ayudará en un proyecto personal que dejé hace más de un año...
ResponderEliminar