** Enhancements requests ** Before explaining how you would like things to work, please describe a concrete use case for this feature and how you have tried to solve this so far.

Enhancement Request

Replace new HttpHeaders(...) constructor with static factory method HttpHeaders.backedBy(...) and add also a method called HttpHeaders.copyOf(...).

Use cases

There are already use cases for a backedBy method that behaves the way the constructor does now.

Use cases for a copyOf method that creates a copy and is not backed by the previous map. - Copying HttpHeaders to be redacted for logging. - Copying HttpHeaders to mutated for security-related headers. - Copying a default HttpHeaders object and adding customized headers. (Yes, I am aware that there are defaultHeader(...) methods on WebClient, RestTemplate, etc.) - Copying a HttpHeaders during proxy type operations.

Background

Unless one is a seasoned Spring maintainer; the behavior of the HttpHeaders(...) constructor seems very surprising.

Take the following example code.

static HttpHeaders redactProtectedHeaders(HttpHeaders headers) {  
  HttpHeaders httpHeadersCopy = new HttpHeaders(headers);  
  Optional.ofNullable(httpHeadersCopy.get("Authorization"))  
      .ifPresent(authorizationHeaderValues -> 
            httpHeadersCopy.replace("Authorization", redact(authorizationHeaderValues)));  
  return httpHeadersCopy;  
}
 ```

The above code is incorrect in that the second instance of HttpHeaders is not a true deep copy.
Changes to the copy are also changed in the first instance.
If (and that is a big if) the developer reads the documentation and HttpHeadersTest unit test;
they might be led to write:
```java
HttpHeaders httpHeadersCopy = new HttpHeaders(HttpHeaders.readOnlyHttpHeaders(headers));

However, this is not intuitive and also does not protect the original headers object from being mutated since ReadOnlyHttpHeaders does not make the underlying MultiValueMap read-only. So then the developer writes this code since there is not a copy/clone method.

HttpHeaders httpHeadersCopy = new HttpHeaders();  
headers.forEach((key, values) -> httpHeadersCopy.put(key, new ArrayList<>(values)));

I've read the following related issues and I recognize there are historical reasons for why the constructor is the way it is. https://github.com/spring-projects/spring-framework/issues/28336 https://github.com/spring-projects/spring-framework/issues/33789 https://github.com/spring-projects/spring-framework/issues/32116 This comment stuck out:

Unlike collection-related constructors (like HashMap or ArrayList), this is not about copying entries to a new collection, but creating a new HttpHeaders instance backed by an existing map.

This comment, while explaining the desired behavior, acknowledges the root of the surprise in that there is an implied norm given by collection-related constructors. For developers who have trained on collections, the conflicting behavior of HttpHeaders is disorienting.

I'd ask that the new HttpHeaders(...) constructors be deprecated, made private, and eventually fully replaced with static factory methods HttpHeaders.backedBy(...) and HttpHeaders.copyOf(...) to remove any ambiguity, keep the desired behavior for adapting existing structures, and also provide the functionality of creating deep clones.