使用 open-uri 指定默认字符集,但如果给定则使用服务器提供的字符集

Specify default charset using open-uri but use server-provided charset if given

使用 Ruby 的 open-uri 中的 open(),我想从不受我控制的任意服务器获取文件。服务器可以为文件指定内容类型,例如text/calendar; charset=utf-8text/calendar; charset=ISO-8859-1,在这种情况下,我很高兴 open() 会相信该字符集是服务器声明的任何内容。但是,如果服务器没有指定字符集,那么 open() 似乎假设字符集是 "ASCII-8BIT." 我想 open() 而不是假设字符集是 "UTF-8" (当没有指定字符集时),因为 text/calendar,即 "iCal files," 通常应编码为 "UTF-8."

我强调仅在未指定字符集时假设字符集,因为我仍然想尊重服务器的决定,即有选择地以他们喜欢的任何字符集提供文件。

我尝试了 open('http://my-test-uri.test', 'r:UTF-8'),但它无条件地覆盖了字符集,即使服务器指定了不同的字符集,如 "ISO-8859-1."

OpenURI::Meta#charset 接受一个将 return 字符集的块,仅当服务器未指定字符集时。

使用该信息,我们可以将 StringIO return 由 open 编辑的编码设置为与它相同的编码(冗余)或我们的默认编码:

open('http://localhost:3333').tap do |io|
  charset = io.charset { 'utf-8' }
  io.set_encoding(charset)
end