httpx 0.24.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +0 -48
  3. data/README.md +4 -13
  4. data/doc/release_notes/0_24_4.md +3 -3
  5. data/doc/release_notes/0_24_6.md +5 -0
  6. data/doc/release_notes/1_0_0.md +60 -0
  7. data/lib/httpx/adapters/datadog.rb +28 -97
  8. data/lib/httpx/adapters/faraday.rb +9 -52
  9. data/lib/httpx/adapters/webmock.rb +2 -7
  10. data/lib/httpx/altsvc.rb +4 -22
  11. data/lib/httpx/base64.rb +27 -0
  12. data/lib/httpx/chainable.rb +2 -25
  13. data/lib/httpx/connection.rb +11 -32
  14. data/lib/httpx/domain_name.rb +5 -12
  15. data/lib/httpx/errors.rb +0 -2
  16. data/lib/httpx/extensions.rb +0 -124
  17. data/lib/httpx/io/ssl.rb +26 -59
  18. data/lib/httpx/io/tcp.rb +27 -68
  19. data/lib/httpx/io/udp.rb +13 -48
  20. data/lib/httpx/io/unix.rb +1 -8
  21. data/lib/httpx/loggable.rb +4 -19
  22. data/lib/httpx/options.rb +24 -84
  23. data/lib/httpx/plugins/{authentication → auth}/basic.rb +1 -5
  24. data/lib/httpx/plugins/{authentication → auth}/digest.rb +2 -5
  25. data/lib/httpx/plugins/{authentication → auth}/ntlm.rb +1 -3
  26. data/lib/httpx/plugins/{authentication → auth}/socks5.rb +0 -2
  27. data/lib/httpx/plugins/auth.rb +25 -0
  28. data/lib/httpx/plugins/aws_sigv4.rb +0 -1
  29. data/lib/httpx/plugins/{basic_authentication.rb → basic_auth.rb} +5 -6
  30. data/lib/httpx/plugins/brotli.rb +50 -0
  31. data/lib/httpx/plugins/circuit_breaker/circuit.rb +40 -16
  32. data/lib/httpx/plugins/circuit_breaker/circuit_store.rb +16 -5
  33. data/lib/httpx/plugins/circuit_breaker.rb +11 -4
  34. data/lib/httpx/plugins/cookies/set_cookie_parser.rb +0 -2
  35. data/lib/httpx/plugins/cookies.rb +1 -1
  36. data/lib/httpx/plugins/{digest_authentication.rb → digest_auth.rb} +5 -5
  37. data/lib/httpx/plugins/follow_redirects.rb +21 -24
  38. data/lib/httpx/plugins/grpc/grpc_encoding.rb +82 -0
  39. data/lib/httpx/plugins/grpc/message.rb +7 -39
  40. data/lib/httpx/plugins/grpc.rb +15 -21
  41. data/lib/httpx/plugins/h2c.rb +0 -1
  42. data/lib/httpx/plugins/{ntlm_authentication.rb → ntlm_auth.rb} +5 -5
  43. data/lib/httpx/plugins/oauth.rb +2 -2
  44. data/lib/httpx/plugins/proxy/http.rb +0 -2
  45. data/lib/httpx/plugins/proxy/socks4.rb +0 -4
  46. data/lib/httpx/plugins/proxy/socks5.rb +1 -5
  47. data/lib/httpx/plugins/proxy.rb +3 -32
  48. data/lib/httpx/plugins/retries.rb +3 -4
  49. data/lib/httpx/plugins/stream.rb +4 -6
  50. data/lib/httpx/punycode.rb +9 -291
  51. data/lib/httpx/request/body.rb +145 -0
  52. data/lib/httpx/request.rb +2 -119
  53. data/lib/httpx/resolver/https.rb +1 -1
  54. data/lib/httpx/resolver/native.rb +6 -14
  55. data/lib/httpx/resolver/resolver.rb +1 -1
  56. data/lib/httpx/resolver/system.rb +11 -9
  57. data/lib/httpx/response/body.rb +206 -0
  58. data/lib/httpx/response/buffer.rb +90 -0
  59. data/lib/httpx/response.rb +5 -208
  60. data/lib/httpx/selector.rb +0 -2
  61. data/lib/httpx/session.rb +3 -10
  62. data/lib/httpx/transcoder/body.rb +0 -1
  63. data/lib/httpx/transcoder/deflate.rb +37 -0
  64. data/lib/httpx/transcoder/form.rb +52 -32
  65. data/lib/httpx/transcoder/gzip.rb +74 -0
  66. data/lib/httpx/transcoder/json.rb +2 -4
  67. data/lib/httpx/transcoder/multipart/decoder.rb +139 -0
  68. data/lib/httpx/{plugins → transcoder}/multipart/encoder.rb +3 -3
  69. data/lib/httpx/{plugins → transcoder}/multipart/mime_type_detector.rb +1 -1
  70. data/lib/httpx/{plugins → transcoder}/multipart/part.rb +3 -2
  71. data/lib/httpx/transcoder/multipart.rb +17 -0
  72. data/lib/httpx/transcoder/utils/body_reader.rb +46 -0
  73. data/lib/httpx/transcoder/utils/deflater.rb +72 -0
  74. data/lib/httpx/transcoder/xml.rb +0 -2
  75. data/lib/httpx/transcoder.rb +2 -2
  76. data/lib/httpx/utils.rb +10 -20
  77. data/lib/httpx/version.rb +1 -1
  78. data/lib/httpx.rb +0 -8
  79. data/sig/chainable.rbs +5 -6
  80. data/sig/connection.rbs +0 -1
  81. data/sig/errors.rbs +0 -3
  82. data/sig/httpx.rbs +2 -1
  83. data/sig/io/unix.rbs +1 -1
  84. data/sig/options.rbs +12 -8
  85. data/sig/plugins/{authentication → auth}/basic.rbs +0 -2
  86. data/sig/plugins/auth.rbs +13 -0
  87. data/sig/plugins/{basic_authentication.rbs → basic_auth.rbs} +2 -2
  88. data/sig/plugins/brotli.rbs +22 -0
  89. data/sig/plugins/circuit_breaker.rbs +7 -3
  90. data/sig/plugins/compression.rbs +0 -2
  91. data/sig/plugins/{digest_authentication.rbs → digest_auth.rbs} +2 -2
  92. data/sig/plugins/follow_redirects.rbs +0 -1
  93. data/sig/plugins/grpc/call.rbs +19 -0
  94. data/sig/plugins/grpc/grpc_encoding.rbs +33 -0
  95. data/sig/plugins/grpc/message.rbs +17 -0
  96. data/sig/plugins/grpc.rbs +2 -32
  97. data/sig/plugins/{ntlm_authentication.rbs → ntlm_auth.rbs} +2 -2
  98. data/sig/plugins/oauth.rbs +1 -1
  99. data/sig/plugins/proxy/socks4.rbs +2 -3
  100. data/sig/plugins/proxy/socks5.rbs +0 -1
  101. data/sig/plugins/proxy/ssh.rbs +1 -1
  102. data/sig/plugins/response_cache.rbs +5 -2
  103. data/sig/request/body.rbs +42 -0
  104. data/sig/request.rbs +1 -27
  105. data/sig/resolver/resolver.rbs +1 -1
  106. data/sig/response/body.rbs +52 -0
  107. data/sig/response/buffer.rbs +24 -0
  108. data/sig/response.rbs +0 -39
  109. data/sig/session.rbs +2 -0
  110. data/sig/transcoder/body.rbs +4 -3
  111. data/sig/transcoder/deflate.rbs +11 -0
  112. data/sig/transcoder/form.rbs +5 -3
  113. data/sig/transcoder/gzip.rbs +24 -0
  114. data/sig/transcoder/json.rbs +4 -2
  115. data/sig/{plugins → transcoder}/multipart.rbs +3 -10
  116. data/sig/transcoder/utils/body_reader.rbs +15 -0
  117. data/sig/transcoder/utils/deflater.rbs +29 -0
  118. data/sig/transcoder.rbs +18 -2
  119. metadata +52 -34
  120. data/lib/httpx/plugins/authentication.rb +0 -24
  121. data/lib/httpx/plugins/compression/brotli.rb +0 -54
  122. data/lib/httpx/plugins/compression/deflate.rb +0 -54
  123. data/lib/httpx/plugins/compression/gzip.rb +0 -90
  124. data/lib/httpx/plugins/compression.rb +0 -165
  125. data/lib/httpx/plugins/multipart/decoder.rb +0 -137
  126. data/lib/httpx/plugins/multipart.rb +0 -96
  127. data/sig/plugins/authentication.rbs +0 -13
  128. data/sig/plugins/compression/brotli.rbs +0 -21
  129. data/sig/plugins/compression/deflate.rbs +0 -17
  130. data/sig/plugins/compression/gzip.rbs +0 -29
  131. /data/sig/plugins/{authentication → auth}/digest.rbs +0 -0
  132. /data/sig/plugins/{authentication → auth}/ntlm.rbs +0 -0
  133. /data/sig/plugins/{authentication → auth}/socks5.rbs +0 -0
