0

While studying net/http I actually wanted to know that how go returns http.Response to listener. From this answer, I found that http.Response type is passed to ServeHTTP, but that is not the case because on compilation below code throw error. Which means http.Response does not implement http.ResponseWriter interface. I am curious what is the type which implements http.ResponseWriter interface?

# command-line-arguments
./server1.go:9:20: http.Response.Header is a field, not a method
./server1.go:9:20: impossible type assertion:
        http.Response does not implement http.ResponseWriter (missing Header method)
func handler(resp http.ResponseWriter, req *http.Request){
    actualresp := resp.(http.Response) //https://tour.golang.org/methods/15
    resp.Write([]byte("Hello Web, from go"))
}
func main(){
    http.HandleFunc("/api", handler)
    http.ListenAndServe(":8000", nil)
}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
  • 5
    You've misread the answer you linked to. It mentions `http.response`, not `http.Response`. Note the difference of capitalization. – Jonathan Hall Sep 18 '21 at 08:33
  • 1
    @RahulPalve to confirm that the *dynamic* type of an interface value is what you expect it to be, you can use the `%T` verb in a `fmt` print. E.g. `fmt.Printf("%T\n", w)` will output `*http.response`. – mkopriva Sep 18 '21 at 08:54
  • Thanks for this tip @mkopriva, Actually this came into my mind but I thought `%T` will print http.`ResponseWriter`. – Rahul Palve Sep 18 '21 at 09:01
  • 2
    Please keep in mind that one of the chief reasons for using an interface is decoupling of the implementation and its clients. So while it might be useful for learning/debugging to find out objects of which concrete type get passed to your handlers, be sure to understand the following: 1) objects of different types might be used when handling requests of different versions of the HTTP protocol (currently there are at least two of them, actively used); 2) this type is free to change in any next Go release—even in minor one—without any warning or mentioning in the release notes. – kostix Sep 18 '21 at 09:12

1 Answers1

2

http.Response has the following methods only:

func (r *Response) Cookies() []*Cookie
func (r *Response) Location() (*url.URL, error)
func (r *Response) ProtoAtLeast(major, minor int) bool
func (r *Response) Write(w io.Writer) error

This does not implement the http.ResponseWriter interface which requires:

Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)

So clearly http.Response cannot be used as a http.ResponseWriter.

Instead, and as the answer you linked to mentions, the non-exported http.response is used. You can find a description of the life of a write on the http server side in the code.

Marc
  • 19,394
  • 6
  • 47
  • 51