github.com/machinebox/remoto@v0.1.2-0.20191024144331-eff21a7d321f/go/remotohttp/remototypes/remototypes.go (about) 1 package remototypes 2 3 import ( 4 "context" 5 "errors" 6 "io" 7 ) 8 9 // File describes a binary file. 10 // This type is only allowed in requests, for responses RPC methods should 11 // return a FileResponse. 12 type File struct { 13 Fieldname string `json:"fieldname"` 14 Filename string `json:"filename"` 15 } 16 17 // Open opens the file as an io.ReadCloser. 18 // Callers must close the file. 19 func (f File) Open(ctx context.Context) (io.ReadCloser, error) { 20 opener, ok := ctx.Value(contextKeyFileOpener).(Opener) 21 if !ok { 22 return nil, errors.New("opener missing from context") 23 } 24 return opener(ctx, f) 25 } 26 27 // FileResponse is response type for a file. 28 type FileResponse struct { 29 Filename string `json:"filename"` 30 ContentType string `json:"contentType"` 31 ContentLength int `json:"contentLength"` 32 Data io.Reader `json:"-"` 33 Error string `json:"error"` 34 } 35 36 // Opener is a function that knows how to open files. 37 type Opener func(ctx context.Context, file File) (io.ReadCloser, error) 38 39 // WithOpener gets a new context.Context with the specified Opener. 40 func WithOpener(ctx context.Context, opener Opener) context.Context { 41 return context.WithValue(ctx, contextKeyFileOpener, opener) 42 } 43 44 // contextKey is a local context key type. 45 // see https://medium.com/@matryer/context-keys-in-go-5312346a868d 46 type contextKey string 47 48 func (c contextKey) String() string { 49 return "remototypes context key: " + string(c) 50 } 51 52 // contextKeyFileOpener is the context key for a function capable of 53 // opening files. 54 var contextKeyFileOpener = contextKey("files")