add support for users to provide custom uri normalizer#533
add support for users to provide custom uri normalizer#533mamoonraja wants to merge 3 commits intohttprb:masterfrom
Conversation
|
So, I think API should look like this: HTTP.use(:normalize_uri => { :normalizer => normalizer })Also, normalizer object should be ANYTHING that responds to module NormalizeMeNot
def self.call(uri); uri; end
end
HTTP.use(:normalize_uri => { :normalizer => NormalizeMeNot })
wtf = ->(uri) { HTTP::URI.parse "https://example.com" }
HTTP.use(:normalize_uri => { :normalizer => wtf })To make things easier, we can support extra options in feature, that will be passed to normalizer as second argument. DEFAULT_NORMALIZER = lambda do |uri, only: [:schema, :query...]|
URI.new(
:schema => only.include?(:schame) ? uri.normalized_schema : uri.schema,
# ... |
lib/http/request.rb
Outdated
| # Scheme is normalized to be a lowercase symbol e.g. :http, :https | ||
| attr_reader :scheme | ||
|
|
||
| attr_reader :uri_normalizer |
There was a problem hiding this comment.
I am exposing it because we are using it in wrap_request method in auto_deflate
lib/http/request.rb
Outdated
|
|
||
| # @option opts [String] :version | ||
| # @option opts [#to_s] :verb HTTP request method | ||
| # @option opts [#to_s] :uri_normalizer uri normalizer |
There was a problem hiding this comment.
description is redundant. It's obvious from the key name.
spec/lib/http_spec.rb
Outdated
| end | ||
| end | ||
|
|
||
| it "Use the defaul Uri normalizer when user does not use uri normalizer" do |
There was a problem hiding this comment.
URI should be all caps. And topic of example should start with lowercase. Also typo in defaul.
In this particular example should be moved into default context, either here:
Line 21 in 1eae155
or here:
Line 466 in 1eae155
And should look like:
it "normalizes URI" do
response = HTTP.get "#{dummy.endpoint}/hello world"
expect(response.to_s).to eq("hello world")
endothers examples are OK to be left in here, just make them less "wordy"...
spec/lib/http_spec.rb
Outdated
| def self.call(uri) | ||
| uri | ||
| end | ||
| end |
There was a problem hiding this comment.
Don't declare module/class dynamically. You basically don't need this at all.
spec/lib/http_spec.rb
Outdated
| end | ||
|
|
||
| it "Use the custom Uri Normalizer method" do | ||
| client = HTTP.use(:normalize_uri => {:normalizer => Normalizer}) |
There was a problem hiding this comment.
As I said above you don't need Normalizer module here. Replace this line with:
| client = HTTP.use(:normalize_uri => {:normalizer => Normalizer}) | |
| client = HTTP.use(:normalize_uri => {:normalizer => :itself.to_proc}) |
| end | ||
|
|
||
| it "Use the default Uri normalizer when user does not specify custom uri normalizer" do | ||
| client = HTTP.use :normalize_uri |
There was a problem hiding this comment.
Worth to add expectation that default normalizer will be called in here:
expect(HTTP::URI::NORMALIZER).to receive(:call).and_call_original|
@httprb/core Would like to know your opinions on whenever we should enforce custom URI normalizers to return On one hand I think we should enforce, as it will allow to avoid bug reports due to crazy setup. On the other hand, I guess one of the best things this PR can bring on is optional avoidance of HTTP::Addressable (which has been reported as slow - although I'm not buying this argument). |
|
@digitalextremist Mm, that's actually doable with this PR as well: module MyNamespace
HTTP = ::HTTP.use(:normalize_url => :itself.to_proc)
endBut I'm totally fine if we will have some sort of global defaults configuration as well, although that is a bit out of the scope of this PR IMO. Something like (just a crazy idea): HTTP.defaults.uri_normalizer = ->(_) { HTTP::URI.parse "https://example.com" } |
|
@ixti I addressed the comments, and I agree that adding the global defaults configuration is out of scope for this PR. |
|
@mamoonraja thank you. I'll take a closer look to the weekend. |
|
@ixti Thanks! Do you have an ETA on when this will be merged? |
|
@mamoonraja Sure. Sorry had a busy weeks. Will merge this weekend for sure. |
|
No problem! thanks a lot! |
|
Merged in as 7fd1356 and released as v4.1.0 |
Update ruby-http to 4.4.1. ## 4.4.1 (2020-03-29) * Backport [#590](httprb/http#590) Fix parser failing on some edge cases. ([@ixti]) ## 4.4.0 (2020-03-25) * Backport [#587](httprb/http#587) Fix redirections when server responds with multiple Location headers. ([@ixti]) * Backport [#599](httprb/http#599) Allow passing HTTP::FormData::{Multipart,UrlEncoded} object directly. ([@ixti]) ## 4.3.0 (2020-01-09) * Backport [#581](httprb/http#581) Add Ruby-2.7 compatibility. ([@ixti], [@janko]) ## 4.2.0 (2019-10-22) * Backport [#489](httprb/http#489) Fix HTTP parser. ([@ixti], [@fxposter]) ## 4.1.1 (2019-03-12) * Add `HTTP::Headers::ACCEPT_ENCODING` constant. ([@ixti]) ## 4.1.0 (2019-03-11) * [#533](httprb/http#533) Add URI normalizer feature that allows to swap default URI normalizer. ([@mamoonraja]) ## 4.0.5 (2019-02-15) * Backport [#532](httprb/http#532) from master. Fix pipes support in request bodies. ([@ixti]) ## 4.0.4 (2019-02-12) * Backport [#506](httprb/http#506) from master. Skip auto-deflate when there is no body. ([@Bonias]) ## 4.0.3 (2019-01-18) * Fix missing URL in response wrapped by auto inflate. ([@ixti]) * Provide `HTTP::Request#inspect` method for debugging purposes. ([@ixti]) ## 4.0.2 (2019-01-15) * [#506](httprb/http#506) Fix instrumentation feature. ([@paul]) ## 4.0.1 (2019-01-14) * [#515](httprb/http#515) Fix `#build_request` and `#request` to respect default options. ([@RickCSong]) ## 4.0.0 (2018-10-15) * [#482](httprb/http#482) [#499](httprb/http#499) Introduce new features injection API with 2 new feaures: instrumentation (compatible with ActiveSupport::Notification) and logging. ([@paul]) * [#473](httprb/http#473) Handle early responses. ([@janko-m]) * [#468](httprb/http#468) Rewind `HTTP::Request::Body#source` once `#each` is complete. ([@ixti]) * [#467](httprb/http#467) Drop Ruby 2.2 support. ([@ixti]) * [#436](httprb/http#436) Raise ConnectionError when writing to socket fails. ([@janko-m]) * [#438](httprb/http#438) Expose `HTTP::Request::Body#source`. ([@janko-m]) * [#446](httprb/http#446) Simplify setting a timeout. ([@mikegee]) * [#451](httprb/http#451) Reduce memory usage when reading response body. ([@janko-m]) * [#458](httprb/http#458) Extract HTTP::Client#build_request method. ([@tycoon]) * [#462](httprb/http#462) Fix HTTP::Request#headline to allow two leading slashes in path. ([@scarfacedeb]) * [#454](httprb/http#454) [#464](httprb/http#464) [#384](httprb/http#384) Fix #readpartial not respecting max length argument. ([@janko-m], [@marshall-lee])
This PR tries to tackle #378 while not breaking current functionality. I wanted to get the review while I spend more time cleaning up the code to answer the open questions I mentioned and add some documentation around it.
UriNormalizerHTTP.use(:uri_normalizer => {:custom_uri_normalizer => CustomUriNormalizer.new})http_spectest to demonstrate the functionalityOpen questions:
rubocopfor now because I am adding a new condition inrequest.new, but I will work on moving that code or make client handle that.self.normalize_uriin the request, we can just use theDefaultUriNormalizerin the feature itself. Probably related to the above comment.