-
Notifications
You must be signed in to change notification settings - Fork 367
Allow response_body_formatter config to format "binary" responses #458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow response_body_formatter config to format "binary" responses #458
Conversation
Just want to drop a note that this PR will fix #456 as well. |
Do not display binary data in generated documentation. Closes #199.
@@ -118,7 +118,9 @@ def self.add_setting(name, opts = {}) | |||
# See RspecApiDocumentation::DSL::Endpoint#do_request | |||
add_setting :response_body_formatter, default: Proc.new { |_, _| | |||
Proc.new do |content_type, response_body| | |||
if content_type =~ /application\/.*json/ | |||
if response_body.encoding == Encoding::ASCII_8BIT | |||
"[binary data]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, so this is backwards compatible. 👍
@@ -250,7 +250,8 @@ RspecApiDocumentation.configure do |config| | |||
|
|||
# Change how the response body is formatted by default | |||
# Is proc that will be called with the response_content_type & response_body | |||
# by default response_content_type of `application/json` are pretty formated. | |||
# by default, a response body that is likely to be binary is replaced with the string | |||
# "[binary data]" regardless of the media type. Otherwise, a response_content_type of `application/json` is pretty formatted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# "[binary data]" regardless of the media type. Otherwise, a response_content_type of `application/json` is pretty formatted. | |
# "[binary data]" regardless of the media type. Otherwise, a response_content_type identified as JSON is pretty formatted. |
@davidstosik you have passing tests locally? I tried and got mixed results with the feature specs, and issues with Webmock... see my closed attempt #460 |
To be frank, I had not even tried to run tests locally! 😅 Locally on Ruby 2.6.5, I managed to run the tests, but ended up with 14 failures (mainly "undefined method `<<' for Hash" and one "undefined method `close' for StubSocket"). 🤔 Webmock 1.22.6 is very old and it is likely it does not work on more recent versions of Ruby. 🤔 (It looks like support for Ruby 2.4 was added in 2.3.1...) I think removing Without Gemfile.lock however, I get more recent versions of the gem dependencies. It's fine for runtime dependencies (as a gem should be able to work with most), however, version requirements on development dependencies might be more restrictive than what Update: check this: #461 🙏 |
Awesome job! My own policy for gemspec is development deps should only be what is required to run tests, then use the Gemfile(s) to add other things or version specific gems or constraints |
Any update on this? |
@davidstosik Thank you for your work! |
Following this issue on Rack's repository: [Fix incorrect MockResponse#body String encoding](rack/rack#1486), it looks like we can expect, from now on, that Rack's `response_body` encoding will be `Encoding::ASCII_8BIT`: > I think the response body should probably always be ASCII-8BIT. Rack can't really know anything about the encoding of the bytes that users want to send. At the end of the day, it's just bytes written to the socket, and I don't think Rack should have any opinion about the encoding the user sends. Therefore, `rspec_api_documentation` cannot rely on `response_body.encoding` to determine whether the response is binary data or not. This line becomes incorrect: https://github.com/zipmark/rspec_api_documentation/blob/81e5c563ce6787f143cf775c64e2bd08c35d3585/lib/rspec_api_documentation/client_base.rb#L90-L91 The real fix would be to figure out a better way to define whether a string is binary or not, but I believe this is a bit outside the scope of my knowledge. In this PR, I'm focusing on giving any application using the `rspec_api_documentation` the choice on how to process the response_body, and particularly on how to detect binary data, while not altering `rspec_api_documentation`'s default behaviour. As an additional benefit, this change would allow an application to display friendlier responses in the documentation for some binary types. For example, PNG data: ```rb Proc.new do |content_type, response_body| # http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature if response_body[0,8] == "\x89PNG\r\n\u001A\n" "<img src=\"data:image/png;base64,#{Base64.strict_encode64(response_body)}\" />" elsif content_type =~ /application\/.*json/ JSON.pretty_generate(JSON.parse(response_body)) else response_body end end ```
Co-Authored-By: Benjamin Fleischer <[email protected]>
f7889eb
to
6675985
Compare
…pmark#458) * Allow response_body_formatter config to format "binary" responses Following this issue on Rack's repository: [Fix incorrect MockResponse#body String encoding](rack/rack#1486), it looks like we can expect, from now on, that Rack's `response_body` encoding will be `Encoding::ASCII_8BIT`: > I think the response body should probably always be ASCII-8BIT. Rack can't really know anything about the encoding of the bytes that users want to send. At the end of the day, it's just bytes written to the socket, and I don't think Rack should have any opinion about the encoding the user sends. Therefore, `rspec_api_documentation` cannot rely on `response_body.encoding` to determine whether the response is binary data or not. This line becomes incorrect: https://github.com/zipmark/rspec_api_documentation/blob/81e5c563ce6787f143cf775c64e2bd08c35d3585/lib/rspec_api_documentation/client_base.rb#L90-L91 The real fix would be to figure out a better way to define whether a string is binary or not, but I believe this is a bit outside the scope of my knowledge. In this PR, I'm focusing on giving any application using the `rspec_api_documentation` the choice on how to process the response_body, and particularly on how to detect binary data, while not altering `rspec_api_documentation`'s default behaviour. As an additional benefit, this change would allow an application to display friendlier responses in the documentation for some binary types. For example, PNG data: ```rb Proc.new do |content_type, response_body| # http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature if response_body[0,8] == "\x89PNG\r\n\u001A\n" "<img src=\"data:image/png;base64,#{Base64.strict_encode64(response_body)}\" />" elsif content_type =~ /application\/.*json/ JSON.pretty_generate(JSON.parse(response_body)) else response_body end end ``` * Update README.md Co-Authored-By: Benjamin Fleischer <[email protected]>
Following this issue on Rack's repository: Fix incorrect MockResponse#body String encoding, it looks like we can expect, from now on, that Rack's
response_body
encoding will beEncoding::ASCII_8BIT
:Therefore,
rspec_api_documentation
cannot rely onresponse_body.encoding
to determine whether the response is binary data or not. This line becomes incorrect:rspec_api_documentation/lib/rspec_api_documentation/client_base.rb
Lines 90 to 91 in 81e5c56
The real fix would be to figure out a better way to define whether a string is binary or not, but I believe this is a bit outside the scope of my knowledge.
In this PR, I'm focusing on giving any application using the
rspec_api_documentation
gem the choice on how to process the response_body, and particularly on how to detect binary data, while not alteringrspec_api_documentation
's default behaviour.As an additional benefit, this change would allow an application to display friendlier responses in its documentation for some binary types.
For example, PNG data: