shelf icon indicating copy to clipboard operation
shelf copied to clipboard

The Server header cannot be removed (docs suggest it shouldn't even be added by default)

Open renatoathaydes opened this issue 3 years ago • 6 comments
trafficstars

Starting up a hello world server with shelf I get this response:

HTTP/1.1 200 OK
date: Sat, 20 Aug 2022 13:15:00 GMT
content-length: 13
x-frame-options: SAMEORIGIN
content-type: text/plain; charset=utf-8
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
server: dart:io with Shelf

Hello World!

Notice the server header. I don't need most of those headers, so I am doing this to remove them:

  var server =
      await shelf_io.serve(handler, config.address, config.port, shared: true);

  server.defaultResponseHeaders
    ..removeAll('x-frame-options')
    ..removeAll('x-xss-protection')
    ..removeAll('x-content-type-options')
    ..removeAll('server');
  server.serverHeader = null;

All headers I removed are gone, except for Server:

HTTP/1.1 200 OK
content-type: text/plain; charset=utf-8
date: Sat, 20 Aug 2022 13:24:08 GMT
server: dart:io with Shelf
content-length: 13

Hello World!

According to the docs, the Server header shouldn't even be there....

From /dart/2.17.6/libexec/lib/_http/http.dart:124:

  /// If the `Server` header is added here and the `serverHeader` is set as
  /// well then the value of `serverHeader` takes precedence.
  HttpHeaders get defaultResponseHeaders;

From /usr/local/Cellar/dart/2.17.6/libexec/lib/_http/http.dart:111:

  /// If [serverHeader] is `null`, no `Server` header will be added to each
  /// response.
  ///
  /// The default value is `null`.
  String? serverHeader;

Is there another way to remove that? Are the docs wrong?

renatoathaydes avatar Aug 20 '22 13:08 renatoathaydes

It also seems that I can't even change the value of the Server header:

server.serverHeader = 'Dart';

I still get:

server: dart:io with Shelf

renatoathaydes avatar Aug 20 '22 13:08 renatoathaydes

As of 1.3.2, the header changed to x-powered-by... but it seems it still can't be removed?! Really?

renatoathaydes avatar Aug 23 '22 20:08 renatoathaydes

I am currently using this middleware to set the value to the empty String:

shelf.Response _cleanHeaders(shelf.Response response) {
  return response.change(headers: const {'x-powered-by': ''});
}

setting the value to null results in the header maintaining the original value, but would be nice if that actually made the header disappear.

renatoathaydes avatar Aug 24 '22 17:08 renatoathaydes

According to the docs, the Server header shouldn't even be there....

Those look like docs from the SDK and would apply when you are using HttpServer directly.

shelf_io is adding the x-powered-by header on top of what HttpServer does.

I don't have particularly strong feelings about this header - I'd be just as happy not adding it at all. I have a preference not to have extra config for this since it seems so incidental, but I could be convinced. @kevmoo - WDYT?

natebosch avatar Aug 24 '22 21:08 natebosch

Your attempted workaround to this does look like it's something we might be able to support - we could use the defaultResponseHeaders for this behavior, which would also let you override it in exactly the way you expected would work.

natebosch avatar Aug 24 '22 22:08 natebosch

@natebosch has a GREAT proposal. Something we should have done from the start....

kevmoo avatar Aug 25 '22 01:08 kevmoo