- Modify AWS credentials to use 's3' instead of 'minio' for both production and development environments. - Update associated initializers, environment configurations, and sitemap generator settings. - Simplify the configuration retrieval by aligning with new standards for S3. These changes ensure consistent access to AWS S3 resources and improve maintainability by aligning with updated environment variable practices.
127 lines
3.4 KiB
Ruby
127 lines
3.4 KiB
Ruby
class SitemapsController < ApplicationController
|
||
include SitemapsHelper
|
||
before_action :set_bucket_name
|
||
|
||
def index
|
||
@sitemaps = list_sitemaps
|
||
respond_to do |format|
|
||
format.html
|
||
format.xml { render_sitemap_index }
|
||
end
|
||
rescue Aws::S3::Errors::ServiceError => e
|
||
Rails.logger.error "S3 Error: #{e.message}"
|
||
render status: :internal_server_error
|
||
end
|
||
|
||
def show
|
||
path = params[:path]
|
||
key = "sitemaps/#{path}"
|
||
|
||
Rails.logger.info "Requesting sitemap: #{path}"
|
||
|
||
begin
|
||
# 检查文件是否存在
|
||
s3_client.head_object(
|
||
bucket: @bucket_name,
|
||
key: key
|
||
)
|
||
|
||
# 生成预签名URL,设置15分钟有效期
|
||
signer = Aws::S3::Presigner.new(client: s3_client)
|
||
url = signer.presigned_url(
|
||
:get_object,
|
||
bucket: @bucket_name,
|
||
key: key,
|
||
expires_in: 15 * 60, # 15 minutes
|
||
# response_content_type: 'application/xml', # 确保正确的内容类型
|
||
response_content_disposition: "inline" # 在浏览器中直接显示
|
||
)
|
||
|
||
# 设置缓存头
|
||
response.headers["Cache-Control"] = "public, max-age=3600" # 1小时缓存
|
||
|
||
# 重定向到预签名URL
|
||
redirect_to url, allow_other_host: true, status: :found
|
||
|
||
rescue Aws::S3::Errors::NotFound
|
||
Rails.logger.error "Sitemap not found: #{path}"
|
||
render status: :not_found
|
||
rescue Aws::S3::Errors::ServiceError => e
|
||
Rails.logger.error "S3 Error: #{e.message}"
|
||
render status: :internal_server_error
|
||
end
|
||
end
|
||
|
||
# def show
|
||
# path = params[:path]
|
||
# Rails.logger.info "Sitemap: #{path}"
|
||
|
||
# begin
|
||
# response = s3_client.get_object(
|
||
# bucket: @bucket_name,
|
||
# key: "sitemaps/#{path}"
|
||
# )
|
||
|
||
# expires_in 12.hours, public: true
|
||
# content_type = response.content_type || "application/xml"
|
||
|
||
# send_data(
|
||
# response.body.read,
|
||
# filename: path,
|
||
# type: content_type,
|
||
# disposition: "inline"
|
||
# )
|
||
# rescue Aws::S3::Errors::NoSuchKey
|
||
# render status: :not_found
|
||
# rescue Aws::S3::Errors::ServiceError => e
|
||
# Rails.logger.error "S3 Error: #{e.message}"
|
||
# render status: :internal_server_error
|
||
# end
|
||
# end
|
||
|
||
private
|
||
|
||
def set_bucket_name
|
||
@bucket_name = Rails.env.production? ?
|
||
ENV.fetch("AWS_BUCKET", Rails.application.credentials.dig(:s3, :bucket)) :
|
||
ENV.fetch("AWS_DEV_BUCKET", Rails.application.credentials.dig(:s3_dev, :bucket))
|
||
end
|
||
|
||
def s3_client
|
||
@s3_client ||= Aws::S3::Client.new
|
||
end
|
||
|
||
def list_sitemaps
|
||
response = s3_client.list_objects_v2(
|
||
bucket: @bucket_name,
|
||
prefix: "sitemaps/"
|
||
)
|
||
|
||
response.contents.map do |object|
|
||
{
|
||
key: object.key.sub("sitemaps/", ""),
|
||
last_modified: object.last_modified,
|
||
size: object.size,
|
||
url: sitemap_url(object.key.sub("sitemaps/", ""))
|
||
}
|
||
end.reject { |obj| obj[:key].empty? }
|
||
end
|
||
|
||
def render_sitemap_index
|
||
base_url = "#{request.protocol}#{request.host_with_port}"
|
||
|
||
builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
||
xml.sitemapindex(xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9") do
|
||
@sitemaps.each do |sitemap|
|
||
xml.sitemap do
|
||
xml.loc "#{base_url}/sitemaps/#{sitemap[:key]}"
|
||
xml.lastmod sitemap[:last_modified].iso8601
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
render xml: builder.to_xml
|
||
end
|
||
end
|