question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Immutable HttpHeaders and Cookies

See original GitHub issue

HttpHeaders in Armeria is mutable. Although it is convenient to use, it sometimes leads us to a surprising behavior when it’s modified by an unexpected place.

To address such issues, I’d like to propose to make HttpHeaders immutable, which means modifying an HttpHeaders will result in a new HttpHeaders instance. The following is an example of the API I have in mind:

// Mutable headers. Behaves like current HttpHeaders do.
MutableHeaders mh1 = MutableHeaders.of().add("name", "value");

// Immutable headers. Does not have methods like 'set()'.
Headers ih1 = ImmutableHeaders.of("name", "value", ...);

// Conversion to immutable headers.
Headers ih2 = mh1.toImmutable();

// Conversion to mutable headers.
MutableHeaders mh2 = ih2.toMutable();
assertThat(mh2).isEqualTo(mh1);
assertThat(mh2).isNotSameAs(mh1); 

// Mutation of immutable headers.
Headers ih3 = ih2.mutate((MutableHeaders h) -> {
    h.set("name", "new-value");
    ...
});

// One-time mutation.
Headers ih4 = ih2.mutator().set("name", "new-value");

Thoughts? I’d like to get as much feed back (e.g. what could be a problem when we do this?) as possible because this will be a big breaking change. To be honest, I may even fail to refactor Armeria itself because Armeria itself relies on mutability of HttpHeaders in some places.

Note that I removed Http from the type names, which may need an additional discussion as well.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:13 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
trustincommented, Apr 17, 2019

This is a rough preview of the new API:

Note that Headers now have two new subtypes RequestHeaders and ResponseHeaders. They are essentially same, but they are different in which shortcut methods they expose. It was inspired by @anuraaga’s suggestion about separating AggregatedHttpMessage into AggregatedHttpRequest and AggregatedHttpResponse.

The following is the example usage:

RequestHeaders h = RequestHeaders.of(HttpMethod.GET, "/foo");
RequestHeaders h = RequestHeaders.of(HttpMethod.GET, "/foo",
                                     HttpHeaderNames.ACCEPT_ENCODING, "gzip",
                                     HttpHeaderNames.AUTHORITY, "foo.com");
RequestHeaders h = new RequestHeadersBuilder(HttpMethod.GET, "/foo")
    .add(HttpHeaderNames.ACCEPT_ENCODING, "gzip")
    .add(HttpHeaderNames.AUTHORITY, "foo.com")
    .build();

RequestHeaders h = h.toBuilder()
                    .add(HttpHeaderNames.USER_AGENT, "baz")
                    .build();

RequestHeaders h = h.mutate(mutator -> {
    mutator.add(HttpHeaderNames.USER_AGENT, "baz");
    mutator.remove(HttpHeaderNames.ACCEPT_ENCODING);
});
1reaction
southernkasaistcommented, Jan 30, 2019

How about using builder way like guava immutable types (ImmutableList.Builder, etc)? e.g.,

Headers headers = ImmutableHeaders.builder().add("name1", "value1").build();
Headers other = headers.toBuilder().add("name2", "value2").set("name1", "value3").build();
Read more comments on GitHub >

github_iconTop Results From Across the Web

HttpHeaders (Spring Framework 6.0.2 API)
A data structure representing HTTP request or response headers, mapping String header names to a list of String values, also offering accessors for...
Read more >
Is there a way to make HTTP request headers immutable?
Request headers are sent from the client to the server. The browser itself constructs an HTTP request to send. A user with control...
Read more >
Cache-Control - HTTP - MDN Web Docs
The Cache-Control HTTP header field holds directives ... The immutable response directive indicates that the response will not be updated ...
Read more >
Best Practices for Processing HTTP Headers and Cookies in a ...
Pay attention that newHeaders and newCookies are mutable collections and we can change their state by adding, removing, or changing an element —...
Read more >
HttpHeaders - Angular
Represents the header configuration options for an HTTP request. Instances are immutable. Modifying methods return a cloned instance with the change.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found