Sha256: 54304bda80a4efe09c2f4ca295c627e459952be159896cfaf4e24207acfa22d5

Contents?: true

Size: 1.91 KB

Versions: 3

Compression:

Stored size: 1.91 KB

Contents

require 'proxes/services/es'
require 'net/http/persistent'
require 'singleton'
require 'rack'

module ProxES
  # A lot of code in this comes from Rack::Proxy
  class Forwarder
    include Singleton
    include ProxES::Services::ES

    attr_reader :streaming

    def backend
      @backend ||= URI(ENV['ELASTICSEARCH_URL'])
    end

    def backend=(var)
      @backend = URI(var)
    end

    def call(env)
      forward(env)
    rescue SocketError
      headers = { 'Content-Type' => 'application/json' }
      [500, headers, ['{"error":"Could not connect to Elasticsearch"}']]
    end

    def forward(env)
      source = Rack::Request.new(env)
      conn.basic_auth backend.user, backend.password
      response = conn.send(source.request_method.downcase) do |req|
        source_body = body_from(source)
        req.body = source_body if source_body
        req.url source.fullpath == '' ? URI.parse(env['REQUEST_URI']).request_uri : source.fullpath
      end
      mangle response
    end

    def mangle(response)
      headers = (response.respond_to?(:headers) && response.headers) || self.class.normalize_headers(response.to_hash)
      body    = response.body || ['']
      body    = [body] unless body.respond_to?(:each)

      # Not sure where this is coming from, but it causes timeouts on the client
      headers.delete('transfer-encoding')
      # Ensure that the content length rack middleware kicks in
      headers.delete('content-length')

      [response.status, headers, body]
    end

    def body_from(request)
      return nil if request.body.nil? || (Kernel.const_defined?('::Puma::NullIO') && request.body.is_a?(Puma::NullIO))
      request.body.read.tap { |_r| request.body.rewind }
    end

    class << self
      def normalize_headers(headers)
        mapped = headers.map do |k, v|
          [k, v.is_a?(Array) ? v.join("\n") : v]
        end
        Rack::Utils::HeaderHash.new Hash[mapped]
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
proxes-0.9.2 lib/proxes/forwarder.rb
proxes-0.9.1 lib/proxes/forwarder.rb
proxes-0.9.0 lib/proxes/forwarder.rb