Files
redux-scraper/app/models/http_log_entry.rb
Dylan Knutson 572c61cebb add proxies
2025-07-23 04:51:44 +00:00

131 lines
3.0 KiB
Ruby

# typed: strict
class HttpLogEntry < ReduxApplicationRecord
include ImmutableModel
before_destroy { raise ActiveRecord::ReadOnlyRecord }
enum :verb, %i[get post], prefix: true
enum :performed_by,
%i[
direct
legacy
proxy-1
dedipath-1
direct-gdl
serverhost-1
airvpn-1-netherlands
airvpn-2-san-jose
],
prefix: true
belongs_to :response,
foreign_key: :response_sha256,
class_name: "::BlobFile",
autosave: true
belongs_to :request_headers, class_name: "::HttpLogEntryHeader"
belongs_to :response_headers, class_name: "::HttpLogEntryHeader"
validates :response_sha256, length: { is: 32 }
belongs_to :caused_by_entry,
class_name: "::HttpLogEntry",
foreign_key: :caused_by_id,
optional: true
has_many :triggered_entries,
class_name: "::HttpLogEntry",
foreign_key: :caused_by_id
validates_presence_of(
:uri_scheme,
:uri_host,
:uri_path,
:verb,
:performed_by,
:status_code,
:response_time_ms,
:content_type,
:requested_at,
)
sig do
params(uri: T.any(String, Addressable::URI)).returns(
T.nilable(HttpLogEntry),
)
end
def self.find_by_uri_host_path(uri)
uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI)
where(uri_host: uri.host, uri_path: uri.path).order(
requested_at: :desc,
).first
end
sig do
params(uri: T.any(String, Addressable::URI)).returns(
T.nilable(HttpLogEntry),
)
end
def self.find_by_uri(uri)
find_all_by_uri(uri).first
end
sig do
params(uri: T.any(String, Addressable::URI)).returns(
::ActiveRecord::Relation,
)
end
def self.find_all_by_uri(uri)
if uri.is_a?(String) &&
%w[https:// http:// //].none? { |prefix| uri.start_with?(prefix) }
uri = "//#{uri}"
end
uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI)
where(
uri_host: uri.host,
uri_path: uri.path,
uri_query: uri.query,
uri_hash: uri.fragment,
).order(requested_at: :desc)
end
sig { returns(T.nilable(Integer)) }
def response_size
response&.size_bytes
end
sig { returns(T.nilable(String)) }
def response_bytes
response&.content_bytes
end
sig { params(uri: T.any(String, Addressable::URI)).void }
def uri=(uri)
uri = Addressable::URI.parse(uri) if uri.is_a?(String)
self.uri_scheme = uri.scheme
self.uri_host = uri.host
self.uri_path = uri.path
self.uri_query = uri.query
self.uri_hash = uri.fragment
end
sig { returns(Addressable::URI) }
def uri
Addressable::URI.parse(uri_str)
end
sig { returns(String) }
def uri_str
"#{uri_scheme}://#{uri_host}#{uri_str_without_host}"
end
sig { returns(String) }
def uri_str_without_host
str = ""
str += "#{uri_path}"
str += "?#{uri_query}" if uri_query
str += "\##{uri_hash}" if uri_hash
str
end
end