http 4.0.5 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94fd7f54004fd45a400c1e9befb46ea80d4bcdebae70929330355a5ea9056cf2
4
- data.tar.gz: 3bbd9c1f0a29267bff2b6682ddaeaa53832eb896ec471d6ab3db62d5cbd08be2
3
+ metadata.gz: 2fd67432d99ac8430c405776f6483ddb0e05d323ea9e8c18a0760936ba3c2608
4
+ data.tar.gz: bfcd8f950d05342a5fe993a0b88d47cbdc6418fbeef4e13b67eefb482ece7b77
5
5
  SHA512:
6
- metadata.gz: 5863fb462013166b6f76ff40929768f5a87ca86c02bd23c882bf5db1aefa6bed5be2a21785a45edecf66f6a6ac3418d86042b5c24f998e1f01489a661a1d9cae
7
- data.tar.gz: 04726c6858928f553380fbb221cc1164cc51917ae2122cd9b7424ef3f1ff072c7b32ae2231cb32569a4411487f6c805acee54ec09e309e6eba4675a783df8306
6
+ metadata.gz: 74790c3405ba4cd9ebe667d7e4ae61ae895bd9a67c36be057fe8dba446b8020ec74b06c77fbe904bccebcf23b307aa3a1fd85fd6ea48248abf2869069f5e109b
7
+ data.tar.gz: ce21f7ca1026c690eae83f18a688bab7d5a1da6344af13865819f5da911a4ff79a0b2424a9f22a6ac605273bb825dd848171c0f555d5d4130bd7b8e137532eea
data/CHANGES.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 4.1.0 (2019-03-11)
2
+
3
+ * [#533](https://github.com/httprb/http/pull/533)
4
+ Add URI normalizer feature that allows to swap default URI normalizer.
5
+ ([@mamoonraja])
6
+
7
+
1
8
  ## 4.0.5 (2019-02-15)
2
9
 
3
10
  * Backport [#532](https://github.com/httprb/http/pull/532) from master.
@@ -758,3 +765,4 @@ end
758
765
  [@tycoon]: https://github.com/tycooon
759
766
  [@paul]: https://github.com/paul
760
767
  [@RickCSong]: https://github.com/RickCSong
768
+ [@mamoonraja]: https://github.com/mamoonraja
@@ -42,14 +42,14 @@ module HTTP
42
42
  uri = make_request_uri(uri, opts)
43
43
  headers = make_request_headers(opts)
44
44
  body = make_request_body(opts, headers)
45
- proxy = opts.proxy
46
45
 
47
46
  req = HTTP::Request.new(
48
- :verb => verb,
49
- :uri => uri,
50
- :headers => headers,
51
- :proxy => proxy,
52
- :body => body
47
+ :verb => verb,
48
+ :uri => uri,
49
+ :uri_normalizer => opts.feature(:normalize_uri)&.normalizer,
50
+ :proxy => opts.proxy,
51
+ :headers => headers,
52
+ :body => body
53
53
  )
54
54
 
55
55
  opts.features.inject(req) do |request, (_name, feature)|
@@ -20,3 +20,4 @@ require "http/features/auto_inflate"
20
20
  require "http/features/auto_deflate"
21
21
  require "http/features/logging"
22
22
  require "http/features/instrumentation"
23
+ require "http/features/normalize_uri"
@@ -32,7 +32,8 @@ module HTTP
32
32
  :uri => request.uri,
33
33
  :headers => request.headers,
34
34
  :proxy => request.proxy,
35
- :body => deflated_body(request.body)
35
+ :body => deflated_body(request.body),
36
+ :uri_normalizer => request.uri_normalizer
36
37
  )
37
38
  end
38
39
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "http/uri"
4
+
5
+ module HTTP
6
+ module Features
7
+ class NormalizeUri < Feature
8
+ attr_reader :normalizer
9
+
10
+ def initialize(normalizer: HTTP::URI::NORMALIZER)
11
+ @normalizer = normalizer
12
+ end
13
+
14
+ HTTP::Options.register_feature(:normalize_uri, self)
15
+ end
16
+ end
17
+ end
@@ -66,6 +66,8 @@ module HTTP
66
66
  # Scheme is normalized to be a lowercase symbol e.g. :http, :https
67
67
  attr_reader :scheme
68
68
 
69
+ attr_reader :uri_normalizer
70
+
69
71
  # "Request URI" as per RFC 2616
70
72
  # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
71
73
  attr_reader :uri
@@ -73,25 +75,25 @@ module HTTP
73
75
 
74
76
  # @option opts [String] :version
75
77
  # @option opts [#to_s] :verb HTTP request method
78
+ # @option opts [#call] :uri_normalizer (HTTP::URI::NORMALIZER)
76
79
  # @option opts [HTTP::URI, #to_s] :uri
77
80
  # @option opts [Hash] :headers
78
81
  # @option opts [Hash] :proxy
79
82
  # @option opts [String, Enumerable, IO, nil] :body
80
83
  def initialize(opts)
81
- @verb = opts.fetch(:verb).to_s.downcase.to_sym
82
- @uri = normalize_uri(opts.fetch(:uri))
84
+ @verb = opts.fetch(:verb).to_s.downcase.to_sym
85
+ @uri_normalizer = opts[:uri_normalizer] || HTTP::URI::NORMALIZER
86
+
87
+ @uri = @uri_normalizer.call(opts.fetch(:uri))
83
88
  @scheme = @uri.scheme.to_s.downcase.to_sym if @uri.scheme
84
89
 
85
90
  raise(UnsupportedMethodError, "unknown method: #{verb}") unless METHODS.include?(@verb)
86
91
  raise(UnsupportedSchemeError, "unknown scheme: #{scheme}") unless SCHEMES.include?(@scheme)
87
92
 
88
93
  @proxy = opts[:proxy] || {}
89
- @body = (body = opts[:body]).is_a?(Request::Body) ? body : Request::Body.new(body)
90
94
  @version = opts[:version] || "1.1"
91
- @headers = HTTP::Headers.coerce(opts[:headers] || {})
92
-
93
- @headers[Headers::HOST] ||= default_host_header_value
94
- @headers[Headers::USER_AGENT] ||= USER_AGENT
95
+ @headers = prepare_headers(opts[:headers])
96
+ @body = prepare_body(opts[:body])
95
97
  end
96
98
 
97
99
  # Returns new Request with updated uri
@@ -100,12 +102,13 @@ module HTTP
100
102
  headers.delete(Headers::HOST)
101
103
 
102
104
  self.class.new(
103
- :verb => verb,
104
- :uri => @uri.join(uri),
105
- :headers => headers,
106
- :proxy => proxy,
107
- :body => body.source,
108
- :version => version
105
+ :verb => verb,
106
+ :uri => @uri.join(uri),
107
+ :headers => headers,
108
+ :proxy => proxy,
109
+ :body => body.source,
110
+ :version => version,
111
+ :uri_normalizer => uri_normalizer
109
112
  )
110
113
  end
111
114
 
@@ -213,17 +216,17 @@ module HTTP
213
216
  PORTS[@scheme] != port ? "#{host}:#{port}" : host
214
217
  end
215
218
 
216
- # @return [HTTP::URI] URI with all componentes but query being normalized.
217
- def normalize_uri(uri)
218
- uri = HTTP::URI.parse uri
219
+ def prepare_body(body)
220
+ body.is_a?(Request::Body) ? body : Request::Body.new(body)
221
+ end
219
222
 
220
- HTTP::URI.new(
221
- :scheme => uri.normalized_scheme,
222
- :authority => uri.normalized_authority,
223
- :path => uri.normalized_path,
224
- :query => uri.query,
225
- :fragment => uri.normalized_fragment
226
- )
223
+ def prepare_headers(headers)
224
+ headers = HTTP::Headers.coerce(headers || {})
225
+
226
+ headers[Headers::HOST] ||= default_host_header_value
227
+ headers[Headers::USER_AGENT] ||= USER_AGENT
228
+
229
+ headers
227
230
  end
228
231
  end
229
232
  end
@@ -26,6 +26,19 @@ module HTTP
26
26
  # @private
27
27
  HTTPS_SCHEME = "https"
28
28
 
29
+ # @private
30
+ NORMALIZER = lambda do |uri|
31
+ uri = HTTP::URI.parse uri
32
+
33
+ HTTP::URI.new(
34
+ :scheme => uri.normalized_scheme,
35
+ :authority => uri.normalized_authority,
36
+ :path => uri.normalized_path,
37
+ :query => uri.query,
38
+ :fragment => uri.normalized_fragment
39
+ )
40
+ end
41
+
29
42
  # Parse the given URI string, returning an HTTP::URI object
30
43
  #
31
44
  # @param [HTTP::URI, String, #to_str] uri to parse
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTP
4
- VERSION = "4.0.5"
4
+ VERSION = "4.1.0"
5
5
  end
@@ -430,6 +430,26 @@ RSpec.describe HTTP do
430
430
  expect(response.to_s).to eq("#{body}-deflated")
431
431
  end
432
432
  end
433
+
434
+ context "with :normalize_uri" do
435
+ it "normalizes URI" do
436
+ response = HTTP.get "#{dummy.endpoint}/hello world"
437
+ expect(response.to_s).to eq("hello world")
438
+ end
439
+
440
+ it "uses the custom URI Normalizer method" do
441
+ client = HTTP.use(:normalize_uri => {:normalizer => :itself.to_proc})
442
+ response = client.get("#{dummy.endpoint}/hello world")
443
+ expect(response.status).to eq(400)
444
+ end
445
+
446
+ it "uses the default URI normalizer" do
447
+ client = HTTP.use :normalize_uri
448
+ expect(HTTP::URI::NORMALIZER).to receive(:call).and_call_original
449
+ response = client.get("#{dummy.endpoint}/hello world")
450
+ expect(response.to_s).to eq("hello world")
451
+ end
452
+ end
433
453
  end
434
454
 
435
455
  it "unifies socket errors into HTTP::ConnectionError" do
@@ -148,6 +148,11 @@ class DummyServer < WEBrick::HTTPServer
148
148
  res.body = req.body
149
149
  end
150
150
 
151
+ get "/hello world" do |_req, res|
152
+ res.status = 200
153
+ res.body = "hello world"
154
+ end
155
+
151
156
  post "/encoded-body" do |req, res|
152
157
  res.status = 200
153
158
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.5
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2019-02-15 00:00:00.000000000 Z
14
+ date: 2019-03-11 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: http_parser.rb
@@ -116,6 +116,7 @@ files:
116
116
  - lib/http/features/auto_inflate.rb
117
117
  - lib/http/features/instrumentation.rb
118
118
  - lib/http/features/logging.rb
119
+ - lib/http/features/normalize_uri.rb
119
120
  - lib/http/headers.rb
120
121
  - lib/http/headers/known.rb
121
122
  - lib/http/headers/mixin.rb
@@ -197,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
198
  - !ruby/object:Gem::Version
198
199
  version: '0'
199
200
  requirements: []
200
- rubygems_version: 3.0.1
201
+ rubygems_version: 3.0.3
201
202
  signing_key:
202
203
  specification_version: 4
203
204
  summary: HTTP should be easy