我对这个问题有部分解决方案:
检查外部文件头。该应用程序正在向外部服务器发送标头请求。
1.1 如果状态为200(成功),则应用程序像以前一样开始检索过程。
1.2 如果状态是任何其他值,则会显示一个错误页面,其中包含相应的错误消息。
代码如下所示:
uri = URI.parse(link)
net_http = Net::HTTP.new(uri.host, uri.port)
net_http.open_timeout = options[:timeout]
net_http.read_timeout = options[:timeout]
net_http.use_ssl = (uri.scheme == 'https')
if net_http.use_ssl?
net_http.cert = OpenSSL::X509::Certificate.new(File.read(options[:cert]))
net_http.key = OpenSSL::PKey::RSA.new(File.read(options[:cert]))
net_http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
begin
request = Net::HTTP::Get.new(uri.request_uri)
res = net_http.request(request)
if res.code.to_i == 200
self.response.headers['Pragma'] = 'no-cache'
self.response.headers['Cache-Control'] = 'private,max-age=0,must-revalidate,no-store'
self.response.headers['Last-Modified'] = Time.now.ctime.to_s
self.response.headers['Accept-Ranges'] = 'bytes'
self.response.headers['Content-Type'] = type
self.response.headers['Content-Disposition'] = "attachment; filename=\"#{save_as}\""
self.response.headers['Content-Transfer-Encoding'] = 'binary'
self.response.headers['Content-Description'] = 'File Transfer'
self.response.headers['Content-Length'] = "#{filesize}"
self.response_body = FileStreamer.new(link, options)
else
raise "The requested file is not available at the moment"
end
rescue SocketError => se
raise 'It seems the URL is not correct'
rescue Errno::ECONNREFUSED => cr
raise 'It seems the server refused the connection request'
rescue Errno::EHOSTUNREACH => hu
raise 'It seems the server cannot be reached'
rescue Errno::ENETUNREACH => nu
raise 'It seems the network cannot be reached'
rescue Timeout::Error => te
raise 'Request timed out while connecting to the server'
rescue StandardError => e
raise e.message
end
FileStreamer 是一个机架中间件,它响应每个方法。
def each
begin
@net_http.start do |http|
http.request_get(@uri.request_uri(),
{'User-Agent' => 'FileStreamer'}) do |response|
case response
when Net::HTTPSuccess then
response.read_body do |segment|
yield segment
end
when Net::HTTPRedirection then
raise 'Redirection not allowed'
else
raise "Error trying to retrieve a file:\n" \
" URL: #{@uri.to_s}\n" \
" Error: #{response.message.to_s}"
end
end
end
rescue SocketError => se
raise 'It seems the URL is not correct'
rescue Errno::ECONNREFUSED => cr
raise 'It seems the server refused the connection request'
rescue Errno::EHOSTUNREACH => hu
raise 'It seems the server cannot be reached'
rescue Errno::ENETUNREACH => nu
raise 'It seems the network cannot be reached'
rescue Timeout::Error => te
raise 'Request timed out while connecting to the server'
rescue StandardError => e
raise e.message
end
end
请记住,此解决方案不包括在过程中间发生的错误,我猜如果中间发生错误,那么应用程序将显示丑陋的错误页面。