Skip to content

Further updates to HttpHeaders and header adapters to align with underlying header APIs #36354

@rstoyanchev

Description

@rstoyanchev

WebFlux introduced HttpHeaders adapters in Spring Framework 5.1 to map directly to underlying server header API's. Over time a mismatch between MultiValueMap and such header API's became clear.

Typically servers do not store headers in a map, but rather in an ordered collection, e.g. MimeHeaders in Tomcat or HttpFields in Jetty, trading convenience for more efficient access. The loss of efficiency is significant enough, or rather ignoring it can lead to use of innocent looking methods like size() that are inefficient and to real issues like #33823.

In 7.0 HttpHeaders no longer implements MultiValueMap to guide away from Map-like usage, see #33913, adding a dedicated key set to support iterator-based removal, and introducing header-focused alternatives to Map methods.

In 7.0.x we also introduced Servlet API header adapters with #36334, so that both Spring MVC and WebFlux use the header adapter approach.

For 7.1 we can pursue further changes in this direction:

  • decouple adapters from MutliValueMap, and avoid methods that aren't needed in HttpHeaders:

    addAll(MultiValueMap<String, String> map)
    containsValue(Object rawValue)
    putAll(Map<? extends String, ? extends List<String>> map)
    values()
    entrySet()

    Use a more focused contract, e.g. HttpHeadersAdapter and switch existing implementations to it. A default implementation, for new HttpHeaders(), could use LinkedCaseInsensitiveMap internally.

  • take further advantage of a header-focused contract, e.g. the put and remove methods return a List of existing values, which is typically not needed. We could provide void set(List) and use it everywhere instead.

  • The size() method is expensive due to the need to deduplicate across all header fields. We could consider deprecating it in favour of using headerNames() to obtain a set, which would keep it possible, but not as easy, and more clear.

  • HttpHeaders could provide some default implementation of equals/hashcode, useful for testing, so that individual headers adapters don't.

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: enhancementA general enhancement

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions