-
Notifications
You must be signed in to change notification settings - Fork 0
/
stream.go
181 lines (160 loc) · 7.24 KB
/
stream.go
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package services
import (
"io"
)
// ContentGetter provides a way for your service response to indicate that you want to return a
// raw stream of bytes rather than relying on our auto-encoding.
type ContentGetter interface {
// Content returns the stream of exact bytes to send back to the caller.
Content() io.ReadCloser
}
// ContentSetter allows raw stream responses to be properly reconstituted when using the
// code-generated Go client for your service.
type ContentSetter interface {
// SetContent applies the stream of bytes that the response object should use when reading.
SetContent(io.ReadCloser)
}
// ContentTypeGetter is used by raw response streams to indicate what type of data is in the stream.
type ContentTypeGetter interface {
// ContentType returns the MIME encoding type of the raw content stream.
ContentType() string
}
// ContentTypeSetter recaptures the custom content type header from raw responses when using the
// code-generated Go client for your service.
type ContentTypeSetter interface {
// SetContentType sets the MIME encoding type of the raw content stream.
SetContentType(string)
}
// ContentLengthGetter is used by raw response streams to indicate exactly how many bytes are
// in the response's Content stream.
type ContentLengthGetter interface {
// ContentLength returns the total number of bytes you can/should read from the Content stream.
ContentLength() int
}
// ContentLengthSetter recaptures the custom content length header from raw responses when using
// the code-generate Go client for your services.
type ContentLengthSetter interface {
// SetContentLength applies the total number of bytes you can/should read from the Content stream.
SetContentLength(int)
}
// ContentRangeGetter is used by raw response streams to indicate that this is resumable using the
// standard Range header.
type ContentRangeGetter interface {
// ContentRange returns the individual values used to build a custom Content-Range header
// when responding with a raw content stream. For more information on how these values are
// used, please see: https://www.geeksforgeeks.org/http-headers-content-range/
ContentRange() (start int, end int, size int)
}
// ContentRangeSetter recaptures the custom content range header from raw responses when using
// the code-generated Go client for your services.
type ContentRangeSetter interface {
// SetContentRange accepts the 3 standard components of the Content-Range header.
SetContentRange(start int, end int, size int)
}
// StreamRequest implements all of the ContentXxx and SetContentXxx methods that we support and look
// at when we look at streaming/upload style requests.
//
// type FileUploadRequest struct {
// services.StreamRequest
// }
//
// func (res *ImageDownloadResponse) Init(file os.File, info fs.FileInfo) {
// res.SetContent(file)
// res.SetContentType("image/png")
// res.SetContentLength(info.Size())
// }
type StreamRequest struct {
content io.ReadCloser
contentType string
contentLength int
}
// StreamResponse implements all of the ContentXxx and SetContentXxx methods that we support. You
// can embed one of these structs in your response struct to automatically gain the ability to
// respond with raw data streams rather than auto-encoding.
//
// type ImageDownloadResponse struct {
// services.StreamResponse
// }
//
// func (res *ImageDownloadResponse) Init(file os.File, info fs.FileInfo) {
// res.SetContent(file)
// res.SetContentType("image/png")
// res.SetContentLength(info.Size())
// }
type StreamResponse struct {
content io.ReadCloser
contentType string
contentLength int
contentRangeStart int
contentRangeEnd int
contentRangeSize int
}
// Content returns the raw byte stream representing the data returned by the endpoint.
func (res *StreamResponse) Content() io.ReadCloser {
return res.content
}
// SetContent applies the raw byte stream representing the data returned by the endpoint.
func (res *StreamResponse) SetContent(content io.ReadCloser) {
res.content = content
}
// ContentRange returns non-zero values if this resource supports the ability to resume downloads.
func (res *StreamResponse) ContentRange() (start int, end int, size int) {
return res.contentRangeStart, res.contentRangeEnd, res.contentRangeSize
}
// SetContentRange applies the attributes related to controlling resumable downloads.
func (res *StreamResponse) SetContentRange(start int, end int, size int) {
res.contentRangeStart = start
res.contentRangeEnd = end
res.contentRangeSize = size
}
// ContentType returns the MIME content type string describe the type of data in the stream.
func (res *StreamResponse) ContentType() string {
return res.contentType
}
// SetContentType applies the MIME content type that describes the data in the stream.
func (res *StreamResponse) SetContentType(contentType string) {
res.contentType = contentType
}
// ContentLength returns the number of bytes you can read from the content stream.
func (res *StreamResponse) ContentLength() int {
return res.contentLength
}
// SetContentLength sets the number of bytes the caller should read from the content stream.
func (res *StreamResponse) SetContentLength(contentLength int) {
res.contentLength = contentLength
}
// Redirector provides a way to tell gateways that the response value doesn't contain the
// raw byte stream we want to deliver. Instead, you should redirect to that URI to fetch
// the response data.
//
// This indicates the redirect is temporary, and you should probably continue to use the same
// endpoint address in the future. You'd probably use this more in cases such as redirecting
// to a file on S3; something that will be different each time.
//
// GATEWAY COMPATABILITY: This currently only works with the API gateway. When delivering/receiving
// responses through other gateways such as "Events", your response will be auto-encoded just
// like it was a normal struct/value. As a result, your response should continue to maintain
// exported fields that you would like to transport in those cases.
type Redirector interface {
// Redirect returns the URI of an alternate resource that will provide the final data
// we want this endpoint to return.
Redirect() string
}
// RedirectorPermanent provides a way to tell gateways that the response value doesn't contain the
// raw byte stream we want to deliver. Instead, you should redirect to that URI to fetch
// the response data.
//
// This indicates that the redirect is permanent, and you should probably start using the
// redirected URI moving forward. You'd probably use this more in a situation where you are
// deprecating one API endpoint in favor of another. The old endpoint could redirect to the
// new endpoint to maintain backwards compatability, but you really should start using the new one.
//
// GATEWAY COMPATABILITY: This currently only works with the API gateway. When delivering/receiving
// responses through other gateways such as "Events", your response will be auto-encoded just
// like it was a normal struct/value. As a result, your response should continue to maintain
// exported fields that you would like to transport in those cases.
type RedirectorPermanent interface {
// RedirectPermanent returns the URI of an alternate resource that will provide the final data
// we want this endpoint to return.
RedirectPermanent() string
}