1
votes

I am using servant library. I tried modifying an approach from some blog post, but it doesn't do anything in case of removing "Server" header. (It only works for adding custom headers.)

removeServerHeaderMiddleware :: Middleware
removeServerHeaderMiddleware baseApp = \req responseFunc -> baseApp req (newResponseFunc responseFunc)
  where
    newResponseFunc :: (Response -> IO ResponseReceived) -> Response -> IO ResponseReceived
    newResponseFunc responseFunc = removeServerHeader >>> responseFunc
    removeServerHeader :: Response -> Response
    removeServerHeader r = trace (show $ responseHeaders r) $ mapResponseHeaders (filter (\(k, _) -> k /= "Server")) r

app1 :: Application
app1 = serve imageAPI1 server1

main :: IO ()
main = do
  let port = 8080
  putStrLn $ "Starting server on port " <> show port <> "."
  run port $ removeServerHeaderMiddleware app1

Response:

$ http :8080/images
HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
Date: Sat, 15 Jun 2019 06:12:58 GMT
Server: Warp/3.2.27
Transfer-Encoding: chunked

Looking at trace, maybe the header gets added later?

[("Content-Type","application/json;charset=utf-8")]

I found setServerName in warp, but I have no clue how to incorporate that with servant.

1

1 Answers

3
votes

The documentation for setServerName states:

Default server name to be sent as the "Server:" header if an application does not set one. If an empty string is set, the "Server:" header is not sent. This is true even if an application set one.

From http://hackage.haskell.org/package/warp-3.2.27/docs/Network-Wai-Handler-Warp.html

So to disable the Server header one setServerName with an empty string.

To use this one replaces run port with

runSettings (setPort port (setServerName "" defaultSettings))