lib/puma/app/status.rb in piesync-puma-3.12.6.1 vs lib/puma/app/status.rb in piesync-puma-5.4.0.1

- old
+ new

@@ -1,74 +1,93 @@ +# frozen_string_literal: true +require 'puma/json_serialization' + module Puma module App + # Check out {#call}'s source code to see what actions this web application + # can respond to. class Status - def initialize(cli) - @cli = cli - @auth_token = nil - end OK_STATUS = '{ "status": "ok" }'.freeze - attr_accessor :auth_token - - def authenticate(env) - return true unless @auth_token - env['QUERY_STRING'].to_s.split(/&;/).include?("token=#{@auth_token}") + # @param launcher [::Puma::Launcher] + # @param token [String, nil] the token used for authentication + # + def initialize(launcher, token = nil) + @launcher = launcher + @auth_token = token end - def rack_response(status, body, content_type='application/json') - headers = { - 'Content-Type' => content_type, - 'Content-Length' => body.bytesize.to_s - } - - [status, headers, [body]] - end - + # most commands call methods in `::Puma::Launcher` based on command in + # `env['PATH_INFO']` def call(env) unless authenticate(env) return rack_response(403, 'Invalid auth token', 'text/plain') end - case env['PATH_INFO'] - when /\/stop$/ - @cli.stop - return rack_response(200, OK_STATUS) + # resp_type is processed by following case statement, return + # is a number (status) or a string used as the body of a 200 response + resp_type = + case env['PATH_INFO'][/\/([^\/]+)$/, 1] + when 'stop' + @launcher.stop ; 200 - when /\/halt$/ - @cli.halt - return rack_response(200, OK_STATUS) + when 'halt' + @launcher.halt ; 200 - when /\/restart$/ - @cli.restart - return rack_response(200, OK_STATUS) + when 'restart' + @launcher.restart ; 200 - when /\/phased-restart$/ - if !@cli.phased_restart - return rack_response(404, '{ "error": "phased restart not available" }') - else - return rack_response(200, OK_STATUS) - end + when 'phased-restart' + @launcher.phased_restart ? 200 : 404 - when /\/reload-worker-directory$/ - if !@cli.send(:reload_worker_directory) - return rack_response(404, '{ "error": "reload_worker_directory not available" }') + when 'reload-worker-directory' + @launcher.send(:reload_worker_directory) ? 200 : 404 + + when 'gc' + GC.start ; 200 + + when 'gc-stats' + Puma::JSONSerialization.generate GC.stat + + when 'stats' + Puma::JSONSerialization.generate @launcher.stats + + when 'thread-backtraces' + backtraces = [] + @launcher.thread_status do |name, backtrace| + backtraces << { name: name, backtrace: backtrace } + end + Puma::JSONSerialization.generate backtraces + else - return rack_response(200, OK_STATUS) + return rack_response(404, "Unsupported action", 'text/plain') end - when /\/gc$/ - GC.start - return rack_response(200, OK_STATUS) + case resp_type + when String + rack_response 200, resp_type + when 200 + rack_response 200, OK_STATUS + when 404 + str = env['PATH_INFO'][/\/(\S+)/, 1].tr '-', '_' + rack_response 404, "{ \"error\": \"#{str} not available\" }" + end + end - when /\/gc-stats$/ - json = "{" + GC.stat.map { |k, v| "\"#{k}\": #{v}" }.join(",") + "}" - return rack_response(200, json) + private - when /\/stats$/ - return rack_response(200, @cli.stats) - else - rack_response 404, "Unsupported action", 'text/plain' - end + def authenticate(env) + return true unless @auth_token + env['QUERY_STRING'].to_s.split(/&;/).include?("token=#{@auth_token}") + end + + def rack_response(status, body, content_type='application/json') + headers = { + 'Content-Type' => content_type, + 'Content-Length' => body.bytesize.to_s + } + + [status, headers, [body]] end end end end