golang nethttp ResponseWriter에 헤더를 쓸 때 주의할 점


ResponseWriter를 쓸 때 주의할 점

  • net/http 클라이언트는 먼저 상태코드를 받고, 그 다음에 Response body 를 받아들인다.
  • go의 net/http 에서는 ReposeWriter에서 먼저 response body 를 쓰면, 응답 상태가 200이라고 가정하고 의도적으로 보내고자 하는 시점보다 먼저 클라이언트에 response body 를 보내버리게 된다. (다른 언어의 웹 프레임워크도 이런식으로 동작한다는 법칙은 없다)
  • 예시
    func TestHandlerWriteHeader(t *testing.T) {  
     handler := func(w http.ResponseWriter, r *http.Request) {  
        // 먼저 response body 를 쓰고  
        // 나중에 헤더를 쓰는 핸들러  
        _, _ = w.Write([]byte("Bad Request"))  
        w.WriteHeader(http.StatusBadRequest)  
     }  
     r := httptest.NewRequest(http.MethodGet, "http://test", nil)  
     w := httptest.NewRecorder()                      // 얘는 http.ResponseWriter 의 구현체  
     handler(w, r)                                    // r 요청이 들어왔을때 handler 를 거쳐 w가 어떻게 작성되는지 보자  
     t.Logf("Response status: %q", w.Result().Status) // BadRequest가 안써져 있어야 정상  
    
     handler = func(w http.ResponseWriter, r *http.Request) {  
        w.WriteHeader(http.StatusBadRequest)  
        _, _ = w.Write([]byte("Bad Request"))  
     }  
    
     r = httptest.NewRequest(http.MethodGet, "http://test", nil)  
     w = httptest.NewRecorder()  
     handler(w, r)  
     t.Logf("Response status: %q", w.Result().Status)  
    }
    === RUN   TestHandlerWriteHeader
      first_write_body_test.go:19: Response status: "200 OK"
      first_write_body_test.go:29: Response status: "400 Bad Request"
  • net/http 의 ResponseWriter 구현체... -> 이렇게 헤더가 비어있으면 지맘대로 200 응답을 써버린다.