Skip to content

Commit

Permalink
multipart supported by default
Browse files Browse the repository at this point in the history
the plugin was now moved to the transcoder layer, where it is available
from the get-go.
  • Loading branch information
HoneyryderChuck committed Sep 20, 2023
1 parent 896914e commit 3f73d2e
Show file tree
Hide file tree
Showing 21 changed files with 468 additions and 560 deletions.
1 change: 1 addition & 0 deletions doc/release_notes/1_0_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* `:total_timeout` option has been removed (no session-wide timeout supported, use `:request_timeout`).
* `:read_timeout` and `:write_timeout` are now set to 60 seconds by default, and preferred over `:operation_timeout`;
* the exception being in the `:stream` plugin, as the response is theoretically endless (so `:read_timeout` is unset).
* The `:multipart` plugin is now loaded by default.

### plugins

Expand Down
96 changes: 0 additions & 96 deletions lib/httpx/plugins/multipart.rb

This file was deleted.

137 changes: 0 additions & 137 deletions lib/httpx/plugins/multipart/decoder.rb

This file was deleted.

84 changes: 52 additions & 32 deletions lib/httpx/transcoder/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,77 @@

require "forwardable"
require "uri"
require_relative "multipart"

module HTTPX::Transcoder
module Form
module_function
module HTTPX
module Transcoder
module Form
module_function

PARAM_DEPTH_LIMIT = 32
PARAM_DEPTH_LIMIT = 32

class Encoder
extend Forwardable
class Encoder
extend Forwardable

def_delegator :@raw, :to_s
def_delegator :@raw, :to_s

def_delegator :@raw, :to_str
def_delegator :@raw, :to_str

def_delegator :@raw, :bytesize
def_delegator :@raw, :bytesize

def initialize(form)
@raw = form.each_with_object("".b) do |(key, val), buf|
HTTPX::Transcoder.normalize_keys(key, val) do |k, v|
buf << "&" unless buf.empty?
buf << URI.encode_www_form_component(k)
buf << "=#{URI.encode_www_form_component(v.to_s)}" unless v.nil?
def initialize(form)
@raw = form.each_with_object("".b) do |(key, val), buf|
HTTPX::Transcoder.normalize_keys(key, val) do |k, v|
buf << "&" unless buf.empty?
buf << URI.encode_www_form_component(k)
buf << "=#{URI.encode_www_form_component(v.to_s)}" unless v.nil?
end
end
end
end

def content_type
"application/x-www-form-urlencoded"
def content_type
"application/x-www-form-urlencoded"
end
end
end

module Decoder
module_function
module Decoder
module_function

def call(response, *)
URI.decode_www_form(response.to_s).each_with_object({}) do |(field, value), params|
HTTPX::Transcoder.normalize_query(params, field, value, PARAM_DEPTH_LIMIT)
def call(response, *)
URI.decode_www_form(response.to_s).each_with_object({}) do |(field, value), params|
HTTPX::Transcoder.normalize_query(params, field, value, PARAM_DEPTH_LIMIT)
end
end
end
end

def encode(form)
Encoder.new(form)
end
def encode(form)
if multipart?(form)
Multipart::Encoder.new(form)
else
Encoder.new(form)
end
end

def decode(response)
content_type = response.content_type.mime_type
def decode(response)
content_type = response.content_type.mime_type

raise HTTPX::Error, "invalid form mime type (#{content_type})" unless content_type == "application/x-www-form-urlencoded"
case content_type
when "application/x-www-form-urlencoded"
Decoder
when "multipart/form-data"
Multipart::Decoder.new(response)
else
raise Error, "invalid form mime type (#{content_type})"
end
end

Decoder
def multipart?(data)
data.any? do |_, v|
Multipart::MULTIPART_VALUE_COND.call(v) ||
(v.respond_to?(:to_ary) && v.to_ary.any?(&Multipart::MULTIPART_VALUE_COND)) ||
(v.respond_to?(:to_hash) && v.to_hash.any? { |_, e| Multipart::MULTIPART_VALUE_COND.call(e) })
end
end
end
end
end
17 changes: 17 additions & 0 deletions lib/httpx/transcoder/multipart.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

require_relative "multipart/encoder"
require_relative "multipart/decoder"
require_relative "multipart/part"
require_relative "multipart/mime_type_detector"

module HTTPX::Transcoder
module Multipart
MULTIPART_VALUE_COND = lambda do |value|
value.respond_to?(:read) ||
(value.respond_to?(:to_hash) &&
value.key?(:body) &&
(value.key?(:filename) || value.key?(:content_type)))
end
end
end
Loading

0 comments on commit 3f73d2e

Please sign in to comment.