Skip to content

Commit 77f7239

Browse files
chore: broadly detect json family of content-type headers
1 parent 57a10b0 commit 77f7239

File tree

4 files changed

+31
-4
lines changed

4 files changed

+31
-4
lines changed

lib/openai/internal/util.rb

+9-4
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,11 @@ def writable_enum(&blk)
471471
end
472472
end
473473

474+
# @type [Regexp]
475+
JSON_CONTENT = %r{^application/(?:vnd(?:\.[^.]+)*\+)?json(?!l)}
476+
# @type [Regexp]
477+
JSONL_CONTENT = %r{^application/(?:x-)?jsonl}
478+
474479
class << self
475480
# @api private
476481
#
@@ -563,9 +568,9 @@ def encode_content(headers, body)
563568
body = body.inner if body.is_a?(OpenAI::Internal::Util::SerializationAdapter)
564569

565570
case [content_type, body]
566-
in [%r{^application/(?:vnd\.api\+)?json}, Hash | Array | -> { primitive?(_1) }]
571+
in [OpenAI::Internal::Util::JSON_CONTENT, Hash | Array | -> { primitive?(_1) }]
567572
[headers, JSON.fast_generate(body)]
568-
in [%r{^application/(?:x-)?jsonl}, Enumerable] unless body.is_a?(StringIO) || body.is_a?(IO)
573+
in [OpenAI::Internal::Util::JSONL_CONTENT, Enumerable] unless body.is_a?(StringIO) || body.is_a?(IO)
569574
[headers, body.lazy.map { JSON.fast_generate(_1) }]
570575
in [%r{^multipart/form-data}, Hash | Pathname | StringIO | IO]
571576
boundary, strio = encode_multipart_streaming(body)
@@ -611,15 +616,15 @@ def force_charset!(content_type, text:)
611616
# @return [Object]
612617
def decode_content(headers, stream:, suppress_error: false)
613618
case (content_type = headers["content-type"])
614-
in %r{^application/(?:vnd\.api\+)?json}
619+
in OpenAI::Internal::Util::JSON_CONTENT
615620
json = stream.to_a.join
616621
begin
617622
JSON.parse(json, symbolize_names: true)
618623
rescue JSON::ParserError => e
619624
raise e unless suppress_error
620625
json
621626
end
622-
in %r{^application/(?:x-)?jsonl}
627+
in OpenAI::Internal::Util::JSONL_CONTENT
623628
lines = decode_lines(stream)
624629
chain_fused(lines) do |y|
625630
lines.each { y << JSON.parse(_1, symbolize_names: true) }

rbi/lib/openai/internal/util.rbi

+3
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ module OpenAI
192192
def writable_enum(&blk); end
193193
end
194194

195+
JSON_CONTENT = T.let(%r{^application/(?:vnd(?:\.[^.]+)*\+)?json(?!l)}, Regexp)
196+
JSONL_CONTENT = T.let(%r{^application/(?:x-)?jsonl}, Regexp)
197+
195198
class << self
196199
# @api private
197200
sig do

sig/openai/internal/util.rbs

+3
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ module OpenAI
103103
(Enumerator::Yielder y) -> void
104104
} -> Enumerable[String]
105105

106+
JSON_CONTENT: Regexp
107+
JSONL_CONTENT: Regexp
108+
106109
def self?.write_multipart_chunk: (
107110
Enumerator::Yielder y,
108111
boundary: String,

test/openai/internal/util_test.rb

+16
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,22 @@ def test_joining_queries
157157
end
158158
end
159159

160+
class OpenAI::Test::RegexMatchTest < Minitest::Test
161+
def test_json_content
162+
cases = {
163+
"application/json" => true,
164+
"application/jsonl" => false,
165+
"application/vnd.github.v3+json" => true,
166+
"application/vnd.api+json" => true
167+
}
168+
cases.each do |header, _verdict|
169+
assert_pattern do
170+
OpenAI::Internal::Util::JSON_CONTENT.match?(header) => verdict
171+
end
172+
end
173+
end
174+
end
175+
160176
class OpenAI::Test::UtilFormDataEncodingTest < Minitest::Test
161177
class FakeCGI < CGI
162178
def initialize(headers, io)

0 commit comments

Comments
 (0)