file.SectionReader interface required for MultiReaderAt this is here for refrence type SectionReader interface { io.Reader io.ReaderAt }
(streamRaw bool)
| 56 | //} |
| 57 | |
| 58 | func (s *Streamer) Stream(streamRaw bool) (err error) { |
| 59 | // file download |
| 60 | if !streamRaw { |
| 61 | fileName := fmt.Sprintf(" attachment; filename=%s", s.Filename) |
| 62 | // add extension for compression or archive |
| 63 | if s.Compression != "" { |
| 64 | fileName = fmt.Sprintf(" attachment; filename=%s.%s", s.Filename, s.Compression) |
| 65 | } |
| 66 | s.W.Header().Set("Content-Disposition", fileName) |
| 67 | } |
| 68 | // set headers |
| 69 | s.W.Header().Set("Content-Type", s.ContentType) |
| 70 | s.W.Header().Set("Connection", "close") |
| 71 | s.W.Header().Set("Access-Control-Allow-Headers", "Authorization") |
| 72 | s.W.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") |
| 73 | s.W.Header().Set("Access-Control-Allow-Origin", "*") |
| 74 | if (s.Size > 0) && (s.Filter == nil) && (s.Compression == "") { |
| 75 | s.W.Header().Set("Content-Length", fmt.Sprint(s.Size)) |
| 76 | } |
| 77 | |
| 78 | // pipe each SectionReader into one stream |
| 79 | // run filter pre-pipe |
| 80 | // return on error |
| 81 | pReader, pWriter := io.Pipe() |
| 82 | go func() { |
| 83 | defer pWriter.Close() |
| 84 | for i, sr := range s.R { |
| 85 | var rs io.Reader |
| 86 | if s.Filter != nil { |
| 87 | rs = s.Filter(sr) |
| 88 | } else { |
| 89 | rs = sr |
| 90 | } |
| 91 | _, ioerr := io.Copy(pWriter, rs) |
| 92 | if ioerr != nil { |
| 93 | s.E = ioerr |
| 94 | s.ESection = i |
| 95 | return |
| 96 | } |
| 97 | } |
| 98 | }() |
| 99 | |
| 100 | if s.E != nil { |
| 101 | pReader.Close() |
| 102 | err = fmt.Errorf("(request.Stream: section %d) failed: raw=%t; size=%d; file=%s; error=%s", s.ESection, streamRaw, s.Size, s.Filename, s.E.Error()) |
| 103 | return |
| 104 | } |
| 105 | |
| 106 | // pass pipe to ResponseWriter, go through compression if exists |
| 107 | cReader := archive.CompressReader(s.Compression, s.Filename, pReader) |
| 108 | _, ioerr := io.Copy(s.W, cReader) |
| 109 | |
| 110 | cReader.Close() |
| 111 | pReader.Close() |
| 112 | |
| 113 | if ioerr != nil { |
| 114 | err = fmt.Errorf("(request.Stream: full stream) failed: raw=%t; size=%d; file=%s; error=%s", streamRaw, s.Size, s.Filename, ioerr.Error()) |
| 115 | } |
no test coverage detected