class CountsExportsController < ApplicationController wrap_parameters false def prepare locale = resolve_locale! payload = request.request_parameters.merge(request.query_parameters) exporter = CountsExporter.new(payload, language_code: locale.language_code) session[:counts_export_owner] ||= SecureRandom.hex(32) token = CountsExportDownload.prepare(exporter, session[:counts_export_owner]) response.headers['Cache-Control'] = 'private, no-store' render json: { token: } rescue ArgumentError, TypeError, KeyError, JSON::ParserError head :bad_request end def download file = CountsExportDownload.find(params[:token], session[:counts_export_owner]) return head :not_found unless file response.headers['Cache-Control'] = 'private, no-store' send_file file.fetch('path'), filename: "counts-#{ file.fetch('resource') }.#{ file.fetch('format') }", type: file['format'] == 'json' ? 'application/json' : 'text/csv', disposition: 'attachment' end def index locale = resolve_locale! payload = request.request_parameters.except('authenticity_token') .merge(request.query_parameters) exporter = CountsExporter.new(payload, language_code: locale.language_code) response.headers['Content-Type'] = exporter.format == 'json' ? 'application/json; charset=utf-8' : 'text/csv; charset=utf-8' response.headers['Content-Disposition'] = "attachment; filename=\"counts-#{ exporter.resource }.#{ exporter.format }\"" response.headers['Cache-Control'] = 'private, no-store' response.headers['X-Accel-Buffering'] = 'no' # Rack::ETag otherwise materialises the response to calculate a digest. response.headers['Last-Modified'] = Time.current.httpdate self.response_body = exporter.body rescue ArgumentError, TypeError, KeyError, JSON::ParserError head :bad_request end end