Use Ruby para obtener la longitud de contenido de las URL
Pregunta
Estoy tratando de escribir un script de Ruby que obtenga algunos detalles sobre los archivos en un sitio web usando net/http
. Mi código se ve así:
require 'open-uri'
require 'net/http'
url = URI.parse asset
res = Net::HTTP.start(url.host, url.port) {|http|
http.get(asset)
}
headers = res.to_hash
p headers
Me gustaría obtener dos piezas de información de esta solicitud: la longitud total del contenido inflado y (según corresponda) la longitud del contenido desinflado.
A veces, los encabezados incluirán un content-length
Parámetro, que parece ser la longitud gzipped del contenido. También puedo aproximar el tamaño inflado del contenido usando res.body.length, pero esto no ha sido infalible por ningún tramo de la imaginación. La documentación en net/http
dice que los encabezados GZIP se eliminan de la lista automáticamente (a ayuda Yo, gracias, gracias) Así que parece que no puedo tener un manejo confiable de esta información.
Se agradece cualquier ayuda (incluidas otras gemas si lo harán más fácilmente).
Solución
¡Entiendo! El comportamiento "mágico" aquí solo ocurre si no especificas tu propio encabezado de codificación de aceptación. Código modificado de la siguiente manera:
require 'open-uri'
require 'net/http'
require 'date'
require 'zlib'
headers = { "accept-encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3" }
url = URI.parse asset
res = Net::HTTP.start(url.host, url.port) {|http|
http.get(asset, headers)
}
headers = res.to_hash
gzipped = headers['content-encoding'] && headers['content-encoding'][0] == "gzip"
content = gzipped ? Zlib::GzipReader.new(StringIO.new(res.body)).read : res.body
full_length = content.length,
compressed_length = (headers["content-length"] && headers["content-length"][0] || res.body.length),
Otros consejos
Puede intentar usar los sockets para enviar la solicitud de cabecera al servidor con IS más rápido (sin contenido) y no enviar "Aceptación de aceptación: GZIP", por lo que su respuesta no será GZIP.