مراية لـ
https://github.com/postalserver/postal.git
تم المزامنة 2026-01-19 06:09:47 +00:00
* Update mysql2 query call to cast booleans * Treat messages:held field as boolean * Treat messages:inspected field as boolean * Treat messages:spam field as boolean * Treat messages:threat field as boolean * Treat messages:bounce field as boolean * Treat messages:received_with_ssl field as boolean * Treat deliveries:sent_with_ssl field as boolean
134 أسطر
4.3 KiB
Ruby
134 أسطر
4.3 KiB
Ruby
module Postal
|
||
class HTTPSender < Sender
|
||
|
||
def initialize(endpoint, options = {})
|
||
@endpoint = endpoint
|
||
@options = options
|
||
@log_id = Nifty::Utils::RandomString.generate(length: 8).upcase
|
||
end
|
||
|
||
def send_message(message)
|
||
start_time = Time.now
|
||
result = SendResult.new
|
||
result.log_id = @log_id
|
||
|
||
request_options = {}
|
||
request_options[:sign] = true
|
||
request_options[:timeout] = @endpoint.timeout || 5
|
||
case @endpoint.encoding
|
||
when "BodyAsJSON"
|
||
request_options[:json] = parameters(message, flat: false).to_json
|
||
when "FormData"
|
||
request_options[:params] = parameters(message, flat: true)
|
||
end
|
||
|
||
log "Sending request to #{@endpoint.url}"
|
||
response = Postal::HTTP.post(@endpoint.url, request_options)
|
||
result.secure = !!response[:secure]
|
||
result.details = "Received a #{response[:code]} from #{@endpoint.url}"
|
||
log " -> Received: #{response[:code]}"
|
||
if response[:body]
|
||
log " -> Body: #{response[:body][0, 255]}"
|
||
result.output = response[:body].to_s[0, 500].strip
|
||
end
|
||
if response[:code] >= 200 && response[:code] < 300
|
||
# This is considered a success
|
||
result.type = "Sent"
|
||
elsif response[:code] >= 500 && response[:code] < 600
|
||
# This is temporary. They might fix their server so it should soft fail.
|
||
result.type = "SoftFail"
|
||
result.retry = true
|
||
elsif response[:code] < 0
|
||
# Connection/SSL etc... errors
|
||
result.type = "SoftFail"
|
||
result.retry = true
|
||
result.connect_error = true
|
||
elsif response[:code] == 429
|
||
# Rate limit exceeded, treat as a hard fail and don't send bounces
|
||
result.type = "HardFail"
|
||
result.suppress_bounce = true
|
||
else
|
||
# This is permanent. Any other error isn't cool with us.
|
||
result.type = "HardFail"
|
||
end
|
||
result.time = (Time.now - start_time).to_f.round(2)
|
||
result
|
||
end
|
||
|
||
private
|
||
|
||
def log(text)
|
||
Postal.logger_for(:http_sender).info("[#{@log_id}] #{text}")
|
||
end
|
||
|
||
def parameters(message, options = {})
|
||
case @endpoint.format
|
||
when "Hash"
|
||
hash = {
|
||
id: message.id,
|
||
rcpt_to: message.rcpt_to,
|
||
mail_from: message.mail_from,
|
||
token: message.token,
|
||
subject: message.subject,
|
||
message_id: message.message_id,
|
||
timestamp: message.timestamp.to_f,
|
||
size: message.size,
|
||
spam_status: message.spam_status,
|
||
bounce: message.bounce,
|
||
received_with_ssl: message.received_with_ssl,
|
||
to: message.headers["to"]&.last,
|
||
cc: message.headers["cc"]&.last,
|
||
from: message.headers["from"]&.last,
|
||
date: message.headers["date"]&.last,
|
||
in_reply_to: message.headers["in-reply-to"]&.last,
|
||
references: message.headers["references"]&.last,
|
||
html_body: message.html_body,
|
||
attachment_quantity: message.attachments.size,
|
||
auto_submitted: message.headers["auto-submitted"]&.last,
|
||
reply_to: message.headers["reply-to"]
|
||
}
|
||
|
||
if @endpoint.strip_replies
|
||
hash[:plain_body], hash[:replies_from_plain_body] = Postal::ReplySeparator.separate(message.plain_body)
|
||
else
|
||
hash[:plain_body] = message.plain_body
|
||
end
|
||
|
||
if @endpoint.include_attachments?
|
||
if options[:flat]
|
||
message.attachments.each_with_index do |a, i|
|
||
hash["attachments[#{i}][filename]"] = a.filename
|
||
hash["attachments[#{i}][content_type]"] = a.content_type
|
||
hash["attachments[#{i}][size]"] = a.body.to_s.bytesize.to_s
|
||
hash["attachments[#{i}][data]"] = Base64.encode64(a.body.to_s)
|
||
end
|
||
else
|
||
hash[:attachments] = message.attachments.map do |a|
|
||
{
|
||
filename: a.filename,
|
||
content_type: a.mime_type,
|
||
size: a.body.to_s.bytesize,
|
||
data: Base64.encode64(a.body.to_s)
|
||
}
|
||
end
|
||
end
|
||
end
|
||
|
||
hash
|
||
when "RawMessage"
|
||
{
|
||
id: message.id,
|
||
rcpt_to: message.rcpt_to,
|
||
mail_from: message.mail_from,
|
||
message: Base64.encode64(message.raw_message),
|
||
base64: true,
|
||
size: message.size.to_i
|
||
}
|
||
else
|
||
{}
|
||
end
|
||
end
|
||
|
||
end
|
||
end
|