(w http.ResponseWriter, r *http.Request, path string, no404 bool)
| 245 | } |
| 246 | |
| 247 | func handleStreamFileFromReader(w http.ResponseWriter, r *http.Request, path string, no404 bool) error { |
| 248 | startTime := time.Now() |
| 249 | rangeHeader := r.Header.Get("Range") |
| 250 | log.Printf("stream-file path=%q range=%q\n", path, rangeHeader) |
| 251 | |
| 252 | writerRouteId, err := wshfs.GetConnectionRouteId(r.Context(), path) |
| 253 | if err != nil { |
| 254 | return err |
| 255 | } |
| 256 | |
| 257 | byteRange := "" |
| 258 | if rangeHeader != "" { |
| 259 | stripped := strings.TrimPrefix(rangeHeader, "bytes=") |
| 260 | br, parseErr := fileutil.ParseByteRange(stripped) |
| 261 | if parseErr != nil || br.All { |
| 262 | http.Error(w, "invalid range", http.StatusRequestedRangeNotSatisfiable) |
| 263 | return nil |
| 264 | } |
| 265 | byteRange = stripped |
| 266 | } |
| 267 | |
| 268 | bareRpc := wshclient.GetBareRpcClient() |
| 269 | readerRouteId := wshclient.GetBareRpcClientRouteId() |
| 270 | reader, streamMeta := bareRpc.StreamBroker.CreateStreamReader(readerRouteId, writerRouteId, 256*1024) |
| 271 | defer reader.Close() |
| 272 | go func() { |
| 273 | <-r.Context().Done() |
| 274 | reader.Close() |
| 275 | }() |
| 276 | |
| 277 | data := wshrpc.CommandFileStreamData{ |
| 278 | Info: &wshrpc.FileInfo{Path: path}, |
| 279 | ByteRange: byteRange, |
| 280 | StreamMeta: *streamMeta, |
| 281 | } |
| 282 | fileInfo, err := wshfs.FileStream(r.Context(), data) |
| 283 | if err != nil { |
| 284 | if no404 { |
| 285 | serveTransparentGIF(w) |
| 286 | return nil |
| 287 | } |
| 288 | return err |
| 289 | } |
| 290 | if fileInfo.NotFound { |
| 291 | if no404 { |
| 292 | serveTransparentGIF(w) |
| 293 | return nil |
| 294 | } |
| 295 | http.Error(w, fmt.Sprintf("file not found: %q", path), http.StatusNotFound) |
| 296 | return nil |
| 297 | } |
| 298 | if fileInfo.IsDir { |
| 299 | http.Error(w, fmt.Sprintf("cannot stream directory: %q", path), http.StatusBadRequest) |
| 300 | return nil |
| 301 | } |
| 302 | log.Printf("stream-file headers-ready path=%q time-to-headers=%v\n", path, time.Since(startTime)) |
| 303 | w.Header().Set(ContentTypeHeaderKey, fileInfo.MimeType) |
| 304 | w.Header().Set("Accept-Ranges", "bytes") |
no test coverage detected