From 04907a790f8b9a40585e5f852a16e47ecdaceaaa Mon Sep 17 00:00:00 2001 From: Zane Wolfgang Pickett Date: Wed, 10 Jul 2024 16:19:35 +0300 Subject: [PATCH] [Ruby] Fix Content-Transfer-Encoding binary unpacking --- .../api_client_faraday_partial.mustache | 52 +++++++++++-------- .../lib/openapi_client/api_client.rb | 52 +++++++++++-------- .../ruby-faraday/lib/petstore/api_client.rb | 52 +++++++++++-------- 3 files changed, 87 insertions(+), 69 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/ruby-client/api_client_faraday_partial.mustache b/modules/openapi-generator/src/main/resources/ruby-client/api_client_faraday_partial.mustache index 1a85fc69c3de..11ae6450f716 100644 --- a/modules/openapi-generator/src/main/resources/ruby-client/api_client_faraday_partial.mustache +++ b/modules/openapi-generator/src/main/resources/ruby-client/api_client_faraday_partial.mustache @@ -117,35 +117,41 @@ request.options.on_data = Proc.new do |chunk, overall_received_bytes| stream << chunk end + stream end def deserialize_file(response, stream) - body = response.body - if @config.return_binary_data == true - # return byte stream - encoding = body.encoding - stream.join.force_encoding(encoding) + body = response.body + encoding = body.encoding + + # reconstruct content + content = stream.join + content = content.unpack('m').join if response.headers['Content-Transfer-Encoding'] == 'binary' + content = content.force_encoding(encoding) + + # return byte stream + return content if @config.return_binary_data == true + + # return file instead of binary data + content_disposition = response.headers['Content-Disposition'] + if content_disposition && content_disposition =~ /filename=/i + filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] + prefix = sanitize_filename(filename) else - # return file instead of binary data - content_disposition = response.headers['Content-Disposition'] - if content_disposition && content_disposition =~ /filename=/i - filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] - prefix = sanitize_filename(filename) - else - prefix = 'download-' - end - prefix = prefix + '-' unless prefix.end_with?('-') - encoding = body.encoding - tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) - tempfile.write(stream.join.force_encoding(encoding)) - tempfile.close - config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ - "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ - "will be deleted automatically with GC. It's also recommended to delete the temp file "\ - "explicitly with `tempfile.delete`" - tempfile + prefix = 'download-' end + prefix = prefix + '-' unless prefix.end_with?('-') + + tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) + tempfile.write(content) + tempfile.close + + config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ + "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ + "will be deleted automatically with GC. It's also recommended to delete the temp file "\ + "explicitly with `tempfile.delete`" + tempfile end def connection(opts) diff --git a/samples/client/echo_api/ruby-faraday/lib/openapi_client/api_client.rb b/samples/client/echo_api/ruby-faraday/lib/openapi_client/api_client.rb index 3ddd5b6a49d5..13a8340d6f21 100644 --- a/samples/client/echo_api/ruby-faraday/lib/openapi_client/api_client.rb +++ b/samples/client/echo_api/ruby-faraday/lib/openapi_client/api_client.rb @@ -164,35 +164,41 @@ def download_file(request) request.options.on_data = Proc.new do |chunk, overall_received_bytes| stream << chunk end + stream end def deserialize_file(response, stream) - body = response.body - if @config.return_binary_data == true - # return byte stream - encoding = body.encoding - stream.join.force_encoding(encoding) + body = response.body + encoding = body.encoding + + # reconstruct content + content = stream.join + content = content.unpack('m').join if response.headers['Content-Transfer-Encoding'] == 'binary' + content = content.force_encoding(encoding) + + # return byte stream + return content if @config.return_binary_data == true + + # return file instead of binary data + content_disposition = response.headers['Content-Disposition'] + if content_disposition && content_disposition =~ /filename=/i + filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] + prefix = sanitize_filename(filename) else - # return file instead of binary data - content_disposition = response.headers['Content-Disposition'] - if content_disposition && content_disposition =~ /filename=/i - filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] - prefix = sanitize_filename(filename) - else - prefix = 'download-' - end - prefix = prefix + '-' unless prefix.end_with?('-') - encoding = body.encoding - tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) - tempfile.write(stream.join.force_encoding(encoding)) - tempfile.close - config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ - "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ - "will be deleted automatically with GC. It's also recommended to delete the temp file "\ - "explicitly with `tempfile.delete`" - tempfile + prefix = 'download-' end + prefix = prefix + '-' unless prefix.end_with?('-') + + tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) + tempfile.write(content) + tempfile.close + + config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ + "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ + "will be deleted automatically with GC. It's also recommended to delete the temp file "\ + "explicitly with `tempfile.delete`" + tempfile end def connection(opts) diff --git a/samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb b/samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb index 7cff0bb7d9b0..b59a2f8a6a6d 100644 --- a/samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb +++ b/samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb @@ -164,35 +164,41 @@ def download_file(request) request.options.on_data = Proc.new do |chunk, overall_received_bytes| stream << chunk end + stream end def deserialize_file(response, stream) - body = response.body - if @config.return_binary_data == true - # return byte stream - encoding = body.encoding - stream.join.force_encoding(encoding) + body = response.body + encoding = body.encoding + + # reconstruct content + content = stream.join + content = content.unpack('m').join if response.headers['Content-Transfer-Encoding'] == 'binary' + content = content.force_encoding(encoding) + + # return byte stream + return content if @config.return_binary_data == true + + # return file instead of binary data + content_disposition = response.headers['Content-Disposition'] + if content_disposition && content_disposition =~ /filename=/i + filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] + prefix = sanitize_filename(filename) else - # return file instead of binary data - content_disposition = response.headers['Content-Disposition'] - if content_disposition && content_disposition =~ /filename=/i - filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] - prefix = sanitize_filename(filename) - else - prefix = 'download-' - end - prefix = prefix + '-' unless prefix.end_with?('-') - encoding = body.encoding - tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) - tempfile.write(stream.join.force_encoding(encoding)) - tempfile.close - config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ - "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ - "will be deleted automatically with GC. It's also recommended to delete the temp file "\ - "explicitly with `tempfile.delete`" - tempfile + prefix = 'download-' end + prefix = prefix + '-' unless prefix.end_with?('-') + + tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) + tempfile.write(content) + tempfile.close + + config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ + "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ + "will be deleted automatically with GC. It's also recommended to delete the temp file "\ + "explicitly with `tempfile.delete`" + tempfile end def connection(opts)