require 'sinatra' require 'json' require 'rack/accept' require 'time' use Rack::Accept NO_RESPONSES = { "en" => [ "No.", "Nope.", "Nah.", "Nuh-uh.", "Negative.", "Nay.", "Hell no.", "Not in a million years.", "Get lost.", "Not happening, buddy.", "Why don't you try asking someone else?", "Are you kidding me?", "Absolutely not, go away.", "I’m terribly sorry, but no.", "I regret to inform you that I cannot comply.", "Unfortunately, that will not be possible at this time.", "I must respectfully decline your request.", "I wish I could, but sadly I cannot.", "It would be my pleasure to help, but I must regretfully decline.", "With the greatest respect, I must say no.", "I apologize, but I must kindly refuse your request." ], "de" => ["Nein.", "Keineswegs."], "fr" => ["Non.", "Jamais."], "ja" => ["いいえ", "ダメです。"], "ru" => ["Нет", "Никак нет"], "pt" => ["Não.", "De jeito nenhum."], "es" => ["No.", "Para nada."], "pl" => ["Nie.", "W żadnym wypadku."], "fi" => ["Ei.", "Ei todellakaan."], "tr" => ["Hayır.", "Bu değil."], "he" => ["לא"], "hi" => ["नहीं", "बिलकुल नहीं"], "no" => ["Nei.", "Absolutt ikke.", "Ikke tale om."], "sv" => ["Nej.", "Inte alls."], "da" => ["Nej.", "Ikke en chance."], "it" => ["No.", "Assolutamente no."], "nl" => ["Nee.", "Absoluut niet."], "cs" => ["Ne.", "Rozhodně ne."], "ko" => ["아니요.", "절대 안 돼요."], "zh" => ["不。", "绝对不行。"] } RATE_LIMIT = { window: 60, # seconds limit: 60 # requests per IP per window } $requests = {} helpers do def client_ip request.env['HTTP_X_FORWARDED_FOR'] || request.ip end def log_to_journald(message) IO.popen(["/usr/bin/systemd-cat", "--identifier=noaas"], "w") { |io| io.puts message } rescue puts message # fallback to stdout end def log_structured(lang:, format:, status:, duration_ms:) log_entry = { timestamp: Time.now.utc.iso8601, ip: client_ip, method: request.request_method, path: request.path, user_agent: request.user_agent, language: lang, format: format, status: status, duration_ms: duration_ms } log_to_journald(JSON.generate(log_entry)) end def rate_limited? ip = client_ip now = Time.now.to_i $requests[ip] ||= [] $requests[ip].reject! { |timestamp| timestamp < now - RATE_LIMIT[:window] } if $requests[ip].size >= RATE_LIMIT[:limit] true else $requests[ip] << now false end end def preferred_language params["lang"] || request.env["HTTP_ACCEPT_LANGUAGE"].to_s.scan(/[a-z]{2}/).find do |lang| NO_RESPONSES.key?(lang) end || "en" end def no_message(lang) NO_RESPONSES[lang].sample end end before do @start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) end after do duration = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start_time) * 1000).round(2) lang = preferred_language format = request.preferred_type&.to_s || request.accept.first.to_s log_structured(lang: lang, format: format, status: response.status, duration_ms: duration) end get '/' do if rate_limited? response = [ { status: 402, message: "I'm not paid enough for this." }, { status: 418, message: "I'm just a teapot."}, { status: 429, message: "Not so fast!"} ].sample status response[:status] content_type :json return { error: response[:message] }.to_json end lang = preferred_language message = no_message(lang) if request.preferred_type.to_s == 'application/json' || request.accept.include?('application/json') content_type :json status 200 { message: message, language: lang }.to_json else content_type :html status 200 "
#{message}
" end end