Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore null header value in MockHttpServletResponse #26488

Closed
imaxvell opened this issue Feb 1, 2021 · 4 comments
Closed

Ignore null header value in MockHttpServletResponse #26488

imaxvell opened this issue Feb 1, 2021 · 4 comments
Assignees
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@imaxvell
Copy link

imaxvell commented Feb 1, 2021

Hello,

I've faced an issue recently working with MockHttpServletResponse. The thing is when I have conditional (value can be null) headers in my controller, and I want to test them using MockMvc it fails, because MockHttpServletResponse checks if header value in response is null.

Below is what I am trying to do:

    @GetMapping("/example")
    public ResponseEntity<?> example() {
        String nullableHeaderValue = conditionalHeaderValue();
        return ResponseEntity.ok()
                .header("Some-header", nullableHeaderValue)
                .body("Hi");
    }

So the intention is to send header if its value is present and it works as expected. But when I test it with MockMvc it throws an IllegalArgumentException due to this check in MockHttpServletResponse:

	private void doAddHeaderValue(String name, Object value, boolean replace) {
		HeaderValueHolder header = this.headers.get(name);
		Assert.notNull(value, "Header value must not be null");
		if (header == null) {
			header = new HeaderValueHolder();
			this.headers.put(name, header);
		}
		if (replace) {
			header.setValue(value);
		}
		else {
			header.addValue(value);
		}
	}

I know that as workaround instead of nullability of value of header I can put headers themselves conditionally, but the thing is that spec of HttpServletResponse allows me to have nullable header values, while MockHttpServletResponse does not, and this behavior is surprising to say the least.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 1, 2021
@sbrannen sbrannen added in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) labels Feb 1, 2021
@sbrannen
Copy link
Member

sbrannen commented Feb 1, 2021

The Javadoc for addHeader() in HttpServletResponse is unclear as to whether or not null is permitted as a header value:

value the additional header value. If it contains octet string, it should be encoded according to RFC 2047

And as you pointed out, org.springframework.http.HttpHeaders.add(String, String) declares the headerValue parameter as @Nullable.

However, the Tomcat implementation (org.apache.catalina.connector.Response.addHeader(String, String, Charset)) simply ignores an attempt to add a header if the supplied value is null; whereas, the Jetty implementation (org.eclipse.jetty.server.Response.addHeader(String, String)) appears to allow null unless you're setting the Content-Type header.

So I'm a bit undecided about whether we should remove the not-null assertion in MockHttpServletResponse.

@rstoyanchev, thoughts?

@sbrannen
Copy link
Member

sbrannen commented Feb 1, 2021

On second thought, since neither Tomcat nor Jetty throws an IllegalArgumentException for a null header value and since our own HttpHeaders allows null header values as input, I think we should remove the not-null assertion in MockHttpServletResponse and simply ignore null header values.

@rstoyanchev / @jhoeller, are you OK with that?

@sbrannen sbrannen changed the title MockHttpServletResponse null header value check Ignore null header value in MockHttpServletResponse Feb 1, 2021
@sbrannen sbrannen added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 1, 2021
@sbrannen sbrannen added this to the 5.3.4 milestone Feb 1, 2021
@sbrannen sbrannen self-assigned this Feb 1, 2021
@sbrannen
Copy link
Member

sbrannen commented Feb 2, 2021

This change will be included in 5.3.4, but feel free to try it out in an upcoming 5.3.4 snapshot.

@imaxvell
Copy link
Author

imaxvell commented Feb 2, 2021

@sbrannen Thanks, appreciate your quick response.

This was referenced Mar 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants