Skip to content

Netty4HeadersAdapter.remove returns empty list instead of null for non-existing key #36226

@kzander91

Description

@kzander91

Netty4HeadersAdapter implements Map, therefore calling remove("unknown key") should return null, but it doesn't.
The reason is that the method first delegates to io.netty.handler.codec.http.HttpHeaders#getAll(java.lang.String) to get any existing values:

@Override
public @Nullable List<String> remove(Object key) {
if (key instanceof String headerName) {
List<String> previousValues = this.headers.getAll(headerName);
this.headers.remove(headerName);
return previousValues;
}
return null;
}

Netty however returns an empty list instead of null for missing keys:
https://github.com/netty/netty/blob/a853a399b5dc976b70d457953741419db0cd45fa/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaders.java#L1282-L1292

Here's a reproducer:

import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpHeaders;
import org.junit.jupiter.api.Test;
import org.springframework.http.support.Netty4HeadersAdapter;

import static org.assertj.core.api.Assertions.assertThat;

class Demo22ApplicationTests {

    @Test
    void reproducer() {
        HttpHeaders nettyHeaders = new DefaultHttpHeaders()
                .add("known", "value1")
                .add("known", "value2");
        Netty4HeadersAdapter adapter = new Netty4HeadersAdapter(nettyHeaders);
        assertThat(adapter.remove("known")).containsExactly("value1", "value2"); // succeeds
        assertThat(adapter.remove("unknown")).isNull(); // fails with `expected: null but was []`
    }

}

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)status: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions