requests: added support for post body encoding, for json and form params for now

This commit is contained in:
HoneyryderChuck 2017-12-06 19:25:33 +00:00
parent 3ff56ceb09
commit e7b943ba39
3 changed files with 104 additions and 4 deletions

17
examples/post.rb Normal file
View File

@ -0,0 +1,17 @@
require "httpx"
require "json"
include HTTPX
URLS = %w[http://httpbin.org/post]
$HTTPX_DEBUG = true
client = Client.new
requests = URLS.map { |url| client.request(:post, url, json: {"bang" => "bang"}) }
responses = client.send(*requests)
responses.each do |res|
puts "status: #{res.status}"
puts "body: #{JSON.parse(res.body.to_s)}"
end
# puts responses.map(&:status)

View File

@ -68,7 +68,8 @@ module HTTPX
end
%w[
proxy params form json body follow ssl max_retries
params form json body
proxy follow ssl max_retries
].each do |method_name|
def_option(method_name)
end

View File

@ -1,19 +1,49 @@
# frozen_string_literal: true
require "http/form_data"
require "json"
module HTTPX
class Request
METHODS = [
# RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1
:options, :get, :head, :post, :put, :delete, :trace, :connect,
# RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV
:propfind, :proppatch, :mkcol, :copy, :move, :lock, :unlock,
# RFC 3648: WebDAV Ordered Collections Protocol
:orderpatch,
# RFC 3744: WebDAV Access Control Protocol
:acl,
# RFC 6352: vCard Extensions to WebDAV -- CardDAV
:report,
# RFC 5789: PATCH Method for HTTP
:patch,
# draft-reschke-webdav-search: WebDAV Search
:search
].freeze
USER_AGENT = "httpx.rb/#{VERSION}"
attr_reader :verb, :uri, :headers, :body
def initialize(verb, uri, headers: {}, **options)
def initialize(verb, uri, options)
@verb = verb.to_s.downcase.to_sym
@uri = URI(uri)
@headers = Headers.new(headers)
@body = nil
@options = Options.new(options)
raise(Error, "unknown method: #{verb}") unless METHODS.include?(@verb)
@headers = Headers.new(@options.headers)
@headers["user-agent"] ||= USER_AGENT
@headers["accept"] ||= "*/*"
@body = Body.new(@headers, @options)
end
def scheme
@ -36,5 +66,57 @@ module HTTPX
port_string = @uri.port == @uri.default_port ? nil : ":#{@uri.port}"
"#{host}#{port_string}"
end
class Body
def initialize(headers, options)
@headers = headers
@body = case
when options.body
options.body
when options.form
form = HTTP::FormData.create(options.form)
@headers["content-type"] = form.content_type
@headers["content-length"] = form.content_length
form
when options.json
body = JSON.dump(options.json)
@headers["content-type"] = "application/json; charset=#{body.encoding.name.downcase}"
@headers["content-length"] = body.bytesize
body
end
end
def each(&block)
if @body.respond_to?(:read)
IO.copy_stream(@body, ProcIO.new(block))
elsif @body.respond_to?(:each)
@body.each(&block)
else
block[@body]
end
end
def bytesize
return 0 if @body.nil?
if @body.respond_to?(:bytesize)
@body.bytesize
elsif @body.respond_to?(:size)
@body.size
else
raise Error, "cannot determine size of body: #{@body.inspect}"
end
end
end
class ProcIO
def initialize(block)
@block = block
end
def write(data)
@block.call(data)
data.bytesize
end
end
end
end