class Netfira::WebConnect::RequestFilter
Public Class Methods
new(app)
click to toggle source
# File lib/netfira/web_connect/request_filter.rb, line 7 def initialize(app) @app = app end
Public Instance Methods
call(env)
click to toggle source
# File lib/netfira/web_connect/request_filter.rb, line 11 def call(env) begin if (env['CONTENT_TYPE'] || env['HTTP_CONTENT_TYPE']) == 'application/x-netfira-webconnect-packed' begin unpack env rescue Zlib::GzipFile::Error, Zlib::DataError => e return [400, {}, {errorCode: 19, errorMessage: "Decompression error: #{e.message}"}] end end env['WC_ACCEPTABLE_REQUEST_TYPES'] = %w[packed unpacked] @app.call env rescue Exception => error # TODO: this mirrors code in rack_app.rb. Consolidate? [ 500, {'Content-Type' => 'application/json'}, { errorCode: 1, errorMessage: 'Uncaught Exception', exception: { class: error.class.name, message: error.message, backtrace: error.backtrace } } ] end end
unpack(env)
click to toggle source
# File lib/netfira/web_connect/request_filter.rb, line 40 def unpack(env) env['original.rack.input'] = input = env['rack.input'] input = case env['CONTENT_ENCODING'] || env['HTTP_CONTENT_ENCODING'] when 'gzip' Zlib::GzipReader.new(input) when 'deflate' begin # Decompression of .Net-flavoured deflate StringIO.new(Zlib::Inflate.new(-15).inflate input.read) rescue Zlib::DataError # Decompression of regular (Ruby, PHP etc) deflate StringIO.new(Zlib::Inflate.inflate input.tap(&:rewind).read) end else input end method, path, query_string, headers, body = parse_request(input) %w[REQUEST_METHOD PATH_INFO QUERY_STRING].each{ |field| env["OUTER_#{field}"] = env[field] } env['REQUEST_METHOD'] = method env['PATH_INFO'] = path env['QUERY_STRING'] = query_string || '' headers.each do |key, value| field = key =~ /^content\b/i ? '' : 'HTTP_' field << key.upcase.gsub('-', '_') env["OUTER_#{field}"] = env[field] if env[field] env[field] = value end env['rack.input'] = StringIO.new(body || '') end
Private Instance Methods
parse_request(input)
click to toggle source
# File lib/netfira/web_connect/request_filter.rb, line 78 def parse_request(input) input.rewind body = '' headers = {} method, path, query_string = /^([A-Z]+) ([^?\s]+)(?:\?(\S*))?/.match(input.readline)[1..3] while !input.eof and (line = input.readline.chomp) != '' headers.merge! [line.split(/:\s*/, 2)].to_h end body = input.read unless input.eof [method, path, query_string, headers, body] end