1
0
mirror of https://github.com/juanfont/headscale.git synced 2024-12-20 19:09:07 +01:00

Lint fixes 5/n

This commit is contained in:
Juan Font Alonso 2022-06-26 12:21:35 +02:00
parent 03ced0ecfe
commit c810b24eb9
7 changed files with 392 additions and 56 deletions

89
api.go
View File

@ -38,7 +38,13 @@ func (h *Headscale) KeyHandler(
) {
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write([]byte(MachinePublicKeyStripPrefix(h.privateKey.Public())))
_, err := writer.Write([]byte(MachinePublicKeyStripPrefix(h.privateKey.Public())))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
type registerWebAPITemplateConfig struct {
@ -72,7 +78,13 @@ func (h *Headscale) RegisterWebAPI(
if machineKeyStr == "" {
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("Wrong params"))
_, err := writer.Write([]byte("Wrong params"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -87,14 +99,26 @@ func (h *Headscale) RegisterWebAPI(
Msg("Could not render register web API template")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render register web API template"))
_, err = writer.Write([]byte("Could not render register web API template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
writer.Header().Set("Content-Type", "text/html; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(content.Bytes())
_, err := writer.Write(content.Bytes())
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
// RegistrationHandler handles the actual registration process of a machine
@ -407,7 +431,13 @@ func (h *Headscale) handleMachineLogOut(
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(respBody)
_, err = writer.Write(respBody)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
func (h *Headscale) handleMachineValidRegistration(
@ -445,7 +475,13 @@ func (h *Headscale) handleMachineValidRegistration(
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(respBody)
_, err = writer.Write(respBody)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
func (h *Headscale) handleMachineExpired(
@ -493,7 +529,13 @@ func (h *Headscale) handleMachineExpired(
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(respBody)
_, err = writer.Write(respBody)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
func (h *Headscale) handleMachineRefreshKey(
@ -535,7 +577,13 @@ func (h *Headscale) handleMachineRefreshKey(
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(respBody)
_, err = writer.Write(respBody)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
func (h *Headscale) handleMachineRegistrationNew(
@ -574,7 +622,13 @@ func (h *Headscale) handleMachineRegistrationNew(
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(respBody)
_, err = writer.Write(respBody)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
// TODO: check if any locks are needed around IP allocation.
@ -618,7 +672,13 @@ func (h *Headscale) handleAuthKey(
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusUnauthorized)
writer.Write(respBody)
_, err = writer.Write(respBody)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
log.Error().
Caller().
@ -721,7 +781,14 @@ func (h *Headscale) handleAuthKey(
Inc()
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(respBody)
_, err = writer.Write(respBody)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
log.Info().
Str("func", "handleAuthKey").
Str("machine", registerRequest.Hostinfo.Hostname).

32
app.go
View File

@ -348,7 +348,13 @@ func (h *Headscale) httpAuthenticationMiddleware(next http.Handler) http.Handler
Str("client_address", req.RemoteAddr).
Msg(`missing "Bearer " prefix in "Authorization" header`)
writer.WriteHeader(http.StatusUnauthorized)
writer.Write([]byte("Unauthorized"))
_, err := writer.Write([]byte("Unauthorized"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -362,7 +368,13 @@ func (h *Headscale) httpAuthenticationMiddleware(next http.Handler) http.Handler
Msg("failed to validate token")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Unauthorized"))
_, err := writer.Write([]byte("Unauthorized"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -373,7 +385,13 @@ func (h *Headscale) httpAuthenticationMiddleware(next http.Handler) http.Handler
Msg("invalid token")
writer.WriteHeader(http.StatusUnauthorized)
writer.Write([]byte("Unauthorized"))
_, err := writer.Write([]byte("Unauthorized"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -409,7 +427,13 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *mux.Router {
"/health",
func(writer http.ResponseWriter, req *http.Request) {
writer.WriteHeader(http.StatusOK)
writer.Write([]byte("{\"healthy\": \"ok\"}"))
_, err := writer.Write([]byte("{\"healthy\": \"ok\"}"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}).Methods(http.MethodGet)
router.HandleFunc("/key", h.KeyHandler).Methods(http.MethodGet)

View File

@ -105,7 +105,13 @@ func (h *Headscale) DERPHandler(
}
writer.Header().Set("Content-Type", "text/plain")
writer.WriteHeader(http.StatusUpgradeRequired)
writer.Write([]byte("DERP requires connection upgrade"))
_, err := writer.Write([]byte("DERP requires connection upgrade"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -117,7 +123,13 @@ func (h *Headscale) DERPHandler(
log.Error().Caller().Msg("DERP requires Hijacker interface from Gin")
writer.Header().Set("Content-Type", "text/plain")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("HTTP does not support general TCP support"))
_, err := writer.Write([]byte("HTTP does not support general TCP support"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -127,7 +139,13 @@ func (h *Headscale) DERPHandler(
log.Error().Caller().Err(err).Msgf("Hijack failed")
writer.Header().Set("Content-Type", "text/plain")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("HTTP does not support general TCP support"))
_, err = writer.Write([]byte("HTTP does not support general TCP support"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -160,7 +178,13 @@ func (h *Headscale) DERPProbeHandler(
writer.WriteHeader(http.StatusOK)
default:
writer.WriteHeader(http.StatusMethodNotAllowed)
writer.Write([]byte("bogus probe method"))
_, err := writer.Write([]byte("bogus probe method"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
}
@ -196,7 +220,13 @@ func (h *Headscale) DERPBootstrapDNSHandler(
}
writer.Header().Set("Content-Type", "application/json")
writer.WriteHeader(http.StatusOK)
json.NewEncoder(writer).Encode(dnsEntries)
err := json.NewEncoder(writer).Encode(dnsEntries)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
// ServeSTUN starts a STUN server on the configured addr.

144
oidc.go
View File

@ -142,7 +142,13 @@ func (h *Headscale) OIDCCallback(
if code == "" || state == "" {
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("Wrong params"))
_, err := writer.Write([]byte("Wrong params"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -155,7 +161,13 @@ func (h *Headscale) OIDCCallback(
Msg("Could not exchange code for token")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("Could not exchange code for token"))
_, err := writer.Write([]byte("Could not exchange code for token"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -170,7 +182,13 @@ func (h *Headscale) OIDCCallback(
if !rawIDTokenOK {
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("Could not extract ID Token"))
_, err := writer.Write([]byte("Could not extract ID Token"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -185,7 +203,13 @@ func (h *Headscale) OIDCCallback(
Msg("failed to verify id token")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("Failed to verify id token"))
_, err := writer.Write([]byte("Failed to verify id token"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -206,7 +230,13 @@ func (h *Headscale) OIDCCallback(
Msg("Failed to decode id token claims")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("Failed to decode id token claims"))
_, err := writer.Write([]byte("Failed to decode id token claims"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -218,7 +248,13 @@ func (h *Headscale) OIDCCallback(
log.Error().Msg("authenticated principal does not match any allowed domain")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("unauthorized principal (domain mismatch)"))
_, err := writer.Write([]byte("unauthorized principal (domain mismatch)"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -230,7 +266,13 @@ func (h *Headscale) OIDCCallback(
log.Error().Msg("authenticated principal does not match any allowed user")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("unauthorized principal (user mismatch)"))
_, err := writer.Write([]byte("unauthorized principal (user mismatch)"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -243,7 +285,13 @@ func (h *Headscale) OIDCCallback(
Msg("requested machine state key expired before authorisation completed")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("state has expired"))
_, err := writer.Write([]byte("state has expired"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -259,7 +307,13 @@ func (h *Headscale) OIDCCallback(
Msg("could not parse machine public key")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("could not parse public key"))
_, err := writer.Write([]byte("could not parse public key"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -268,7 +322,13 @@ func (h *Headscale) OIDCCallback(
log.Error().Msg("could not get machine key from cache")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("could not get machine key from cache"))
_, err := writer.Write([]byte("could not get machine key from cache"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -300,14 +360,26 @@ func (h *Headscale) OIDCCallback(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render OIDC callback template"))
_, err := writer.Write([]byte("Could not render OIDC callback template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
writer.Header().Set("Content-Type", "text/html; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(content.Bytes())
_, err := writer.Write(content.Bytes())
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -320,7 +392,13 @@ func (h *Headscale) OIDCCallback(
log.Error().Err(err).Caller().Msgf("couldn't normalize email")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("couldn't normalize email"))
_, err := writer.Write([]byte("couldn't normalize email"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -339,7 +417,13 @@ func (h *Headscale) OIDCCallback(
Msgf("could not create new namespace '%s'", namespaceName)
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("could not create namespace"))
_, err := writer.Write([]byte("could not create namespace"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -351,7 +435,13 @@ func (h *Headscale) OIDCCallback(
Msg("could not find or create namespace")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("could not find or create namespace"))
_, err := writer.Write([]byte("could not find or create namespace"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -370,7 +460,13 @@ func (h *Headscale) OIDCCallback(
Msg("could not register machine")
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("could not register machine"))
_, err := writer.Write([]byte("could not register machine"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -388,12 +484,24 @@ func (h *Headscale) OIDCCallback(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render OIDC callback template"))
_, err := writer.Write([]byte("Could not render OIDC callback template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
writer.Header().Set("Content-Type", "text/html; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(content.Bytes())
_, err = writer.Write(content.Bytes())
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}

View File

@ -69,14 +69,26 @@ REG ADD "HKLM\Software\Tailscale IPN" /v LoginURL /t REG_SZ /d "{{.URL}}"</code>
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render Windows index template"))
_, err := writer.Write([]byte("Could not render Windows index template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
writer.Header().Set("Content-Type", "text/html; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(payload.Bytes())
_, err := writer.Write(payload.Bytes())
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
// WindowsRegConfig generates and serves a .reg file configured with the Headscale server address.
@ -97,14 +109,26 @@ func (h *Headscale) WindowsRegConfig(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render Windows registry template"))
_, err := writer.Write([]byte("Could not render Windows registry template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
writer.Header().Set("Content-Type", "text/x-ms-regedit; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(content.Bytes())
_, err := writer.Write(content.Bytes())
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
// AppleConfigMessage shows a simple message in the browser to point the user to the iOS/MacOS profile and instructions for how to install it.
@ -175,14 +199,26 @@ func (h *Headscale) AppleConfigMessage(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render Apple index template"))
_, err := writer.Write([]byte("Could not render Apple index template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
writer.Header().Set("Content-Type", "text/html; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(payload.Bytes())
_, err := writer.Write(payload.Bytes())
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
func (h *Headscale) ApplePlatformConfig(
@ -209,7 +245,13 @@ func (h *Headscale) ApplePlatformConfig(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Failed to create UUID"))
_, err := writer.Write([]byte("Failed to create UUID"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -223,7 +265,13 @@ func (h *Headscale) ApplePlatformConfig(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Failed to create content UUID"))
_, err := writer.Write([]byte("Failed to create content UUID"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -245,7 +293,13 @@ func (h *Headscale) ApplePlatformConfig(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render Apple macOS template"))
_, err := writer.Write([]byte("Could not render Apple macOS template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -258,14 +312,26 @@ func (h *Headscale) ApplePlatformConfig(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render Apple iOS template"))
_, err := writer.Write([]byte("Could not render Apple iOS template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
default:
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusBadRequest)
writer.Write([]byte("Invalid platform, only ios and macos is supported"))
_, err := writer.Write([]byte("Invalid platform, only ios and macos is supported"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -285,14 +351,26 @@ func (h *Headscale) ApplePlatformConfig(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render Apple platform template"))
_, err := writer.Write([]byte("Could not render Apple platform template"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
writer.Header().Set("Content-Type", "application/x-apple-aspen-config; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(content.Bytes())
_, err = writer.Write(content.Bytes())
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
type WindowsRegistryConfig struct {

16
poll.go
View File

@ -179,7 +179,13 @@ func (h *Headscale) PollNetMapHandler(
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(data)
_, err := writer.Write(data)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
@ -213,7 +219,13 @@ func (h *Headscale) PollNetMapHandler(
Msg("Client sent endpoint update and is ok with a response without peer list")
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(data)
_, err := writer.Write(data)
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
// It sounds like we should update the nodes when we have received a endpoint update
// even tho the comments in the tailscale code dont explicitly say so.
updateRequestsFromNode.WithLabelValues(machine.Namespace.Name, machine.Hostname, "endpoint-update").

View File

@ -57,14 +57,26 @@ func SwaggerUI(
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("Could not render Swagger"))
_, err := writer.Write([]byte("Could not render Swagger"))
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
return
}
writer.Header().Set("Content-Type", "text/html; charset=utf-8")
writer.WriteHeader(http.StatusOK)
writer.Write(payload.Bytes())
_, err := writer.Write(payload.Bytes())
if err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}
func SwaggerAPIv1(
@ -73,5 +85,10 @@ func SwaggerAPIv1(
) {
writer.Header().Set("Content-Type", "application/json; charset=utf-88")
writer.WriteHeader(http.StatusOK)
writer.Write(apiV1JSON)
if _, err := writer.Write(apiV1JSON); err != nil {
log.Error().
Caller().
Err(err).
Msg("Failed to write response")
}
}