mirror of
https://github.com/discourse/discourse.git
synced 2024-11-28 02:03:45 +08:00
d9a02d1336
This reverts commit20780a1eee
. * SECURITY: re-adds accidentally reverted commit: 03d26cd6: ensure embed_url contains valid http(s) uri * when the merge commite62a85cf
was reverted, git chose the2660c2e2
parent to land on instead of the03d26cd6
parent (which contains security fixes)
117 lines
2.6 KiB
Ruby
117 lines
2.6 KiB
Ruby
# frozen_string_literal: true
|
|
class ApplicationRequest < ActiveRecord::Base
|
|
|
|
enum req_type: %i(http_total
|
|
http_2xx
|
|
http_background
|
|
http_3xx
|
|
http_4xx
|
|
http_5xx
|
|
page_view_crawler
|
|
page_view_logged_in
|
|
page_view_anon
|
|
page_view_logged_in_mobile
|
|
page_view_anon_mobile)
|
|
|
|
include CachedCounting
|
|
|
|
def self.disable
|
|
@disabled = true
|
|
end
|
|
|
|
def self.enable
|
|
@disabled = false
|
|
end
|
|
|
|
def self.increment!(type, opts = nil)
|
|
return if @disabled
|
|
perform_increment!(redis_key(type), opts)
|
|
end
|
|
|
|
def self.write_cache!(date = nil)
|
|
if date.nil?
|
|
write_cache!(Time.now.utc)
|
|
write_cache!(Time.now.utc.yesterday)
|
|
return
|
|
end
|
|
|
|
self.last_flush = Time.now.utc
|
|
|
|
date = date.to_date
|
|
|
|
req_types.each do |req_type, _|
|
|
val = get_and_reset(redis_key(req_type, date))
|
|
|
|
next if val == 0
|
|
|
|
id = req_id(date, req_type)
|
|
where(id: id).update_all(["count = count + ?", val])
|
|
end
|
|
rescue Redis::CommandError => e
|
|
raise unless e.message =~ /READONLY/
|
|
nil
|
|
end
|
|
|
|
def self.clear_cache!(date = nil)
|
|
if date.nil?
|
|
clear_cache!(Time.now.utc)
|
|
clear_cache!(Time.now.utc.yesterday)
|
|
return
|
|
end
|
|
|
|
req_types.each do |req_type, _|
|
|
key = redis_key(req_type, date)
|
|
Discourse.redis.del key
|
|
end
|
|
end
|
|
|
|
protected
|
|
|
|
def self.req_id(date, req_type, retries = 0)
|
|
|
|
req_type_id = req_types[req_type]
|
|
|
|
# a poor man's upsert
|
|
id = where(date: date, req_type: req_type_id).pluck_first(:id)
|
|
id ||= create!(date: date, req_type: req_type_id, count: 0).id
|
|
|
|
rescue # primary key violation
|
|
if retries == 0
|
|
req_id(date, req_type, 1)
|
|
else
|
|
raise
|
|
end
|
|
end
|
|
|
|
def self.redis_key(req_type, time = Time.now.utc)
|
|
"app_req_#{req_type}#{time.strftime('%Y%m%d')}"
|
|
end
|
|
|
|
def self.stats
|
|
s = HashWithIndifferentAccess.new({})
|
|
|
|
self.req_types.each do |key, i|
|
|
query = self.where(req_type: i)
|
|
s["#{key}_total"] = query.sum(:count)
|
|
s["#{key}_30_days"] = query.where("date > ?", 30.days.ago).sum(:count)
|
|
s["#{key}_7_days"] = query.where("date > ?", 7.days.ago).sum(:count)
|
|
end
|
|
|
|
s
|
|
end
|
|
end
|
|
|
|
# == Schema Information
|
|
#
|
|
# Table name: application_requests
|
|
#
|
|
# id :integer not null, primary key
|
|
# date :date not null
|
|
# req_type :integer not null
|
|
# count :integer default(0), not null
|
|
#
|
|
# Indexes
|
|
#
|
|
# index_application_requests_on_date_and_req_type (date,req_type) UNIQUE
|
|
#
|