3

I'm trying to contribute a fix for this issue, and tried something similar to this, but no matter what header I try to set, I don't see it in the http response I am trying to modify.

This is the method I'm trying to change, and here is the line I tried to add :

w.Header().Set("Content-Type", "application/json").

The full method :

func (s *HTTPServer) getServices(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    if err := json.NewEncoder(w).Encode(s.list.GetAllServices()); err != nil {
        log.Println("Error encoding: ", err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

I would expect the header to change, but it always is text/plain; charset=utf-8

Disclaimer: this is the first piece of code I wrote (or rather, copy/pasted/adapted) in Go.

Community
  • 1
  • 1
greg0ire
  • 21,120
  • 15
  • 68
  • 95
  • Show the code for the request handler and where you added the call to set the header. – Cerise Limón Sep 01 '16 at 14:09
  • I just did I think :) – greg0ire Sep 01 '16 at 14:09
  • 5
    Is the ResponseWriter modified anywhere else before it gets to this function? – Kevin M Granger Sep 01 '16 at 14:11
  • 3
    That looks correct at first glance. Are you sure you're testing the updated code? – JimB Sep 01 '16 at 14:12
  • JimB I just added a log and it does not appear after using the attach trick described in the linked thread, so I'll try again with `--no-cache` – greg0ire Sep 01 '16 at 14:12
  • @KevinMGranger : I don't know, can you explain why that would matter? Do you mean I wouldn't be able to overwrite an existing header? – greg0ire Sep 01 '16 at 14:13
  • You have to be careful that other middleware in the chain hasn't written to the body, since this forces the headers to be written out, after which they can't be modified. – a-h Sep 01 '16 at 14:14
  • 1
    Yay! It finally works! Thanks to the `w.WriteHeader(http.StatusOK)` aacebedo made me add. You can get easy internet points if you want by answering that :) – greg0ire Sep 01 '16 at 14:15
  • Also, I'm moving this logic after the if clause to avoid using json for the error message. – greg0ire Sep 01 '16 at 14:16
  • Thanks a-h, it wasn't the case apparently, but it makes sense! – greg0ire Sep 01 '16 at 14:18

1 Answers1

7

if somebody hit this issue, the next info might be helpful.

the reason this wasn't working is the status code was written out before the attempt to add the content-type header.

to make it work, all headers should be added before w.WriteHeader(status code) is being invoked. example:

w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
if err := encoder.Encode(s.list.GetAllServices()); err != nil {
    panic(err)
}
Itamar Lavender
  • 673
  • 5
  • 16