@@ -1,137 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "tempfile"
4
- require "delegate"
5
-
6
- module HTTPX::Plugins
7
- module Multipart
8
- class FilePart < SimpleDelegator
9
- attr_reader :original_filename, :content_type
10
-
11
- def initialize(filename, content_type)
12
- @original_filename = filename
13
- @content_type = content_type
14
- @file = Tempfile.new("httpx", encoding: Encoding::BINARY, mode: File::RDWR)
15
- super(@file)
16
- end
17
- end
18
-
19
- class Decoder
20
- include HTTPX::Utils
21
-
22
- CRLF = "\r\n"
23
- BOUNDARY_RE = /;\s*boundary=([^;]+)/i.freeze
24
- MULTIPART_CONTENT_TYPE = /Content-Type: (.*)#{CRLF}/ni.freeze
25
- MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:.*;\s*name=(#{VALUE})/ni.freeze
26
- MULTIPART_CONTENT_ID = /Content-ID:\s*([^#{CRLF}]*)/ni.freeze
27
- WINDOW_SIZE = 2 << 14
28
-
29
- def initialize(response)
30
- @boundary = begin
31
- m = response.headers["content-type"].to_s[BOUNDARY_RE, 1]
32
- raise Error, "no boundary declared in content-type header" unless m
33
-
34
- m.strip
35
- end
36
- @buffer = "".b
37
- @parts = {}
38
- @intermediate_boundary = "--#{@boundary}"
39
- @state = :idle
40
- end
41
-
42
- def call(response, *)
43
- response.body.each do |chunk|
44
- @buffer << chunk
45
-
46
- parse
47
- end
48
-
49
- raise Error, "invalid or unsupported multipart format" unless @buffer.empty?
50
-
51
- @parts
52
- end
53
-
54
- private
55
-
56
- def parse
57
- case @state
58
- when :idle
59
- raise Error, "payload does not start with boundary" unless @buffer.start_with?("#{@intermediate_boundary}#{CRLF}")
60
-
61
- @buffer = @buffer.byteslice(@intermediate_boundary.bytesize + 2..-1)
62
-
63
- @state = :part_header
64
- when :part_header
65
- idx = @buffer.index("#{CRLF}#{CRLF}")
66
-
67
- # raise Error, "couldn't parse part headers" unless idx
68
- return unless idx
69
-
70
- head = @buffer.byteslice(0..idx + 4 - 1)
71
-
72
- @buffer = @buffer.byteslice(head.bytesize..-1)
73
-
74
- content_type = head[MULTIPART_CONTENT_TYPE, 1]
75
- if (name = head[MULTIPART_CONTENT_DISPOSITION, 1])
76
- name = /\A"(.*)"\Z/ =~ name ? Regexp.last_match(1) : name.dup
77
- name.gsub!(/\\(.)/, "\\1")
78
- name
79
- else
80
- name = head[MULTIPART_CONTENT_ID, 1]
81
- end
82
-
83
- filename = HTTPX::Utils.get_filename(head)
84
-
85
- name = filename || +"#{content_type || "text/plain"}[]" if name.nil? || name.empty?
86
-
87
- @current = name
88
-
89
- @parts[name] = if filename
90
- FilePart.new(filename, content_type)
91
- else
92
- "".b
93
- end
94
-
95
- @state = :part_body
96
- when :part_body
97
- part = @parts[@current]
98
-
99
- body_separator = if part.is_a?(FilePart)
100
- "#{CRLF}#{CRLF}"
101
- else
102
- CRLF
103
- end
104
- idx = @buffer.index(body_separator)
105
-
106
- if idx
107
- payload = @buffer.byteslice(0..idx - 1)
108
- @buffer = @buffer.byteslice(idx + body_separator.bytesize..-1)
109
- part << payload
110
- part.rewind if part.respond_to?(:rewind)
111
- @state = :parse_boundary
112
- else
113
- part << @buffer
114
- @buffer.clear
115
- end
116
- when :parse_boundary
117
- raise Error, "payload does not start with boundary" unless @buffer.start_with?(@intermediate_boundary)
118
-
119
- @buffer = @buffer.byteslice(@intermediate_boundary.bytesize..-1)
120
-
121
- if @buffer == "--"
122
- @buffer.clear
123
- @state = :done
124
- return
125
- elsif @buffer.start_with?(CRLF)
126
- @buffer = @buffer.byteslice(2..-1)
127
- @state = :part_header
128
- else
129
- return
130
- end
131
- when :done
132
- raise Error, "parsing should have been over by now"
133
- end until @buffer.empty?
134
- end
135
- end
136
- end
137
- end
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module HTTPX
4
- module Plugins
5
- #
6
- # This plugin adds support for passing `http-form_data` objects (like file objects) as "multipart/form-data";
7
- #
8
- # HTTPX.post(URL, form: form: { image: HTTP::FormData::File.new("path/to/file")})
9
- #
10
- # https://gitlab.com/os85/httpx/wikis/Multipart-Uploads
11
- #
12
- module Multipart
13
- MULTIPART_VALUE_COND = lambda do |value|
14
- value.respond_to?(:read) ||
15
- (value.respond_to?(:to_hash) &&
16
- value.key?(:body) &&
17
- (value.key?(:filename) || value.key?(:content_type)))
18
- end
19
-
20
- class << self
21
- def normalize_keys(key, value, &block)
22
- Transcoder.normalize_keys(key, value, MULTIPART_VALUE_COND, &block)
23
- end
24
-
25
- def load_dependencies(*)
26
- # :nocov:
27
- begin
28
- unless defined?(HTTP::FormData)
29
- # in order not to break legacy code, we'll keep loading http/form_data for them.
30
- require "http/form_data"
31
- warn "httpx: http/form_data is no longer a requirement to use HTTPX :multipart plugin. See migration instructions under" \
32
- "https://os85.gitlab.io/httpx/wiki/Multipart-Uploads.html#notes. \n\n" \
33
- "If you'd like to stop seeing this message, require 'http/form_data' yourself."
34
- end
35
- rescue LoadError
36
- end
37
- # :nocov:
38
- require "httpx/plugins/multipart/encoder"
39
- require "httpx/plugins/multipart/decoder"
40
- require "httpx/plugins/multipart/part"
41
- require "httpx/plugins/multipart/mime_type_detector"
42
- end
43
- end
44
-
45
- module RequestBodyMethods
46
- private
47
-
48
- def initialize_body(options)
49
- return FormTranscoder.encode(options.form) if options.form
50
-
51
- super
52
- end
53
- end
54
-
55
- module ResponseMethods
56
- def form
57
- decode(FormTranscoder)
58
- end
59
- end
60
-
61
- module FormTranscoder
62
- module_function
63
-
64
- def encode(form)
65
- if multipart?(form)
66
- Encoder.new(form)
67
- else
68
- Transcoder::Form::Encoder.new(form)
69
- end
70
- end
71
-
72
- def decode(response)
73
- content_type = response.content_type.mime_type
74
-
75
- case content_type
76
- when "application/x-www-form-urlencoded"
77
- Transcoder::Form.decode(response)
78
- when "multipart/form-data"
79
- Decoder.new(response)
80
- else
81
- raise Error, "invalid form mime type (#{content_type})"
82
- end
83
- end
84
-
85
- def multipart?(data)
86
- data.any? do |_, v|
87
- MULTIPART_VALUE_COND.call(v) ||
88
- (v.respond_to?(:to_ary) && v.to_ary.any?(&MULTIPART_VALUE_COND)) ||
89
- (v.respond_to?(:to_hash) && v.to_hash.any? { |_, e| MULTIPART_VALUE_COND.call(e) })
90
- end
91
- end
92
- end
93
- end
94
- register_plugin :multipart, Multipart
95
- end
96
- end
@@ -1,13 +0,0 @@
1
- module HTTPX
2
- module Plugins
3
- module Authentication
4
- module InstanceMethods
5
- def authentication: (string token) -> instance
6
-
7
- def bearer_auth: (string token) -> instance
8
- end
9
- end
10
-
11
- type sessionAuthentication = Session & Authentication::InstanceMethods
12
- end
13
- end
@@ -1,21 +0,0 @@
1
- module HTTPX
2
- module Plugins
3
- module Compression
4
- module Brotli
5
- def self.load_dependencies: (singleton(Session)) -> void
6
- def self.configure: (singleton(Session)) -> void
7
-
8
- def self?.deflater: () -> _Deflater
9
- def self?.decoder: (Integer | Float bytesize) -> Inflater
10
-
11
- module Deflater
12
- extend _Deflater
13
- end
14
-
15
- class Inflater
16
- include _Inflater
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,17 +0,0 @@
1
- module HTTPX
2
- module Plugins
3
- module Compression
4
- module Deflate
5
- def self.load_dependencies: (singleton(Session)) -> void
6
- def self.configure: (singleton(Session)) -> void
7
-
8
- def self?.deflater: () -> _Deflater
9
- def self?.inflater: (Integer | Float bytesize) -> GZIP::Inflater
10
-
11
- module Deflater
12
- extend _Deflater
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,29 +0,0 @@
1
- module HTTPX
2
- module Plugins
3
- module Compression
4
- module GZIP
5
- def self.load_dependencies: (singleton(Session)) -> void
6
- def self.configure: (singleton(Session)) -> void
7
-
8
- def self?.deflater: () -> _Deflater
9
- def self?.inflater: (Integer | Float bytesize) -> Inflater
10
-
11
- class Deflater
12
- include _Deflater
13
-
14
- @compressed_chunk: String
15
-
16
- private
17
-
18
- def initialize: () -> untyped
19
- def write: (string) -> void
20
- def compressed_chunk: () -> String
21
- end
22
-
23
- class Inflater
24
- include _Inflater
25
- end
26
- end
27
- end
28
- end
29
- end
File without changes
File without changes
File without changes