#!/usr/bin/env ruby require 'yaml' require 'oj' require 'faastruby-rpc' require 'base64' require 'faastruby/server' require 'sinatra' require 'sinatra/multi_route' require 'colorize' FaaStRuby::EventHub.listen_for_events! set :port, 3000 set :bind, '0.0.0.0' case ARGV.shift when '-p' set :port, ARGV.shift when '-b', '-o' set :bind, ARGV.shift end set :server, %w[puma] set :show_exceptions, true register Sinatra::MultiRoute route :get, :post, :put, :patch, :delete, '/:workspace_name/:function_name' do path = "#{params[:workspace_name]}/#{params[:function_name]}" headers = env.select { |key, value| key.include?('HTTP_') || ['CONTENT_TYPE', 'CONTENT_LENGTH', 'REMOTE_ADDR', 'REQUEST_METHOD', 'QUERY_STRING'].include?(key) } if headers.has_key?("HTTP_FAASTRUBY_RPC") body = nil rpc_args = parse_body(request.body.read, headers['CONTENT_TYPE'], request.request_method) || [] else body = parse_body(request.body.read, headers['CONTENT_TYPE'], request.request_method) rpc_args = [] end query_params = parse_query(request.query_string) context = set_context(params[:workspace_name], params[:function_name]) event = FaaStRuby::Event.new(body, query_params, headers, context) response = FaaStRuby::Runner.new.call(params[:workspace_name], params[:function_name], event, rpc_args) status response.status headers response.headers if response.binary? response_body = Base64.urlsafe_decode64(response.body) else response_body = response.body end puts "[#{path}] #=> status=#{response.status} body=#{response_body.inspect} headers=#{Oj.dump response.headers}".light_blue body response_body end def parse_body(body, content_type, method) return nil if method == 'GET' return {} if body.nil? && method != 'GET' return Oj.load(body) if content_type == 'application/json' return body end def set_context(workspace_name, function_name) return nil unless File.file?('context.yml') yaml = YAML.load(File.read('context.yml')) return nil unless yaml.has_key?(workspace_name) yaml[workspace_name][function_name] end def parse_query(query_string) hash = {} query_string.split('&').each do |param| key, value = param.split('=') hash[key] = value end hash end def self.run? true end