emicklei / go-restful

package for building REST-style Web Services using Go
MIT License
5.04k stars 690 forks source link

Flush don't work #529

Closed ashertz-dev closed 1 year ago

ashertz-dev commented 1 year ago

When I try to convert Response.ResponseWriter to http.Flush, by using restful.Response.ResponseWriter.(http.Flusher), it return false. So, the func Flush faild too.

ashertz-dev commented 1 year ago

I resolve it

maratrixx commented 10 months ago

I resolve it

How to solve the problem? I also encountered the same problem. thanks.

ashertz-dev commented 10 months ago

I resolve it

How to solve the problem? I also encountered the same problem. thanks.

Sorry, it has been a long time, and I have already forgotten. I find some code block in my project. Maybe it's useful.

type WriterFlusher interface {
    io.Writer
    http.Flusher
}

// wrapperHTTP used to wrap http request for print
func wrapperHTTP(h http.Handler) http.Handler {
    slogger := slog.New(slog.NewTextHandler(os.Stdout))
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        m := httpsnoop.CaptureMetrics(h, w, r)
        defer func() {
            slogger.Info("",
                "method", r.Method,
                "url", r.URL,
                "proto", r.Proto,
                "user-agent", r.UserAgent(),
                "remote", r.RemoteAddr,
                "referer", r.Referer(),
                "status", m.Code,
                "size", m.Written,
                "lat-ms", m.Duration.Milliseconds(),
            )
        }()
    })
}

func ListenAndServe(addr string, handler http.Handler) error {
    return http.ListenAndServe(addr, wrapperHTTP(handler))
}
maratrixx commented 10 months ago

I resolve it

How to solve the problem? I also encountered the same problem. thanks.

Sorry, it has been a long time, and I have already forgotten. I find some code block in my project. Maybe it's useful.

type WriterFlusher interface {
  io.Writer
  http.Flusher
}

// wrapperHTTP used to wrap http request for print
func wrapperHTTP(h http.Handler) http.Handler {
  slogger := slog.New(slog.NewTextHandler(os.Stdout))
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
      m := httpsnoop.CaptureMetrics(h, w, r)
      defer func() {
          slogger.Info("",
              "method", r.Method,
              "url", r.URL,
              "proto", r.Proto,
              "user-agent", r.UserAgent(),
              "remote", r.RemoteAddr,
              "referer", r.Referer(),
              "status", m.Code,
              "size", m.Written,
              "lat-ms", m.Duration.Milliseconds(),
          )
      }()
  })
}

func ListenAndServe(addr string, handler http.Handler) error {
  return http.ListenAndServe(addr, wrapperHTTP(handler))
}

Thanks your reply. But this does not appear to use the flush method.

nullbus commented 10 months ago

I suggest to figure out the actual type of ResponseWriter the server is using (using debbuger or logging). I think your ResponseWriter is not being from Go's default http package.

In this package, there is some path that it can wrap default http.ResponseWriter: https://github.com/emicklei/go-restful/blob/c691c18926f9d85112cb5072c1c6478b3b737abc/container.go#L263-L272

It replaces writer to CompressingResponseWriter if something compression is needed and CompressingResponseWriter is not implementing Flush method for now. If your case is it, there are some options:

emicklei commented 10 months ago

I think adding a Flush method is an easy step to take

emicklei commented 10 months ago

https://github.com/emicklei/go-restful/pull/538