280 Commits
Author SHA1 Message Date
Hiroshi SHIBATAandClaude Opus 5.5 6095c59c7e [ruby/net-http] Stop loading resolv from net/http
Net::HTTP required the whole DNS resolver, which also reads the system DNS configuration at load time, only to match Resolv::IPv4::Regex and Resolv::IPv6::Regex when deciding whether to send SNI. Use the same inlined regexps as the copy vendored in RubyGems, so that the two stay identical.

https://github.com/ruby/net-http/commit/5b42d75812

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 03:58:10 +00:00
Sutou Kouhei 981b020a9f [ruby/net-http] Don't use trailing spaces in test (https://github.com/ruby/net-http/pull/350)
ruby/ruby removes trailing spaces in here document:
https://github.com/ruby/ruby/commit/757d36142bd474c166639acade2988b901878ce6

https://github.com/ruby/net-http/commit/5c7596a433
2026-10-07 12:05:32 +09:00
git 757d36142b * remove trailing spaces. [ci skip] 2026-10-06 23:37:54 +00:00
Sutou Kouhei b45655470c [ruby/net-http] Treat a whitespace-only header line as obs-fold
(https://github.com/ruby/net-http/pull/348)

The current implementation has a problem with the following case:

```ruby
print("HTTP/1.1 200 OK\r\n")
print("Content-Length: 5\r\n")
print(" \t\r\n")
print("X-After: value\r\n")
print("\r\n")
print("hello")
```

The `" \t\r\n"` line should be processed as obs-fold in RFC 9112:

https://www.rfc-editor.org/rfc/rfc9112.html#section-5.2

>     obs-fold     = OWS CRLF RWS
>                  ; obsolete line folding
>
>     A user agent that receives an obs-fold in a response message that
>     is not within a "message/http" container MUST replace each received
>     obs-fold with one or more SP octets prior to interpreting the field
>     value.

But it's processed as the header part end:

Header:

```text
HTTP/1.1 200 OK
Content-Length: 5
```

Body:

```text
X-After: value

hello
```

It must be processed as the following (whitespace only obs-fold is
ignored):

Header:

```text
HTTP/1.1 200 OK
Content-Length: 5
X-After: value
```

Body:

```text
hello
```

https://github.com/ruby/net-http/commit/6e2bc82919
2026-10-06 23:37:25 +00:00
kares c442e94e99 [ruby/net-http] test: refactor assert to pass with nil as well
JRuby doesn't report session re-use and returns nil

https://github.com/ruby/net-http/commit/44af00331d
2026-09-08 10:37:58 +00:00
Hiroshi SHIBATAandClaude Opus 5 4eb03b31cb [ruby/net-http] Let Transfer-Encoding override Content-Length
Once chunked is not the final transfer coding, read_body_0 fell through
to Content-Length and framed the body by it, which leaves the client and
the server disagreeing about where the response ends.

See RFC 9112 Section 6.3:
https://www.rfc-editor.org/rfc/rfc9112.html#section-6.3

    If a message is received with both a Transfer-Encoding and a
    Content-Length header field, the Transfer-Encoding overrides the
    Content-Length.

https://github.com/ruby/net-http/commit/9fb5b93b52

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 02:55:16 +00:00
Hiroshi SHIBATAandClaude Opus 5 21bc49cf73 [ruby/net-http] Require chunked to be the final transfer coding
Net::HTTPHeader#chunked? matched the token anywhere in
Transfer-Encoding, so a response carrying `chunked, gzip` was
chunk-framed and the bytes after the terminating chunk were left
unread on the connection.

See RFC 9112 Section 6.3:
https://www.rfc-editor.org/rfc/rfc9112.html#section-6.3

    If a Transfer-Encoding header field is present in a response and
    the chunked transfer coding is not the final encoding, the message
    body length is determined by reading the connection until it is
    closed by the server.

https://github.com/ruby/net-http/commit/e70762aaf9

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 02:55:16 +00:00
Sutou Kouhei 2c260b8dec [ruby/net-http] Make Content-Length handling strict
(https://github.com/ruby/net-http/pull/324)

`Content-Length` value must have only digits.

See also RFC 9110 Section 8.6:
https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6

    Content-Length = 1*DIGIT

The current implementation accepts garbage before/after digits such as
`abc5` and `5abc`.

This rejects these invalid values.

But this accepts same values in one `Content-Length`

    Content-Length: 5, 5

and in multiple `Content-Length`es:

    Content-Length: 5
    Content-Length: 5

This is for the following part in the RFC:

https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6-13

> Likewise, a sender MUST NOT forward a message with a Content-Length
> header field value that does not match the ABNF above, with one
> exception: a recipient of a Content-Length header field value
> consisting of the same decimal value repeated as a comma-separated
> list (e.g, "Content-Length: 42, 42") MAY either reject the message
> as invalid or replace that invalid field value with a single
> instance of the decimal value, since this likely indicates that a
> duplicate was generated or combined by an upstream message
> processor.

https://github.com/ruby/net-http/commit/23e859e92e
2026-08-26 00:46:26 +00:00
Hiroshi SHIBATAandClaude Opus 5 05e1f1f648 [ruby/net-http] Limit the number of informational responses per request
A peer that keeps sending 1xx responses keeps the client in the read
loop of transport_request indefinitely, since the per-response header
limit resets for each response. Cap the count at 100, the same value
CPython's http.client uses.

https://github.com/ruby/net-http/commit/39cf5f648a

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 00:33:27 +00:00
Hiroshi SHIBATAandClaude Fable 5 331568b2a9 [ruby/net-http] Limit read length of a single response line
The response header cap added by #219 applies only once a complete line
has arrived, so a server that never sends a line terminator can still
grow the read buffer without bound, as reported in #315. Read the
status line, header lines, chunk-size lines and chunk trailers through
net-protocol's readuntil(limit:) so they fail with
Net::HTTPBadResponse at MAX_RESPONSE_HEADER_LENGTH, and require the
net-protocol that provides it.

The cumulative header budget stays separate from the per-line limit so
that exhausting the total still reports 'response header too large'
rather than blaming a line that is not long.

https://github.com/ruby/net-http/issues/315

https://github.com/ruby/net-http/commit/132c8cc1b1

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 23:13:17 +00:00
Sean Doyle 59d4afaade [ruby/net-http] Add support for HTTP QUERY method
Closes https://github.com/ruby/net-http/issues/202

As of June 2026, [RFC 10008][] is a proposed standard.

From the RFC Abstract:

> This specification defines the QUERY method for HTTP. A QUERY requests
> that the request target process the enclosed content in a safe and
> idempotent manner and then respond with the result of that processing.
> This is similar to POST requests, but QUERY requests can be
> automatically repeated or restarted without concern for partial state
> changes.

This commit proposes support for the HTTP Query method by way of the
`Net::HTTP::Query` class along with the corresponding `#query` and
`#request_query` methods.

[RFC 10008]: https://www.rfc-editor.org/rfc/rfc10008.html

https://github.com/ruby/net-http/commit/76b11b3a26
2026-07-10 03:29:36 +00:00
Nobuyoshi Nakada 498a2cbc53 [ruby/net-http] Fix FD leaks
https://github.com/ruby/net-http/commit/69f6f6dedd
2026-06-24 10:38:59 +00:00
5900b2f53d [ruby/net-http] Limit the total size of response headers
each_response_header read header lines until the blank separator with no
bound on their total size, so a server could exhaust client memory by
sending a large header block. Cap the cumulative size at 1 MiB and raise
Net::HTTPBadResponse once it is exceeded.

https://github.com/ruby/net-http/commit/ebe8f3876f

Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 16:02:15 +09:00
6f3e462182 [ruby/net-http] Validate header key and field value length in set_field
The length limits only ran in initialize_http_header, which responses
bypass: each_response_header builds the response through add_field and
set_field, so an oversized response header field was never bounded. Check
the field value length in set_field and append_field_value, and fold the
key length check into validate_field_name so set_field and
initialize_http_header share one place for validating field names.

https://github.com/ruby/net-http/commit/ab084fdc0c

Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 16:02:15 +09:00
Hiroshi SHIBATAandClaude Fable 5 fce7fb63fc [ruby/net-http] Reject CR/LF in multipart boundary
A custom boundary is interpolated into the part separators as-is, so a
boundary containing CR/LF could forge part headers in the same way as
the field name and filename.

https://github.com/ruby/net-http/commit/44c480b336

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 01:50:53 +00:00
Hiroshi SHIBATAandClaude Fable 5 bb4b4f1fdf [ruby/net-http] Coerce multipart content type to a string before validating
The CR/LF check via Regexp#match? requires a String, but the per-part
content type was previously interpolated through to_s and accepted any
object such as a Symbol. Coerce it first to keep that behavior.

https://github.com/ruby/net-http/commit/c07d6581ce

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 01:50:53 +00:00
Hiroshi SHIBATAandClaude Fable 5 94c133a368 [ruby/net-http] Reject CR/LF in multipart field name, filename, and content type
encode_multipart_form_data interpolated the field name, filename, and
per-part content type into Content-Disposition and Content-Type lines
with only quote_string escaping backslash and double quote, so CR/LF in
any of them could forge part headers and tamper with the request.

Fixes https://github.com/ruby/net-http/issues/195

https://github.com/ruby/net-http/commit/02a962fce2

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 01:50:53 +00:00
Hiroshi SHIBATAandClaude Fable 5 cb8a34d785 [ruby/net-http] Validate Content-Type value set by set_content_type
set_content_type assigned to @header directly, bypassing the CR/LF
validation in set_field, so a crafted media type or parameter could
inject header lines.

https://github.com/ruby/net-http/commit/5fe0f96190

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 01:50:53 +00:00
Hiroshi SHIBATAandClaude Fable 5 ebddeca11d [ruby/net-http] Reject control characters and colon in header field names
Field values and the request line are already validated against CR/LF,
but field names were interpolated into the request as-is, allowing
header injection via the key. Validate names in set_field and
initialize_http_header, which cover all paths into @header with a
user-supplied key.

https://github.com/ruby/net-http/commit/4f13ea5047

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 01:50:53 +00:00
Kazuki Yamaguchi b80fc8bd84 [ruby/net-http] Freeze more constants for Ractor compatibility
Freeze Net::HTTP::SSL_ATTRIBUTES and IDEMPOTENT_METHODS_. Both constants
have been marked as :nodoc:.

Together with https://github.com/ruby/openssl/issues/521, this enables
HTTPS clients in non-main Ractors on Ruby 4.0.

https://github.com/ruby/net-http/commit/f24b3b358b
2025-12-17 15:47:43 +09:00
Kazuki Yamaguchi 700487ce21 [ruby/net-http] Refactor HTTPS tests
This contains various improvements in tests for openssl integration:

  - Remove DHE parameters from test servers. OpenSSL is almost always
    compiled with ECC support nowadays and will prefer ECDHE over DHE.
  - Remove an outdated omission for a bug in OpenSSL 1.1.0h released in
    2018. None of our CI systems use this specific OpenSSL version.
  - Use top-level return to skip tests if openssl is unavailable.
  - Refactor tests for Net::HTTP#verify_callback.

https://github.com/ruby/net-http/commit/35c1745a26
2025-12-15 06:08:39 +00:00
2ab21f56f9 [ruby/net-http] Fix handling of IPv6 literal hosts in Net::HTTPGenericRequest
Update uri dependency to version 0.11.0 or later to use `URI::HTTP#authority` and `URI#parse` without scheme

https://github.com/ruby/net-http/commit/3d4f06bd7f

Co-authored-by: 0x1eef <0x1eef@users.noreply.github.com>
Co-authored-by: Sorah Fukumori <sora134@gmail.com>
2025-11-13 14:33:22 +00:00
Hiroshi SHIBATA 82e3312493 [ruby/net-http] Fixed test case for default content-type.
I changed content-type of request to "application/octet-stream" if request didn't have
content-type.

https://github.com/ruby/net-http/commit/fc5870d2ac
2025-06-11 03:35:12 +00:00
Hiroshi SHIBATA fab133e629 Use EnvUtil.apply_timeout_scale 2025-04-03 20:03:18 +09:00
Hiroshi SHIBATA 3f152ce767 Extend open_timeout for test failure on s390x
https://rubyci.s3.amazonaws.com/s390x/ruby-master/log/20250403T060004Z.fail.html.gz
2025-04-03 20:03:18 +09:00
Charles Oliver Nutter 89c9a9fd03 [ruby/net-http] Don't double-interrupt the test HTTP server
The shutdown process here attempted to terminate the test server
by interrupting it with Thread#kill, and then proceeded to close
the server and join the thread. The kill does indeed interrupt
the accept call, but the close call could also interrupt the
thread as part of notifying blocked threads waiting on that
socket call.

In JRuby, where all of this can happen at the same time, it leads
to the following scenario:

* The server thread enters TCPServer#accept and blocks.
* The main thread calls Thread#kill to interrupt the accept call.
* The server thread wakes up and starts to propagate the kill.
  There is a slight delay between this wakeup and removing the
  server thread from the TCPServer's blocked threads list.
* The main thread calls TCPServer#close, which sees that the server
  thread is still in the blocked list, so it initiates a second
  interrupt to raise IOError "closed in another thread" on the
  server thread.
* As the kill is bubbling out, another check for interrupts occurs,
  causing it to see the new raise interrupt and propagate that
  instead of the active kill.
* Because the server is now closed and the rescue here is empty,
  the server loop will endlessly attempt and fail to call accept.

I was unable to determine how CRuby avoids this race. There may be
code that prevents an active kill interrupt from triggering
further interrupts.

In order to get these tests running on JRuby, I've made the
following changes:

* Only kill the thread; one interrupt is sufficient to break it
  out of the accept call.
* Ensure outside the server loop that the server gets closed. This
  happens within the server thread, so triggers no new interrupts.
* Minor cleanup for the pattern of using @ssl_server or @server.

This change avoids the race in JRuby (and possibly other parallel-
threaded implementations) and does not impact the behavior of the
tests.

https://github.com/ruby/net-http/commit/54025b3870
2024-12-31 10:00:41 +00:00
Misaki Shioi fd4b27472e Do not wait connection attempt delay without in progress fds (#12087)
Do not wait Connection Attempt Delay without in progress fds

Reset Connection Attempt Delay when connection fails and there is no other socket connection in progress.
This is intended to resolve an issue that was temporarily worked around in Pull Request #12062.

`TCPServer::new` (used in tests such as `TestNetHTTP_v1_2_chunked#test_timeout_during_non_chunked_streamed_HTTP_session_write`) can only connect over either IPv6 or IPv4, depending on the environment.
Since HEv2 attempts to connect over IPv6 first, environments where IPv6 connections are unavailable return ECONNREFUSED immediately.
In such cases, the client should immediately retry the connection over IPv4.
However, HEv2 includes a specification for a "Connection Attempt Delay," where it waits 250ms after the previous connection attempt before starting the next one.
This delay causes Net::OpenTimeout (100ms) to be exceeded while waiting for the next connection attempt to start.

With this change, when a connection attempt fails, if there are sockets still attempting to connect and there are addresses yet to be tried, the Connection Attempt Delay will be resetted, allowing the next connection attempt to start immediately.

---

Additionally, the following minor fixes have been made:

- The `nfds` value used for select(2) is now reset with each wait.
2024-11-15 00:25:59 +09:00
Misaki Shioi fee706d9dd Allow Net::HTTP#request to raise Net::OpenTimeout (#12062)
with a TCPSoerver that is only listening
to avoid AssertionFailedError on Ubuntu.

---

The tests such as
`TestNetHTTP_v1_2_chunked#test_timeout_during_non_chunked_streamed_HTTP_session_write`
expect to raise a `Net::WriteTimeout` due to a failure in writing to the server.

However, on Ubuntu environments,
the server immediately returns a "Connection Refused" in such cases.
The socket created with `TCPSocket.new` that supports HEv2 catches this immediately
and raises a `Net::OpenTimeout`.
As a result, these tests fail due to raising a different exception than expected.
This PR adds `Net::OpenTimeout` asexceptions to avoid these test failures.
2024-11-12 19:14:05 +09:00
Yusuke Endoh 6ae05584bd [ruby/net-http] Prevent warnings
```
/home/chkbuild/chkbuild/tmp/build/20240913T003003Z/ruby/test/net/http/utils.rb:32: warning: assigned but unused variable - e
/home/chkbuild/chkbuild/tmp/build/20240913T003003Z/ruby/test/net/http/utils.rb:61: warning: assigned but unused variable - version
/home/chkbuild/chkbuild/tmp/build/20240913T003003Z/ruby/test/net/http/utils.rb:124: warning: method redefined; discarding old query
```

https://github.com/ruby/net-http/commit/6f818346ce
2024-09-13 02:39:11 +00:00
Nobuyoshi Nakada 30f57637ee Wait for server threads to finish 2024-07-30 07:33:43 +08:00
Hiroshi SHIBATA 83a99bdbe6 [ruby/net-http] Removed needless NullWriter class
https://github.com/ruby/net-http/commit/ddb2a81aed
2024-07-26 01:45:02 +00:00
Hiroshi SHIBATA 2a12e4ffec To avoid fd leak with fetch request for SSL server 2024-07-17 17:37:57 +09:00
Hiroshi SHIBATA f4c642edb1 Fixed fd leak from TCPServer
```
Leaked file descriptor: HTTPSProxyTest#test_https_proxy_ssl_connection: 8 : #<TCPServer:fd 8, AF_INET, 127.0.0.1, 63104>
```
2024-07-17 17:37:57 +09:00
Hiroshi SHIBATA 9acc0efdc1 Use fixture certificates to fix test failure with RHEL9.
http://rubyci.s3.amazonaws.com/rhel9/ruby-master/log/20240711T213004Z.fail.html.gz

```
  1) Error:
HTTPSProxyTest#test_https_proxy_ssl_connection:
OpenSSL::X509::CertificateError: invalid digest
    /home/chkbuild/chkbuild/tmp/build/20240711T213004Z/ruby/test/net/http/test_https_proxy.rb:63:in 'OpenSSL::X509::Certificate#sign'
    /home/chkbuild/chkbuild/tmp/build/20240711T213004Z/ruby/test/net/http/test_https_proxy.rb:63:in 'HTTPSProxyTest#test_https_proxy_ssl_connection'
```
2024-07-12 09:15:12 +09:00
Evgeni Golov bc1b4235fb [ruby/net-http] implement talking SSL to the proxy too
https://bugs.ruby-lang.org/issues/16482

https://github.com/ruby/net-http/commit/ae2d83f88b
2024-07-11 01:56:08 +00:00
fatkodima 70bdc0f777 [ruby/net-http] Add ability to configure default settings for new connections
https://github.com/ruby/net-http/commit/fed3dcd0c2
2024-07-11 01:51:03 +00:00
MSP-Greg 9f4b45fbf7 [ruby/net-http] test_https.rb - fix test_session_reuse_but_expire
https://github.com/ruby/net-http/commit/5544243c41
2024-07-11 01:22:10 +00:00
git 8c69caa495 * append newline at EOF. [ci skip] 2024-07-10 23:06:20 +00:00
Hiroshi SHIBATA 840f7ebfde [ruby/net-http] Commented out unfinished chunked test
https://github.com/ruby/net-http/commit/6376592cb4
2024-07-10 23:06:10 +00:00
Hiroshi SHIBATA 492b505d95 [ruby/net-http] Removed needless warning
https://github.com/ruby/net-http/commit/d867edc0fe
2024-07-10 23:06:10 +00:00
Hiroshi SHIBATA b11aba503b [ruby/net-http] Split POST test because new dummy server can't handle continuouse POST request
https://github.com/ruby/net-http/commit/54a99b9f0c
2024-07-10 23:06:09 +00:00
Hiroshi SHIBATA e77bc17e5d [ruby/net-http] Write log after server start, not handling request
https://github.com/ruby/net-http/commit/205bac757a
2024-07-10 23:06:09 +00:00
Hiroshi SHIBATA 6428536146 [ruby/net-http] Split test class because TCPServer couldn't accept localhost and 127.0.0.1 both
https://github.com/ruby/net-http/commit/749a1b3197
2024-07-10 23:06:08 +00:00
Hiroshi SHIBATA 4e6463ad7a [ruby/net-http] Support chunked data and fixed test failure with multipart/form-data
https://github.com/ruby/net-http/commit/b38c2795a9
2024-07-10 23:06:08 +00:00
Hiroshi SHIBATA 87a45af105 [ruby/net-http] Removed server-side log test
https://github.com/ruby/net-http/commit/9c16c383ce
2024-07-10 23:06:07 +00:00
Hiroshi SHIBATA 5e6f04abc8 [ruby/net-http] Fix wrong hostname with test_max_version test
https://github.com/ruby/net-http/commit/f00d198433
2024-07-10 23:06:07 +00:00
Hiroshi SHIBATA c7eb9ac6f9 [ruby/net-http] Rewrite WEBrick server with TCPServer and OpenSSL::SSL::SSLServer
https://github.com/ruby/net-http/commit/b01bcf6d7f
2024-07-10 23:06:06 +00:00
Xi Ruoyao 03f8477566 [ruby/net-http] Skip test_session_reuse_but_expire with OpenSSL 3.3
OpenSSL 3.3.0 9 Apr 2024 is also broken.

Signed-off-by: Xi Ruoyao <xry111@xry111.site>

https://github.com/ruby/net-http/commit/ab525c956d
2024-04-25 08:01:53 +00:00
NARUSE, Yui 64b6a018a3 Fix test session reuse but expire (#9824)
* OpenSSL 3.2.1 30 Jan 2024 is also broken

Import 4506461072 from ruby_3_3 branch
tentatively.
2024-02-07 10:59:59 +09:00
NARUSE, Yui bc79229be9 Show OpenSSL version in the error message of assert_equal 2024-02-03 19:39:17 +09:00