From eef71d8eb3c80d2a4ddf9e15b916d37a1ac29db7 Mon Sep 17 00:00:00 2001 From: ksss Date: Sun, 18 Oct 2026 23:19:17 +0900 Subject: [PATCH] Add Net::HTTP#query and #request_query for net-http 0.10.0 net-http 0.10.0 (bundled with Ruby 4.1) added the HTTP QUERY method: Net::HTTP#query, Net::HTTP#request_query and the Net::HTTP::Query request class. Sync stdlib/net-http with the sig/net-http.rbs shipped in the net-http 0.10.0 gem, and define Net::HTTP::Query (present in lib/net/http/requests.rb but missing from the upstream sig) alongside the other request classes. The new test is omitted when the running net-http lacks #query. Co-Authored-By: Claude Fable 5.1 --- stdlib/net-http/0/net-http.rbs | 92 ++++++++++++++++++++++++++++++++++ test/stdlib/Net_HTTP_test.rb | 23 +++++++++ 2 files changed, 115 insertions(+) diff --git a/stdlib/net-http/0/net-http.rbs b/stdlib/net-http/0/net-http.rbs index b1ee16ffa8..e2d70db938 100644 --- a/stdlib/net-http/0/net-http.rbs +++ b/stdlib/net-http/0/net-http.rbs @@ -94,6 +94,7 @@ module Net # body = 'Some text' # http.post(path, body) # Can also have a block. # http.put(path, body) + # http.query(path, body) # Can also have a block. # http.delete(path) # http.options(path) # http.trace(path) @@ -222,6 +223,7 @@ module Net # * #options: OPTIONS. # * #trace: TRACE. # * #patch: PATCH. + # * #query, #request_query: QUERY. # # * [WebDAV methods](https://en.wikipedia.org/wiki/WebDAV#Implementation): # @@ -561,6 +563,8 @@ module Net # returns a response object. # * [#put](rdoc-ref:Net::HTTP#put): Sends a PUT request and returns a response # object. + # * [#query](rdoc-ref:Net::HTTP#query): Sends a QUERY request and returns a + # response object. # * [#request](rdoc-ref:Net::HTTP#request): Sends a request and returns a # response object. # * [#request_get](rdoc-ref:Net::HTTP#request_get): Sends a GET request and @@ -1689,6 +1693,27 @@ module Net # def put: (String path, String data, ?headers initheader) -> Net::HTTPResponse + # + # Sends a QUERY request to the server; returns an instance of a subclass of + # Net::HTTPResponse. + # + # The request is based on the Net::HTTP::Query object created from string + # `path`, string `data`, and initial headers hash `initheader`. + # + # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}' + # http = Net::HTTP.new(hostname) + # http.query('/todos/1', data) # => # + # + # Related: + # + # * Net::HTTP::Query: request class for HTTP method QUERY. + # * Net::HTTP.query: sends QUERY request, returns response body. + # + def query: (String path, String data, ?headers initheader, ?bot dest) ?{ (String body_segment) -> void } -> Net::HTTPResponse + # + # Sends a QUERY request to the server; forms the response into a + # Net::HTTPResponse object. + # + # The request is based on the Net::HTTP::Query object created from string `path`, + # string `data`, and initial headers hash `initheader`. + # + # With no block given, returns the response object: + # + # http = Net::HTTP.new(hostname) + # http.query('/todos') + # # => # + # + # With a block given, calls the block with the response body and returns the + # response object: + # + # http.request_query('/todos') do |res| + # p res + # end # => # + # + # Output: + # + # # + # + def request_query: (String path, String data, ?headers initheader) ?{ (Net::HTTPResponse response) -> void } -> Net::HTTPResponse + # + # Class for representing [HTTP method + # QUERY](https://www.rfc-editor.org/rfc/rfc10008.html): + # + # require 'net/http' + # uri = URI('http://example.com') + # hostname = uri.hostname # => "example.com" + # uri.path = '/posts' + # req = Net::HTTP::Query.new(uri) # => # + # req.body = '{"title": "foo","body": "bar","userId": 1}' + # req.content_type = 'application/json' + # res = Net::HTTP.start(hostname) do |http| + # http.request(req) + # end + # + # See [Request Headers](rdoc-ref:Net::HTTPRequest@Request+Headers). + # + # Properties: + # + # * Request body: yes. + # * Response body: yes. + # * [Safe](https://en.wikipedia.org/wiki/HTTP#Safe_method): yes. + # * [Idempotent](https://en.wikipedia.org/wiki/HTTP#Idempotent_method): yes. + # * [Cacheable](https://en.wikipedia.org/wiki/HTTP#Cacheable_method): yes. + # + # Related: + # + # * Net::HTTP#query: sends `QUERY` request, returns response object. + # + class HTTP::Query < HTTPRequest + METHOD: String + + REQUEST_HAS_BODY: bool + + RESPONSE_HAS_BODY: bool + end + # # Class for representing [WebDAV method # PROPFIND](http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND): diff --git a/test/stdlib/Net_HTTP_test.rb b/test/stdlib/Net_HTTP_test.rb index 50b8bf985c..f5fcc7e5e6 100644 --- a/test/stdlib/Net_HTTP_test.rb +++ b/test/stdlib/Net_HTTP_test.rb @@ -386,6 +386,29 @@ def test_http_verbs end end + def test_query + omit_unless Net::HTTP.method_defined?(:query), "Net::HTTP#query requires net-http 0.10.0+" + + with_server("localhost") do |uri| + assert_send_type "(String, String) -> Net::HTTPResponse", + Net::HTTP.start("localhost", uri.port), :query, "/todos", "{\"completed\": false}" + assert_send_type "(String, String, Hash[String, String]) -> Net::HTTPResponse", + Net::HTTP.start("localhost", uri.port), :query, "/todos", "{\"completed\": false}", { "Content-Type" => "application/json" } + assert_send_type "(String, String) { (String) -> untyped } -> Net::HTTPResponse", + Net::HTTP.start("localhost", uri.port), :query, "/todos", "{\"completed\": false}" do |string| string end + assert_send_type "(String, String, Hash[String, String]) { (String) -> untyped } -> Net::HTTPResponse", + Net::HTTP.start("localhost", uri.port), :query, "/todos", "{\"completed\": false}", { "Content-Type" => "application/json" } do |string| string end + assert_send_type "(String, String) -> Net::HTTPResponse", + Net::HTTP.start("localhost", uri.port), :request_query, "/todos", "{\"completed\": false}" + assert_send_type "(String, String, Hash[String, String]) -> Net::HTTPResponse", + Net::HTTP.start("localhost", uri.port), :request_query, "/todos", "{\"completed\": false}", { "Content-Type" => "application/json" } + assert_send_type "(String, String) { (Net::HTTPResponse) -> untyped } -> Net::HTTPResponse", + Net::HTTP.start("localhost", uri.port), :request_query, "/todos", "{\"completed\": false}" do |response| response end + assert_send_type "(String, String, Hash[String, String]) { (Net::HTTPResponse) -> untyped } -> Net::HTTPResponse", + Net::HTTP.start("localhost", uri.port), :request_query, "/todos", "{\"completed\": false}", { "Content-Type" => "application/json" } do |response| response end + end + end + def test_request with_server("localhost") do |uri| assert_send_type "(String, String) -> Net::HTTPResponse",