traefik / yaegi

Yaegi is Another Elegant Go Interpreter
https://pkg.go.dev/github.com/traefik/yaegi
Apache License 2.0
6.78k stars 341 forks source link

Struct not recognized as `http.Flusher` after conversion to `http.ResponseWriter` interface #1600

Open okkero opened 7 months ago

okkero commented 7 months ago

The following program sample.go triggers an unexpected result

package main

import (
    "fmt"
    "net/http"
    "reflect"
)

type responseWriter struct {
    http.ResponseWriter
}

func (w *responseWriter) Flush() {
    fmt.Println("Flushing...")
    if flusher, ok := w.ResponseWriter.(http.Flusher); ok {
        flusher.Flush()
    }
}

type dummy struct{}

func (d *dummy) Header() http.Header {
    fmt.Println("Dummy Header")
    return nil
}

func (d *dummy) Write(data []byte) (int, error) {
    fmt.Println("Dummy Write ", data)
    return 0, nil
}

func (d *dummy) WriteHeader(responseCode int) {
    fmt.Println("Dummy WriteHeader ", responseCode)
}

func foo(rw http.ResponseWriter) {
    var respCodeOverrideWriter = &responseWriter{ResponseWriter: rw}

    var flusher http.Flusher = respCodeOverrideWriter
    fmt.Println("responseWriter is http.Flusher. We can call Flush manually:")
    flusher.Flush()

    var httpResponseWriter http.ResponseWriter = respCodeOverrideWriter
    _, ok := httpResponseWriter.(http.Flusher)
    fmt.Println("Is responseWriter http.Flusher?", ok)
}

func main() {
    foo(&dummy{})
}

Expected result

responseWriter is http.Flusher. We can call Flush manually:
Flushing...
Is responseWriter http.Flusher? true

Got

responseWriter is http.Flusher. We can call Flush manually:
Flushing...
Is responseWriter http.Flusher? false

Yaegi Version

v0.15.1

Additional Notes

See this issue in the Traefik repo for context