Class: SanitizeUserAgentHeader

Inherits:
Object
  • Object
show all
Defined in:
lib/sanitize_user_agent_header.rb,
lib/sanitize_user_agent_header/version.rb

Overview

This middleware will ensure that the User-Agent request header is actually UTF-8, which will prevent bad things down the road. Strictly speaking, the string must be kept in an ISO encoding (single byte header limitations). But pragmatically we use this header in many places, and applying an explicit decode to it is a chore. Also, we are not violating the spec, merely “matching” the encoding of an input variable to the internal encoding of the system.

Defined Under Namespace

Classes: Railtie

Constant Summary collapse

VERSION =
"0.1.0"

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ SanitizeUserAgentHeader

Returns a new instance of SanitizeUserAgentHeader.



13
14
15
# File 'lib/sanitize_user_agent_header.rb', line 13

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Object



17
18
19
20
21
22
# File 'lib/sanitize_user_agent_header.rb', line 17

def call(env)
  if env[HTTP_USER_AGENT]
    env[HTTP_USER_AGENT] = opportunistically_convert_to_utf8(env[HTTP_USER_AGENT])
  end
  @app.call(env)
end

#opportunistically_convert_to_utf8(str) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/sanitize_user_agent_header.rb', line 25

def opportunistically_convert_to_utf8(str)
  try_encodings = %w( ISO-8859-1 CP1252 )
  try_encodings.each do |enc|
    begin
      encoded_as_utf8 = str.force_encoding(enc).encode(Encoding::UTF_8)
      return encoded_as_utf8
    rescue Encoding::UndefinedConversionError
    end
  end
  # Last resort, just strip it of everything
  str.force_encoding(Encoding::ISO8859_1)
  str.encode(Encoding::ASCII, invalid: :replace, undef: :replace, replace: '?').encode(Encoding::UTF_8)
end