Setting http header and status code does not work after setting body

415 views
Skip to first unread message

Steve Hummingbird

unread,
Jul 14, 2016, 4:17:37 PM7/14/16
to vert.x
When running the following code

@Override
public void start(Future fut) {

 
Router router = Router.router(vertx);
 router
.route(HttpMethod.GET, "/").handler( (RoutingContext routingContext) -> {
 
HttpServerResponse response = routingContext.response();
 response
.setChunked(true);
 response
.putHeader("X-HEADER-BEFORE", "true");
 response
.write("HELLO WORLD");
 response
.putHeader("X-HEADER-AFTER", "true");
 response
.setStatusCode(500);
 response
.end();
 
});
 vertx
.createHttpServer().requestHandler(router::accept).listen(8080, (AsyncResult -> {fut.complete();}));
}

I would expect the following behaviour:
- header "X-HEADER-BEFORE" is set to "true"
- header "X-HEADER-AFTER" is set to "true"
- the http response code is 500

However, this is what I have been observing with both vertx 3.3.0 and 3.3.2:
- header "X-HEADER-BEFORE" is set to "true"
- header "X-HEADER-AFTER" is not set at all
- the http response code is 200

Basically status codes and http headers that are set after the body is written are ignored.

This is the corresponding curl output:

 curl -vvvv localhost:8080

 

* Rebuilt URL to: localhost:8080/

*   Trying ::1...

* Connected to localhost (::1) port 8080 (#0)

> GET / HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.43.0

> Accept: */*

>  

< HTTP/1.1 200 OK

< X-HEADER-BEFORE: true

< Transfer-Encoding: chunked

<  

* Connection #0 to host localhost left intact

HELLO WORLD


Is this expected behaviour?

Nat

unread,
Jul 14, 2016, 4:23:06 PM7/14/16
to vert.x
It is expected. You are not supposed to set header after you start writing response. IMHO, It is a bug, however, for not checking that.
Message has been deleted

Steve Hummingbird

unread,
Jul 14, 2016, 4:39:18 PM7/14/16
to vert.x
Ah, thanks. Must have overlooked it in the docs:

"Headers must all be added before any parts of the response body are written."

However, how do I handle the following case:
- start writing data to the body
- server encounters an error
- set status code to 500

even when calling response.reset() and setting the new status code, still the data which has been set before adding the body is returned:


HttpServerResponse response = routingContext.response();
response
.setChunked(true);
response
.putHeader("X-HEADER-BEFORE", "true");

response
.write("HELLO WORLD2");

response
.reset();

response
.putHeader("X-HEADER-AFTER", "true");
response
.setStatusCode(500);
response
.end();


=> same result as above

Alexander Lehmann

unread,
Jul 14, 2016, 5:21:49 PM7/14/16
to vert.x
That is actually a general problem in server side programming languages, e.g. in php the server will give a warning "output has already started" and ignore the headers and the status or in tomcat you can buffer the beginning of the output stream to be able to send headers.

You either have to calculate all data before sending the status (i.e. do a kind of separation of concerns, first calculate/fetch all data, the send all the output based on that) or you can only send an error message at the point where you encounter the error and not send a status.

If you use a template language to create your pages, you have to fetch the data before anyway, so that should not be a problem.

Julien Viet

unread,
Jul 14, 2016, 5:41:29 PM7/14/16
to ve...@googlegroups.com
indeed.

HTTP/2 provides the ability to reset the stream with an 0x01 internal error which offers a alternative.

-- 
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/8b349984-ded1-4073-85ae-d9a0bfc13402%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Steve Hummingbird

unread,
Jul 15, 2016, 11:10:05 AM7/15/16
to vert.x
Ah, thanks for the explanation. I see what is going on now.
Reply all
Reply to author
Forward
0 new messages