mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-09-14 00:00:44 -04:00
added xml transcoder
capabilities to encod/decode xml, expects nokogiri.
This commit is contained in:
parent
49d6cc4da4
commit
c70209db4b
1
Gemfile
1
Gemfile
@ -23,6 +23,7 @@ group :test do
|
||||
else
|
||||
gem "webmock"
|
||||
end
|
||||
gem "nokogiri"
|
||||
gem "websocket-driver"
|
||||
|
||||
gem "net-ssh", "~> 4.2.0" if RUBY_VERSION < "2.2.0"
|
||||
|
@ -201,7 +201,7 @@ module HTTPX
|
||||
end
|
||||
|
||||
%i[
|
||||
params form json body ssl http2_settings
|
||||
params form json xml body ssl http2_settings
|
||||
request_class response_class headers_class request_body_class
|
||||
response_body_class connection_class options_class
|
||||
io fallback_protocol debug debug_level transport_options resolver_class resolver_options
|
||||
@ -210,7 +210,7 @@ module HTTPX
|
||||
def_option(method_name)
|
||||
end
|
||||
|
||||
REQUEST_IVARS = %i[@params @form @json @body].freeze
|
||||
REQUEST_IVARS = %i[@params @form @xml @json @body].freeze
|
||||
private_constant :REQUEST_IVARS
|
||||
|
||||
def ==(other)
|
||||
|
@ -162,6 +162,8 @@ module HTTPX
|
||||
Transcoder.registry("form").encode(options.form)
|
||||
elsif options.json
|
||||
Transcoder.registry("json").encode(options.json)
|
||||
elsif options.xml
|
||||
Transcoder.registry("xml").encode(options.xml)
|
||||
end
|
||||
return if @body.nil?
|
||||
|
||||
|
@ -94,6 +94,10 @@ module HTTPX
|
||||
decode("form")
|
||||
end
|
||||
|
||||
def xml
|
||||
decode("xml")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def decode(format, *args)
|
||||
|
@ -90,4 +90,5 @@ end
|
||||
require "httpx/transcoder/body"
|
||||
require "httpx/transcoder/form"
|
||||
require "httpx/transcoder/json"
|
||||
require "httpx/transcoder/xml"
|
||||
require "httpx/transcoder/chunker"
|
||||
|
49
lib/httpx/transcoder/xml.rb
Normal file
49
lib/httpx/transcoder/xml.rb
Normal file
@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "delegate"
|
||||
require "forwardable"
|
||||
require "uri"
|
||||
|
||||
module HTTPX::Transcoder
|
||||
module Xml
|
||||
using HTTPX::RegexpExtensions
|
||||
|
||||
module_function
|
||||
|
||||
MIME_TYPES = %r{\b(application|text)/(.+\+)?xml\b}.freeze
|
||||
|
||||
class Encoder < SimpleDelegator
|
||||
def content_type
|
||||
charset = respond_to?(:encoding) ? encoding.to_s.downcase : "utf-8"
|
||||
"application/xml; charset=#{charset}"
|
||||
end
|
||||
|
||||
def bytesize
|
||||
to_s.bytesize
|
||||
end
|
||||
end
|
||||
|
||||
def encode(xml)
|
||||
Encoder.new(xml)
|
||||
end
|
||||
|
||||
begin
|
||||
require "nokogiri"
|
||||
|
||||
# rubocop:disable Lint/DuplicateMethods
|
||||
def decode(response)
|
||||
content_type = response.content_type.mime_type
|
||||
|
||||
raise HTTPX::Error, "invalid form mime type (#{content_type})" unless MIME_TYPES.match?(content_type)
|
||||
|
||||
Nokogiri::XML.method(:parse)
|
||||
end
|
||||
rescue LoadError
|
||||
def decode(_response)
|
||||
raise HTTPX::Error, "\"nokogiri\" is required in order to decode XML"
|
||||
end
|
||||
end
|
||||
# rubocop:enable Lint/DuplicateMethods
|
||||
end
|
||||
register "xml", Xml
|
||||
end
|
@ -45,7 +45,7 @@ class OptionsTest < Minitest::Test
|
||||
assert opt2.body == "fat", "body was not set"
|
||||
end
|
||||
|
||||
%i[form json].each do |meth|
|
||||
%i[form json xml].each do |meth|
|
||||
define_method :"test_options_#{meth}" do
|
||||
opt1 = Options.new
|
||||
assert opt1.public_send(meth).nil?, "#{meth} shouldn't be set by default"
|
||||
@ -98,6 +98,7 @@ class OptionsTest < Minitest::Test
|
||||
:debug_level => 1,
|
||||
:params => nil,
|
||||
:json => nil,
|
||||
:xml => nil,
|
||||
:body => nil,
|
||||
:window_size => 16_384,
|
||||
:body_threshold_size => 114_688,
|
||||
|
@ -77,6 +77,13 @@ class RequestTest < Minitest::Test
|
||||
assert req.headers["content-length"] == "13", "content length is wrong"
|
||||
end
|
||||
|
||||
def test_request_body_xml
|
||||
req = Request.new(:post, "http://example.com/", xml: "<xml></xml>")
|
||||
assert !req.body.empty?, "body should exist"
|
||||
assert req.headers["content-type"] == "application/xml; charset=utf-8", "content type is wrong"
|
||||
assert req.headers["content-length"] == "11", "content length is wrong"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource
|
||||
|
@ -156,6 +156,11 @@ class ResponseTest < Minitest::Test
|
||||
form_response << "богус"
|
||||
assert_raises(ArgumentError) { form_response.form }
|
||||
|
||||
xml_response = Response.new(request, 200, "2.0", { "content-type" => "application/xml; charset=utf-8" })
|
||||
xml_response << "<xml></xml>"
|
||||
xml = xml_response.xml
|
||||
assert xml.is_a?(Nokogiri::XML::Node)
|
||||
|
||||
form2_response = Response.new(request, 200, "2.0", { "content-type" => "application/x-www-form-urlencoded" })
|
||||
form2_response << "a[]=b&a[]=c&d[e]=f&g[h][i][j]=k&l[m][][n]=o&l[m][][p]=q&l[m][][n]=r&s[=t"
|
||||
assert form2_response.form == {
|
||||
|
Loading…
x
Reference in New Issue
Block a user