File: stream.go

package info (click to toggle)
golang-github-vulcand-oxy 2.0.0-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 728 kB
  • sloc: makefile: 14
file content (88 lines) | stat: -rw-r--r-- 2,253 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
Package stream provides http.Handler middleware that passes-through the entire request

Stream works around several limitations caused by buffering implementations, but
also introduces certain risks.

Workarounds for buffering limitations:
1. Streaming really large chunks of data (large file transfers, or streaming videos,
etc.)

2. Streaming (chunking) sparse data. For example, an implementation might
send a health check or a heart beat over a long-lived connection. This
does not play well with buffering.

Risks:
1. Connections could survive for very long periods of time.

2. There is no easy way to enforce limits on size/time of a connection.

Examples of a streaming middleware:

	// sample HTTP handler.
	handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
	  w.Write([]byte("hello"))
	})

	// Stream will literally pass through to the next handler without ANY buffering
	// or validation of the data.
	stream.New(handler)
*/
package stream

import (
	"net/http"

	"github.com/vulcand/oxy/v2/utils"
)

// DefaultMaxBodyBytes No limit by default.
const DefaultMaxBodyBytes = -1

// Stream is responsible for buffering requests and responses
// It buffers large requests and responses to disk,.
type Stream struct {
	maxRequestBodyBytes int64

	maxResponseBodyBytes int64

	next http.Handler

	verbose bool
	log     utils.Logger
}

// New returns a new streamer middleware. New() function supports optional functional arguments.
func New(next http.Handler, setters ...Option) (*Stream, error) {
	strm := &Stream{
		next: next,

		maxRequestBodyBytes: DefaultMaxBodyBytes,

		maxResponseBodyBytes: DefaultMaxBodyBytes,

		log: &utils.NoopLogger{},
	}
	for _, s := range setters {
		if err := s(strm); err != nil {
			return nil, err
		}
	}
	return strm, nil
}

// Wrap sets the next handler to be called by stream handler.
func (s *Stream) Wrap(next http.Handler) error {
	s.next = next
	return nil
}

func (s *Stream) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if s.verbose {
		dump := utils.DumpHTTPRequest(req)
		s.log.Debug("vulcand/oxy/stream: begin ServeHttp on request: %s", dump)
		defer s.log.Debug("vulcand/oxy/stream: completed ServeHttp on request: %s", dump)
	}

	s.next.ServeHTTP(w, req)
}