Skip to content

V2 client hangs on every GET: Transfer-Encoding: chunked is set on requests without a body #271

Description

@aeuillot

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions