Environment
mindee 5.4.0 (also present on main at 49f3ec8)
- Ruby 4.0.5, Net::HTTP from stdlib
Description
Mindee::V2::HTTP::MindeeApiV2#poll sets Transfer-Encoding: chunked on a Net::HTTP::Get
request, but no body is ever written. The API therefore waits for a chunked body — and for the
terminating zero-length chunk — that never arrives, while the client waits for a response. The
request only ends when the client's read_timeout fires (120 s by default).
Every V2 GET goes through poll, so Client#get_job, Client#get_result and the built-in
polling loop Client#enqueue_and_get_result are all affected. Client#enqueue works, being a
POST with an actual multipart body.
In practice this makes asynchronous V2 usage unusable without a webhook: the document is
extracted correctly server-side, but the result can never be fetched.
Reproduction
No API key needed — the failure mode shows up on the 401 path:
require "net/http"
uri = URI("https://api-v2.mindee.net/v2/jobs/00000000-0000-0000-0000-000000000000")
[ false, true ].each do |chunked|
request = Net::HTTP::Get.new(uri, { "Authorization" => "dummy", "User-Agent" => "probe" })
request["Transfer-Encoding"] = "chunked" if chunked
started = Time.now
begin
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, open_timeout: 8, read_timeout: 8) do |http|
puts "chunked=#{chunked} code=#{http.request(request).code} in #{(Time.now - started).round(2)}s"
end
rescue => error
puts "chunked=#{chunked} #{error.class} after #{(Time.now - started).round(2)}s"
end
end
Output:
chunked=false code=401 in 0.27s
chunked=true Net::ReadTimeout after 16.34s
Same result through the gem itself: Mindee::V2::Client.new(api_key: "dummy").get_job(job_id)
hangs until the read timeout instead of raising a 401.
Expected behaviour
GET requests should not announce a request body. get_job and get_result should return as soon
as the API responds.
Root cause
lib/mindee/v2/http/mindee_api_v2.rb on main, lines 76 and 148:
req = Net::HTTP::Get.new(uri, headers)
req['Transfer-Encoding'] = 'chunked'
The header was introduced in edb4163 ("switch to 'Transfer-Encoding: chunked' to prevent
Net::HTTP from writing temporary files", #189), where it applied only to V1 multipart POSTs and
is legitimate. It was then carried over to the new V2 GET helpers in ab1f275 ("add support for
Client V2", #194).
Suggested fix
Drop the two req['Transfer-Encoding'] = 'chunked' lines that apply to Net::HTTP::Get, keeping
the one on the enqueue POST (line 209). Setting open_timeout alongside read_timeout in
Net::HTTP.start would also be welcome: an unreachable host currently blocks for the system TCP
timeout rather than the configured one.
Workaround
Redefining poll without the header in an initializer restores normal behaviour — GET responses
come back in ~0.3 s.
Environment
mindee5.4.0 (also present onmainat 49f3ec8)Description
Mindee::V2::HTTP::MindeeApiV2#pollsetsTransfer-Encoding: chunkedon aNet::HTTP::Getrequest, but no body is ever written. The API therefore waits for a chunked body — and for the
terminating zero-length chunk — that never arrives, while the client waits for a response. The
request only ends when the client's
read_timeoutfires (120 s by default).Every V2 GET goes through
poll, soClient#get_job,Client#get_resultand the built-inpolling loop
Client#enqueue_and_get_resultare all affected.Client#enqueueworks, being aPOST with an actual multipart body.
In practice this makes asynchronous V2 usage unusable without a webhook: the document is
extracted correctly server-side, but the result can never be fetched.
Reproduction
No API key needed — the failure mode shows up on the 401 path:
Output:
Same result through the gem itself:
Mindee::V2::Client.new(api_key: "dummy").get_job(job_id)hangs until the read timeout instead of raising a 401.
Expected behaviour
GET requests should not announce a request body.
get_jobandget_resultshould return as soonas the API responds.
Root cause
lib/mindee/v2/http/mindee_api_v2.rbonmain, lines 76 and 148:The header was introduced in edb4163 ("switch to 'Transfer-Encoding: chunked' to prevent
Net::HTTP from writing temporary files", #189), where it applied only to V1 multipart POSTs and
is legitimate. It was then carried over to the new V2 GET helpers in ab1f275 ("add support for
Client V2", #194).
Suggested fix
Drop the two
req['Transfer-Encoding'] = 'chunked'lines that apply toNet::HTTP::Get, keepingthe one on the enqueue POST (line 209). Setting
open_timeoutalongsideread_timeoutinNet::HTTP.startwould also be welcome: an unreachable host currently blocks for the system TCPtimeout rather than the configured one.
Workaround
Redefining
pollwithout the header in an initializer restores normal behaviour — GET responsescome back in ~0.3 s.