httpx 0.24.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) 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/1_0_0.md +60 -0
  6. data/lib/httpx/adapters/datadog.rb +28 -97
  7. data/lib/httpx/adapters/faraday.rb +9 -52
  8. data/lib/httpx/adapters/webmock.rb +2 -7
  9. data/lib/httpx/altsvc.rb +4 -22
  10. data/lib/httpx/base64.rb +27 -0
  11. data/lib/httpx/chainable.rb +0 -23
  12. data/lib/httpx/connection.rb +11 -32
  13. data/lib/httpx/domain_name.rb +5 -12
  14. data/lib/httpx/errors.rb +0 -2
  15. data/lib/httpx/extensions.rb +0 -124
  16. data/lib/httpx/io/ssl.rb +26 -59
  17. data/lib/httpx/io/tcp.rb +27 -68
  18. data/lib/httpx/io/udp.rb +13 -48
  19. data/lib/httpx/io/unix.rb +1 -8
  20. data/lib/httpx/loggable.rb +4 -19
  21. data/lib/httpx/options.rb +24 -84
  22. data/lib/httpx/plugins/{authentication → auth}/basic.rb +1 -5
  23. data/lib/httpx/plugins/{authentication → auth}/digest.rb +2 -5
  24. data/lib/httpx/plugins/{authentication → auth}/ntlm.rb +1 -3
  25. data/lib/httpx/plugins/{authentication → auth}/socks5.rb +0 -2
  26. data/lib/httpx/plugins/auth.rb +25 -0
  27. data/lib/httpx/plugins/aws_sigv4.rb +0 -1
  28. data/lib/httpx/plugins/{basic_authentication.rb → basic_auth.rb} +5 -6
  29. data/lib/httpx/plugins/brotli.rb +50 -0
  30. data/lib/httpx/plugins/circuit_breaker/circuit.rb +40 -16
  31. data/lib/httpx/plugins/circuit_breaker/circuit_store.rb +16 -5
  32. data/lib/httpx/plugins/circuit_breaker.rb +11 -4
  33. data/lib/httpx/plugins/cookies/set_cookie_parser.rb +0 -2
  34. data/lib/httpx/plugins/cookies.rb +1 -1
  35. data/lib/httpx/plugins/{digest_authentication.rb → digest_auth.rb} +5 -5
  36. data/lib/httpx/plugins/follow_redirects.rb +21 -24
  37. data/lib/httpx/plugins/grpc/grpc_encoding.rb +82 -0
  38. data/lib/httpx/plugins/grpc/message.rb +7 -39
  39. data/lib/httpx/plugins/grpc.rb +15 -21
  40. data/lib/httpx/plugins/h2c.rb +0 -1
  41. data/lib/httpx/plugins/{ntlm_authentication.rb → ntlm_auth.rb} +5 -5
  42. data/lib/httpx/plugins/oauth.rb +2 -2
  43. data/lib/httpx/plugins/proxy/http.rb +0 -2
  44. data/lib/httpx/plugins/proxy/socks4.rb +0 -4
  45. data/lib/httpx/plugins/proxy/socks5.rb +1 -5
  46. data/lib/httpx/plugins/proxy.rb +3 -32
  47. data/lib/httpx/plugins/retries.rb +3 -4
  48. data/lib/httpx/plugins/stream.rb +4 -6
  49. data/lib/httpx/punycode.rb +9 -291
  50. data/lib/httpx/request/body.rb +145 -0
  51. data/lib/httpx/request.rb +2 -119
  52. data/lib/httpx/resolver/https.rb +1 -1
  53. data/lib/httpx/resolver/native.rb +6 -14
  54. data/lib/httpx/resolver/resolver.rb +1 -1
  55. data/lib/httpx/resolver/system.rb +11 -9
  56. data/lib/httpx/response/body.rb +206 -0
  57. data/lib/httpx/response/buffer.rb +90 -0
  58. data/lib/httpx/response.rb +5 -208
  59. data/lib/httpx/selector.rb +0 -2
  60. data/lib/httpx/session.rb +0 -10
  61. data/lib/httpx/transcoder/body.rb +0 -1
  62. data/lib/httpx/transcoder/deflate.rb +37 -0
  63. data/lib/httpx/transcoder/form.rb +52 -32
  64. data/lib/httpx/transcoder/gzip.rb +74 -0
  65. data/lib/httpx/transcoder/json.rb +2 -4
  66. data/lib/httpx/transcoder/multipart/decoder.rb +139 -0
  67. data/lib/httpx/{plugins → transcoder}/multipart/encoder.rb +3 -3
  68. data/lib/httpx/{plugins → transcoder}/multipart/mime_type_detector.rb +1 -1
  69. data/lib/httpx/{plugins → transcoder}/multipart/part.rb +3 -2
  70. data/lib/httpx/transcoder/multipart.rb +17 -0
  71. data/lib/httpx/transcoder/utils/body_reader.rb +46 -0
  72. data/lib/httpx/transcoder/utils/deflater.rb +72 -0
  73. data/lib/httpx/transcoder/xml.rb +0 -2
  74. data/lib/httpx/transcoder.rb +2 -2
  75. data/lib/httpx/utils.rb +10 -20
  76. data/lib/httpx/version.rb +1 -1
  77. data/lib/httpx.rb +0 -8
  78. data/sig/chainable.rbs +5 -6
  79. data/sig/connection.rbs +0 -1
  80. data/sig/errors.rbs +0 -3
  81. data/sig/httpx.rbs +2 -1
  82. data/sig/io/unix.rbs +1 -1
  83. data/sig/options.rbs +12 -8
  84. data/sig/plugins/{authentication → auth}/basic.rbs +0 -2
  85. data/sig/plugins/auth.rbs +13 -0
  86. data/sig/plugins/{basic_authentication.rbs → basic_auth.rbs} +2 -2
  87. data/sig/plugins/brotli.rbs +22 -0
  88. data/sig/plugins/circuit_breaker.rbs +7 -3
  89. data/sig/plugins/compression.rbs +0 -2
  90. data/sig/plugins/{digest_authentication.rbs → digest_auth.rbs} +2 -2
  91. data/sig/plugins/follow_redirects.rbs +0 -1
  92. data/sig/plugins/grpc/call.rbs +19 -0
  93. data/sig/plugins/grpc/grpc_encoding.rbs +33 -0
  94. data/sig/plugins/grpc/message.rbs +17 -0
  95. data/sig/plugins/grpc.rbs +2 -32
  96. data/sig/plugins/{ntlm_authentication.rbs → ntlm_auth.rbs} +2 -2
  97. data/sig/plugins/oauth.rbs +1 -1
  98. data/sig/plugins/proxy/socks4.rbs +2 -3
  99. data/sig/plugins/proxy/socks5.rbs +0 -1
  100. data/sig/plugins/proxy/ssh.rbs +1 -1
  101. data/sig/plugins/response_cache.rbs +5 -2
  102. data/sig/request/body.rbs +42 -0
  103. data/sig/request.rbs +1 -27
  104. data/sig/resolver/resolver.rbs +1 -1
  105. data/sig/response/body.rbs +52 -0
  106. data/sig/response/buffer.rbs +24 -0
  107. data/sig/response.rbs +0 -39
  108. data/sig/transcoder/body.rbs +4 -3
  109. data/sig/transcoder/deflate.rbs +11 -0
  110. data/sig/transcoder/form.rbs +5 -3
  111. data/sig/transcoder/gzip.rbs +24 -0
  112. data/sig/transcoder/json.rbs +4 -2
  113. data/sig/{plugins → transcoder}/multipart.rbs +3 -10
  114. data/sig/transcoder/utils/body_reader.rbs +15 -0
  115. data/sig/transcoder/utils/deflater.rbs +29 -0
  116. data/sig/transcoder.rbs +18 -2
  117. metadata +50 -34
  118. data/lib/httpx/plugins/authentication.rb +0 -24
  119. data/lib/httpx/plugins/compression/brotli.rb +0 -54
  120. data/lib/httpx/plugins/compression/deflate.rb +0 -54
  121. data/lib/httpx/plugins/compression/gzip.rb +0 -90
  122. data/lib/httpx/plugins/compression.rb +0 -165
  123. data/lib/httpx/plugins/multipart/decoder.rb +0 -137
  124. data/lib/httpx/plugins/multipart.rb +0 -96
  125. data/sig/plugins/authentication.rbs +0 -13
  126. data/sig/plugins/compression/brotli.rbs +0 -21
  127. data/sig/plugins/compression/deflate.rbs +0 -17
  128. data/sig/plugins/compression/gzip.rbs +0 -29
  129. /data/sig/plugins/{authentication → auth}/digest.rbs +0 -0
  130. /data/sig/plugins/{authentication → auth}/ntlm.rbs +0 -0
  131. /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