call

in core/ruby2.5Action/rackapp/init.rb [24:93]


  def call(env)
    
    if File.exist? CONFIG then
      puts "Error: Cannot initialize the action more than once."
      STDOUT.flush
      return ErrorResponse.new 'Cannot initialize the action more than once.', 403
    end

    
    body = Rack::Request.new(env).body.read
    data = JSON.parse(body)['value'] || {}

    
    if data == {} then
      return ErrorResponse.new 'Missing main/no code to execute.', 500
    end

    name = data['name'] || ''           
    main = data['main'] || ''           
    code = data['code'] || ''           
    binary = data['binary'] || false    

    
    if ![name, main, code].map{|e| e.is_a? String }.inject{|a,b| a && b } then
      return ErrorResponse.new 'Invalid Parameters: failed to handle the request', 500
    end

    env = {'BUNDLE_GEMFILE' => PROGRAM_DIR + 'Gemfile'}
    if binary then
      File.write TMP_ZIP, Base64.decode64(code)
      if !unzip(TMP_ZIP, PROGRAM_DIR) then
        return ErrorResponse.new 'Invalid Binary: failed to open zip file. Please make sure you have finished $bundle package successfully.', 500
      end
      
      if File.exist?(PROGRAM_DIR + 'Gemfile') then
        if !File.directory?(PROGRAM_DIR + 'vendor/cache') then
          return ErrorResponse.new 'Invalid Binary: vendor/cache folder is not found. Please make sure you have used valid zip binary.', 200
        end
        if !system(env, "bundle install --local 2> #{ERR} 1> #{OUT}") then
          return ErrorResponse.new "Invalid Binary: failed to resolve dependencies / #{File.read(OUT)} / #{File.read(ERR)}", 500
        end
      else
        File.write env['BUNDLE_GEMFILE'], ''  
      end
      if !File.exist?(ENTRYPOINT) then
        return ErrorResponse.new 'Invalid Ruby Code: zipped actions must contain main.rb at the root.', 500
      end
    else
      
      File.write ENTRYPOINT, code
      File.write env['BUNDLE_GEMFILE'], ''  
    end

    
    if !valid_code?(ENTRYPOINT) then
      return ErrorResponse.new 'Invalid Ruby Code: failed to parse the input code', 500
    end

    
    if !system(env, "bundle exec ruby -r #{ENTRYPOINT} -e \"method(:#{main}) ? true : raise(Exception.new('Error'))\" 2> #{ERR} 1> #{OUT}") then
      return ErrorResponse.new "Invalid Ruby Code: method checking failed / #{File.read(OUT)} / #{File.read(ERR)}", 500
    end

    
    File.write CONFIG, {:main=>main, :name=>name}.to_json

    
    SuccessResponse.new({'OK'=>true})
  end