flush.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. package dpcore
  2. import (
  3. "mime"
  4. "net/http"
  5. "strings"
  6. "time"
  7. )
  8. // Auto sniff of flush interval from header
  9. func (p *ReverseProxy) getFlushInterval(req *http.Request, res *http.Response) time.Duration {
  10. contentType := req.Header.Get("Content-Type")
  11. if actualContentType, _, _ := mime.ParseMediaType(contentType); actualContentType == "text/event-stream" {
  12. return -1
  13. }
  14. if req.ContentLength == -1 || p.isBidirectionalStream(req, res) {
  15. return -1
  16. }
  17. // Fixed issue #235: Added auto detection for ollama / llm output stream
  18. connectionHeader := req.Header["Connection"]
  19. if len(connectionHeader) > 0 && strings.Contains(strings.Join(connectionHeader, ","), "keep-alive") {
  20. return -1
  21. }
  22. //Cannot sniff anything. Use default value
  23. return p.FlushInterval
  24. }
  25. // Check for bidirectional stream, copy from Caddy :D
  26. func (p *ReverseProxy) isBidirectionalStream(req *http.Request, res *http.Response) bool {
  27. // We have to check the encoding here; only flush headers with identity encoding.
  28. // Non-identity encoding might combine with "encode" directive, and in that case,
  29. // if body size larger than enc.MinLength, upper level encode handle might have
  30. // Content-Encoding header to write.
  31. // (see https://github.com/caddyserver/caddy/issues/3606 for use case)
  32. ae := req.Header.Get("Accept-Encoding")
  33. return req.ProtoMajor == 2 &&
  34. res.ProtoMajor == 2 &&
  35. res.ContentLength == -1 &&
  36. (ae == "identity" || ae == "")
  37. }