このコミットが含まれているのは:
2026-10-29 23:31:04 +09:00
コミット efbd640963
8個のファイルの変更、201行の追加、19行の削除
+54
ファイルの表示
@@ -24,6 +24,14 @@ class CountsExportsController < ApplicationController
job_state(cancel: true)
end
def start_download
result = CountsExportJobs.download_attempt(params[:token], session[:counts_export_owner])
return head :not_found unless result
response.headers['Cache-Control'] = 'private, no-store'
render json: result
end
def prepare
locale = resolve_locale!
payload = request.request_parameters.merge(request.query_parameters)
@@ -45,6 +53,11 @@ class CountsExportsController < ApplicationController
end
def download
if params[:job].present? || params[:attempt].present?
return head :method_not_allowed unless request.get?
return confirmed_download
end
file = CountsExportDownload.find(params[:token], session[:counts_export_owner])
return head :not_found unless file
@@ -55,6 +68,47 @@ class CountsExportsController < ApplicationController
disposition: 'attachment'
end
def confirmed_download
owner = session[:counts_export_owner]
arguments = { file_token: params[:token], attempt: params[:attempt] }
return head :not_found unless arguments[:attempt].present? &&
CountsExportJobs.download_attempt(params[:job], owner, **arguments)
file = CountsExportDownload.find(params[:token], owner)
unless file
CountsExportJobs.download_attempt(params[:job], owner, **arguments, status: 'unavailable')
return head :not_found
end
# Open before committing the response, but never buffer the entire export.
stream = File.open(file.fetch('path'), 'rb')
response.headers['Cache-Control'] = 'private, no-store'
send_file_headers! filename: "counts-#{ file.fetch('resource') }.#{ file.fetch('format') }",
type: file['format'] == 'json' ? 'application/json' : 'text/csv',
disposition: 'attachment'
job = params[:job]
authority = HistoryAccess.user
self.response_body = Enumerator.new do |output|
begin
first = true
while (chunk = stream.read(64 * 1024))
output << chunk
if first
HistoryAccess.set(user: authority) do
CountsExportJobs.download_attempt(job, owner, **arguments, status: 'started')
end
first = false
end
end
ensure
stream.close
end
end
rescue IOError, SystemCallError
CountsExportJobs.download_attempt(params[:job], owner, **arguments, status: 'failed')
head :service_unavailable
end
private :confirmed_download
def job_state(cancel:)
result = CountsExportJobs.status(params[:token], session[:counts_export_owner], cancel:)
return head :not_found unless result