class Stoor::TransformContent

Attributes

app[R]
content_type[R]
headers[R]
pass_condition[R]
regexp[R]
request[R]
status[R]

Public Class Methods

new(app, options) click to toggle source
# File lib/stoor/transform_content.rb, line 10
def initialize(app, options)
  @app            = app
  @regexp         = options[:regexp]
  @before         = options[:before]
  @after          = options[:after]
  @content_type   = options[:content_type] || 'text/html'
  @pass_condition = options[:pass_condition] || ->(env) { false }
end

Public Instance Methods

call(env) click to toggle source
# File lib/stoor/transform_content.rb, line 19
def call(env)
  @status, @headers, response = @app.call(env)
  @request = Rack::Request.new(env)

  if pass_condition.call(request)
    if request.logger
      request.logger.info "Skipping -- because pass condition met"
    end
  else
    @headers = HeaderHash.new(@headers)
    if has_body && not_encoded && headers['content-type'] && headers['content-type'].index(content_type)
      content = Array(response).join('')
      if match_data = content.match(regexp)
        new_body = interpolate(match_data)
        headers['Content-Length'] = new_body.bytesize.to_s
        return [status, headers, [new_body]]
      end
    end
  end

  [status, headers, response]
end

Private Instance Methods

after() click to toggle source
# File lib/stoor/transform_content.rb, line 75
def after
  freshen(@after)
end
before() click to toggle source
# File lib/stoor/transform_content.rb, line 71
def before
  freshen(@before)
end
freshen(e) click to toggle source
# File lib/stoor/transform_content.rb, line 79
def freshen(e)
  if e.respond_to? :call
    e.call(request)
  else
    e.to_s
  end
end
has_body() click to toggle source
# File lib/stoor/transform_content.rb, line 44
def has_body
  !STATUS_WITH_NO_ENTITY_BODY.include?(status)
end
interpolate(match_data) click to toggle source
# File lib/stoor/transform_content.rb, line 52
def interpolate(match_data)
  # regexp: /<body>/
  #   result: before<body>after
  # regexp: /(<div>)(.*?)(<\/div)
  #   result: <div>beforezzzafter</div>
  "".tap do |s|
    s << match_data.pre_match
    if match_data.size == 1
      s << before + match_data[0] + after
    elsif match_data.size == 4
      s << match_data[1] + before + match_data[2] + after + match_data[3]
    else
      # Might just set the result to content?
      raise "Unexpected number of captures in #{match_data.regexp}"
    end
    s << match_data.post_match
  end
end
not_encoded() click to toggle source
# File lib/stoor/transform_content.rb, line 48
def not_encoded
  !headers['transfer-encoding']
end