mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-07-26 00:00:49 -04:00
Compare commits
11 Commits
6437b4b5fb
...
290da6f1fe
Author | SHA1 | Date | |
---|---|---|---|
|
290da6f1fe | ||
|
ea46cb08a4 | ||
|
8ec98064a1 | ||
|
b8f0d0fbcd | ||
|
911a27b20a | ||
|
a586dd0d44 | ||
|
79756e4ac4 | ||
|
354bba3179 | ||
|
b0dfe68ebe | ||
|
fa513a9ac9 | ||
|
716e98af5b |
@ -26,6 +26,7 @@ class WebmockTest < Minitest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def teardown
|
def teardown
|
||||||
|
super
|
||||||
WebMock.reset!
|
WebMock.reset!
|
||||||
WebMock.allow_net_connect!
|
WebMock.allow_net_connect!
|
||||||
WebMock.disable!
|
WebMock.disable!
|
||||||
@ -214,17 +215,49 @@ class WebmockTest < Minitest::Test
|
|||||||
assert_not_requested(:get, "http://#{httpbin}")
|
assert_not_requested(:get, "http://#{httpbin}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_webmock_follow_redirects_with_stream_plugin
|
def test_webmock_follow_redirects_with_stream_plugin_each
|
||||||
session = HTTPX.plugin(:follow_redirects).plugin(:stream)
|
session = HTTPX.plugin(:follow_redirects).plugin(:stream)
|
||||||
redirect_url = "#{MOCK_URL_HTTP}/redirect"
|
redirect_url = "#{MOCK_URL_HTTP}/redirect"
|
||||||
initial_request = stub_request(:get, MOCK_URL_HTTP).to_return(status: 302, headers: { location: redirect_url })
|
initial_request = stub_request(:get, MOCK_URL_HTTP).to_return(status: 302, headers: { location: redirect_url }, body: "redirecting")
|
||||||
redirect_request = stub_request(:get, redirect_url)
|
redirect_request = stub_request(:get, redirect_url).to_return(status: 200, body: "body")
|
||||||
|
|
||||||
session.get(MOCK_URL_HTTP, stream: true).each.to_a.join
|
response = session.get(MOCK_URL_HTTP, stream: true)
|
||||||
|
body = "".b
|
||||||
|
response.each do |chunk|
|
||||||
|
next if (300..399).cover?(response.status)
|
||||||
|
|
||||||
|
body << chunk
|
||||||
|
end
|
||||||
|
assert_equal("body", body)
|
||||||
assert_requested(initial_request)
|
assert_requested(initial_request)
|
||||||
assert_requested(redirect_request)
|
assert_requested(redirect_request)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_webmock_with_stream_plugin_each
|
||||||
|
session = HTTPX.plugin(:stream)
|
||||||
|
request = stub_request(:get, MOCK_URL_HTTP).to_return(body: "body")
|
||||||
|
|
||||||
|
body = "".b
|
||||||
|
response = session.get(MOCK_URL_HTTP, stream: true)
|
||||||
|
response.each do |chunk|
|
||||||
|
next if (300..399).cover?(response.status)
|
||||||
|
|
||||||
|
body << chunk
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal("body", body)
|
||||||
|
assert_requested(request)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_webmock_with_stream_plugin_each_line
|
||||||
|
session = HTTPX.plugin(:stream)
|
||||||
|
request = stub_request(:get, MOCK_URL_HTTP).to_return(body: "First line\nSecond line")
|
||||||
|
|
||||||
|
response = session.get(MOCK_URL_HTTP, stream: true)
|
||||||
|
assert_equal(["First line", "Second line"], response.each_line.to_a)
|
||||||
|
assert_requested(request)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def assert_raise_with_message(e, message, &block)
|
def assert_raise_with_message(e, message, &block)
|
||||||
|
@ -38,12 +38,10 @@ module WebMock
|
|||||||
|
|
||||||
return build_error_response(request, webmock_response.exception) if webmock_response.exception
|
return build_error_response(request, webmock_response.exception) if webmock_response.exception
|
||||||
|
|
||||||
response = request.options.response_class.new(request,
|
request.options.response_class.new(request,
|
||||||
webmock_response.status[0],
|
webmock_response.status[0],
|
||||||
"2.0",
|
"2.0",
|
||||||
webmock_response.headers)
|
webmock_response.headers)
|
||||||
response << webmock_response.body.dup
|
|
||||||
response
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_error_response(request, exception)
|
def build_error_response(request, exception)
|
||||||
@ -90,6 +88,7 @@ module WebMock
|
|||||||
log { "mocking #{request.uri} with #{mock_response.inspect}" }
|
log { "mocking #{request.uri} with #{mock_response.inspect}" }
|
||||||
request.response = response
|
request.response = response
|
||||||
request.emit(:response, response)
|
request.emit(:response, response)
|
||||||
|
response << mock_response.body.dup unless response.is_a?(HTTPX::ErrorResponse)
|
||||||
elsif WebMock.net_connect_allowed?(request_signature.uri)
|
elsif WebMock.net_connect_allowed?(request_signature.uri)
|
||||||
if WebMock::CallbackRegistry.any_callbacks?
|
if WebMock::CallbackRegistry.any_callbacks?
|
||||||
request.on(:response) do |resp|
|
request.on(:response) do |resp|
|
||||||
|
@ -11,6 +11,7 @@ module HTTPX
|
|||||||
@response = response
|
@response = response
|
||||||
@decoder = ->(z) { z }
|
@decoder = ->(z) { z }
|
||||||
@consumed = false
|
@consumed = false
|
||||||
|
@grpc_response = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
@ -34,9 +35,7 @@ module HTTPX
|
|||||||
private
|
private
|
||||||
|
|
||||||
def grpc_response
|
def grpc_response
|
||||||
return @grpc_response if defined?(@grpc_response)
|
@grpc_response ||= if @response.respond_to?(:each)
|
||||||
|
|
||||||
@grpc_response = if @response.respond_to?(:each)
|
|
||||||
Enumerator.new do |y|
|
Enumerator.new do |y|
|
||||||
Message.stream(@response).each do |message|
|
Message.stream(@response).each do |message|
|
||||||
y << @decoder.call(message)
|
y << @decoder.call(message)
|
||||||
|
@ -37,6 +37,7 @@ module HTTPX
|
|||||||
class Inflater
|
class Inflater
|
||||||
def initialize(response)
|
def initialize(response)
|
||||||
@response = response
|
@response = response
|
||||||
|
@grpc_encodings = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(message, &blk)
|
def call(message, &blk)
|
||||||
|
@ -5,6 +5,7 @@ module HTTPX
|
|||||||
def initialize(request, session)
|
def initialize(request, session)
|
||||||
@request = request
|
@request = request
|
||||||
@session = session
|
@session = session
|
||||||
|
@response = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def each(&block)
|
def each(&block)
|
||||||
@ -25,7 +26,7 @@ module HTTPX
|
|||||||
def each_line
|
def each_line
|
||||||
return enum_for(__method__) unless block_given?
|
return enum_for(__method__) unless block_given?
|
||||||
|
|
||||||
line = +""
|
line = "".b
|
||||||
|
|
||||||
each do |chunk|
|
each do |chunk|
|
||||||
line << chunk
|
line << chunk
|
||||||
@ -36,6 +37,8 @@ module HTTPX
|
|||||||
line = line.byteslice(idx + 1..-1)
|
line = line.byteslice(idx + 1..-1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
yield line unless line.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is a ghost method. It's to be used ONLY internally, when processing streams
|
# This is a ghost method. It's to be used ONLY internally, when processing streams
|
||||||
@ -58,8 +61,10 @@ module HTTPX
|
|||||||
private
|
private
|
||||||
|
|
||||||
def response
|
def response
|
||||||
@response ||= begin
|
return @response if @response
|
||||||
@request.response || @session.request(@request)
|
|
||||||
|
@request.response || begin
|
||||||
|
@response = @session.request(@request)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -119,10 +119,21 @@ module HTTPX
|
|||||||
def response=(response)
|
def response=(response)
|
||||||
return unless response
|
return unless response
|
||||||
|
|
||||||
if response.is_a?(Response) && response.status == 100 && @headers.key?("expect")
|
if response.is_a?(Response) && response.status < 200
|
||||||
@informational_status = response.status
|
# deal with informational responses
|
||||||
return
|
|
||||||
|
if response.status == 100 && @headers.key?("expect")
|
||||||
|
@informational_status = response.status
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if response.status >= 103
|
||||||
|
# 103 Early Hints advertises resources in document to browsers.
|
||||||
|
# not very relevant for an HTTP client, discard.
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@response = response
|
@response = response
|
||||||
|
|
||||||
emit(:response_started, response)
|
emit(:response_started, response)
|
||||||
|
@ -264,4 +264,4 @@ end
|
|||||||
|
|
||||||
require_relative "response/body"
|
require_relative "response/body"
|
||||||
require_relative "response/buffer"
|
require_relative "response/buffer"
|
||||||
require_relative "pmatch_extensions" if RUBY_VERSION >= "3.0.0"
|
require_relative "pmatch_extensions" if RUBY_VERSION >= "2.7.0"
|
||||||
|
@ -1,26 +1,4 @@
|
|||||||
module HTTPX
|
module HTTPX
|
||||||
class StreamResponse
|
|
||||||
include _ToS
|
|
||||||
|
|
||||||
@request: Request & RequestMethods
|
|
||||||
@session: sessionStream
|
|
||||||
@on_chunk: ^(String) -> void | nil
|
|
||||||
|
|
||||||
def each: () { (String) -> void } -> void
|
|
||||||
| () -> Enumerable[String]
|
|
||||||
|
|
||||||
def each_line: () { (String) -> void } -> void
|
|
||||||
| () -> Enumerable[String]
|
|
||||||
|
|
||||||
def on_chunk: (string) -> void
|
|
||||||
|
|
||||||
def initialize: (Request, Session) -> void
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def response: () -> response
|
|
||||||
end
|
|
||||||
|
|
||||||
module Plugins
|
module Plugins
|
||||||
module Stream
|
module Stream
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
@ -42,4 +20,28 @@ module HTTPX
|
|||||||
|
|
||||||
type sessionStream = Session & Stream::InstanceMethods
|
type sessionStream = Session & Stream::InstanceMethods
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class StreamResponse
|
||||||
|
include _ToS
|
||||||
|
|
||||||
|
type streamRequest = Request & Plugins::Stream::RequestMethods
|
||||||
|
|
||||||
|
@request: streamRequest
|
||||||
|
@session: Plugins::sessionStream
|
||||||
|
@on_chunk: ^(String) -> void | nil
|
||||||
|
|
||||||
|
def each: () { (String) -> void } -> void
|
||||||
|
| () -> Enumerable[String]
|
||||||
|
|
||||||
|
def each_line: () { (String) -> void } -> void
|
||||||
|
| () -> Enumerable[String]
|
||||||
|
|
||||||
|
def on_chunk: (string) -> void
|
||||||
|
|
||||||
|
def initialize: (streamRequest, Plugins::sessionStream) -> void
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def response: () -> response
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@ class ResponseTest < Minitest::Test
|
|||||||
include HTTPX
|
include HTTPX
|
||||||
include ResponseHelpers
|
include ResponseHelpers
|
||||||
|
|
||||||
if RUBY_VERSION >= "3.0.0"
|
if RUBY_VERSION >= "2.7.0"
|
||||||
begin
|
begin
|
||||||
eval("case 1; in 1 ;then true; end") # rubocop:disable Style/EvalWithLocation
|
eval("case 1; in 1 ;then true; end") # rubocop:disable Style/EvalWithLocation
|
||||||
require_relative "extensions/response_pattern_match"
|
require_relative "extensions/response_pattern_match"
|
||||||
|
@ -76,6 +76,11 @@ fi
|
|||||||
|
|
||||||
PARALLEL=1 bundle exec rake test
|
PARALLEL=1 bundle exec rake test
|
||||||
|
|
||||||
|
if [[ "$RUBY_ENGINE" = "ruby" ]] && [[ ${RUBY_VERSION:0:1} = "3" ]] && [[ ! $RUBYOPT =~ "jit" ]]; then
|
||||||
|
# https://github.com/ruby/rbs/issues/1636
|
||||||
|
unset RUBYOPT
|
||||||
|
fi
|
||||||
|
|
||||||
# third party modules
|
# third party modules
|
||||||
# Testing them only with main ruby, as some of them work weird with other variants.
|
# Testing them only with main ruby, as some of them work weird with other variants.
|
||||||
if [[ "$RUBY_ENGINE" = "ruby" ]]; then
|
if [[ "$RUBY_ENGINE" = "ruby" ]]; then
|
||||||
|
Loading…
x
Reference in New Issue
Block a user