public static ResponseHeaders maybeUpdateContentLengthAndEndOfStream(ResponseHeaders headers,
                                                                         HttpData content,
                                                                         HttpHeaders trailers,
                                                                         boolean isAggregatedResponse) {
        requireNonNull(headers, "headers");
        requireNonNull(content, "content");
        requireNonNull(trailers, "trailers");

        final HttpStatus status = headers.status();

        if (status.isContentAlwaysEmpty()) {
            if (status != HttpStatus.NOT_MODIFIED) {
                if (headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
                    return headers.toBuilder()
                                  .removeAndThen(HttpHeaderNames.CONTENT_LENGTH)
                                  .endOfStream(true)
                                  .build();
                }
            } else {
                // 304 response can have the "content-length" header when it is a response to a conditional
                // GET request. See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
            }

            return maybeSetEndOfStream(headers, 0, isAggregatedResponse);
        }

        if (!trailers.isEmpty()) {
            // Some of the client implementations such as "curl" ignores trailers if
            // the "content-length" header is present. We should not set "content-length" header when
            // trailers exists so that those clients can receive the trailers.
            // The response is sent using chunked transfer encoding in HTTP/1 or a DATA frame payload
            // in HTTP/2, so it's no worry.
            if (headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
                final ResponseHeadersBuilder builder = headers.toBuilder();
                builder.remove(HttpHeaderNames.CONTENT_LENGTH);
                return builder.build();
            }

            return headers;
        }

        final long contentLength;
        if (headers.isContentLengthUnknown()) {
            // Do not set a content-length for a streaming response.
            contentLength = -1;
        } else {
            if (headers.contentLength() > 0 && content.isEmpty()) {
                // If HEAD method is used, a content-length can exist with an empty content.
                contentLength = headers.contentLength();
            } else {
                contentLength = content.length();
            }
        }

        if (contentLength >= 0) {
            return headers.toBuilder()
                          .contentLength(contentLength)
                          .removeAndThen(HttpHeaderNames.TRANSFER_ENCODING)
                          .build();
        }

        // A streaming content or a content length is set and the content is empty.
        // Do not overwrite the header because a response to a HEAD request
        // will have no content even if it has non-zero content-length header
        // or a null content-length header for chunked-transfer encoding.
        return maybeSetEndOfStream(headers, content.length(), isAggregatedResponse);
    }
Returns a {@link ResponseHeaders} whose {@link HttpHeaderNames#CONTENT_LENGTH} is added or removed
according to the status of the specified {@code headers}, {@code content} and {@code trailers}.
The {@link HttpHeaderNames#CONTENT_LENGTH} is removed when:
<ul>
  <li>the status of the specified {@code headers} is one of {@link HttpStatus#NO_CONTENT},
      {@link HttpStatus#RESET_CONTENT} or {@link HttpStatus#NOT_MODIFIED}</li>
  <li>the trailers exists</li>
</ul>
The {@link HttpHeaderNames#CONTENT_LENGTH} is added when the state of the specified {@code headers}
does not meet the conditions above and {@link HttpHeaderNames#CONTENT_LENGTH} is not present
regardless of the fact that the content is empty or not.

<p>{@link ResponseHeaders#isEndOfStream()} is set to {@code true} if both {@link HttpData} and trailers
are empty.

@throws IllegalArgumentException if the specified {@code content} is not empty when the specified
                                 {@link HttpStatus} is one of {@link HttpStatus#NO_CONTENT},
                                 {@link HttpStatus#RESET_CONTENT} and {@link HttpStatus#NOT_MODIFIED}.
core/src/main/java/com/linecorp/armeria/internal/common/ArmeriaHttpUtil.java