[Ruby] Fix Content-Transfer-Encoding binary unpacking (#19132)

This commit is contained in:
Zane Pickett 2024-07-11 09:52:38 +03:00 committed by GitHub
parent 2940d3219c
commit 8938f9dea1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 87 additions and 69 deletions

View File

@ -117,16 +117,22 @@
request.options.on_data = Proc.new do |chunk, overall_received_bytes| request.options.on_data = Proc.new do |chunk, overall_received_bytes|
stream << chunk stream << chunk
end end
stream stream
end end
def deserialize_file(response, stream) def deserialize_file(response, stream)
body = response.body body = response.body
if @config.return_binary_data == true
# return byte stream
encoding = body.encoding encoding = body.encoding
stream.join.force_encoding(encoding)
else # 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 # return file instead of binary data
content_disposition = response.headers['Content-Disposition'] content_disposition = response.headers['Content-Disposition']
if content_disposition && content_disposition =~ /filename=/i if content_disposition && content_disposition =~ /filename=/i
@ -136,17 +142,17 @@
prefix = 'download-' prefix = 'download-'
end end
prefix = prefix + '-' unless prefix.end_with?('-') prefix = prefix + '-' unless prefix.end_with?('-')
encoding = body.encoding
tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
tempfile.write(stream.join.force_encoding(encoding)) tempfile.write(content)
tempfile.close tempfile.close
config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ 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 "\ "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 "\ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
"explicitly with `tempfile.delete`" "explicitly with `tempfile.delete`"
tempfile tempfile
end end
end
def connection(opts) def connection(opts)
opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular

View File

@ -164,16 +164,22 @@ module OpenapiClient
request.options.on_data = Proc.new do |chunk, overall_received_bytes| request.options.on_data = Proc.new do |chunk, overall_received_bytes|
stream << chunk stream << chunk
end end
stream stream
end end
def deserialize_file(response, stream) def deserialize_file(response, stream)
body = response.body body = response.body
if @config.return_binary_data == true
# return byte stream
encoding = body.encoding encoding = body.encoding
stream.join.force_encoding(encoding)
else # 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 # return file instead of binary data
content_disposition = response.headers['Content-Disposition'] content_disposition = response.headers['Content-Disposition']
if content_disposition && content_disposition =~ /filename=/i if content_disposition && content_disposition =~ /filename=/i
@ -183,17 +189,17 @@ module OpenapiClient
prefix = 'download-' prefix = 'download-'
end end
prefix = prefix + '-' unless prefix.end_with?('-') prefix = prefix + '-' unless prefix.end_with?('-')
encoding = body.encoding
tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
tempfile.write(stream.join.force_encoding(encoding)) tempfile.write(content)
tempfile.close tempfile.close
config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ 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 "\ "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 "\ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
"explicitly with `tempfile.delete`" "explicitly with `tempfile.delete`"
tempfile tempfile
end end
end
def connection(opts) def connection(opts)
opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular

View File

@ -164,16 +164,22 @@ module Petstore
request.options.on_data = Proc.new do |chunk, overall_received_bytes| request.options.on_data = Proc.new do |chunk, overall_received_bytes|
stream << chunk stream << chunk
end end
stream stream
end end
def deserialize_file(response, stream) def deserialize_file(response, stream)
body = response.body body = response.body
if @config.return_binary_data == true
# return byte stream
encoding = body.encoding encoding = body.encoding
stream.join.force_encoding(encoding)
else # 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 # return file instead of binary data
content_disposition = response.headers['Content-Disposition'] content_disposition = response.headers['Content-Disposition']
if content_disposition && content_disposition =~ /filename=/i if content_disposition && content_disposition =~ /filename=/i
@ -183,17 +189,17 @@ module Petstore
prefix = 'download-' prefix = 'download-'
end end
prefix = prefix + '-' unless prefix.end_with?('-') prefix = prefix + '-' unless prefix.end_with?('-')
encoding = body.encoding
tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
tempfile.write(stream.join.force_encoding(encoding)) tempfile.write(content)
tempfile.close tempfile.close
config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ 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 "\ "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 "\ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
"explicitly with `tempfile.delete`" "explicitly with `tempfile.delete`"
tempfile tempfile
end end
end
def connection(opts) def connection(opts)
opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular