ServeFileOption handles serving content based on the provided FileHandlerOption
(w http.ResponseWriter, r *http.Request, option FileHandlerOption)
| 385 | |
| 386 | // ServeFileOption handles serving content based on the provided FileHandlerOption |
| 387 | func ServeFileOption(w http.ResponseWriter, r *http.Request, option FileHandlerOption) error { |
| 388 | // Determine MIME type and get buffered data if needed |
| 389 | contentType, bufferedData := determineMimeType(option) |
| 390 | w.Header().Set("Content-Type", contentType) |
| 391 | // Handle ETag |
| 392 | if option.ETag != "" { |
| 393 | w.Header().Set("ETag", option.ETag) |
| 394 | |
| 395 | // Check If-None-Match header |
| 396 | if inm := r.Header.Get("If-None-Match"); inm != "" { |
| 397 | // Strip W/ prefix and quotes if present |
| 398 | inm = strings.Trim(inm, `"`) |
| 399 | inm = strings.TrimPrefix(inm, "W/") |
| 400 | etag := strings.Trim(option.ETag, `"`) |
| 401 | etag = strings.TrimPrefix(etag, "W/") |
| 402 | |
| 403 | if inm == etag { |
| 404 | // Resource not modified |
| 405 | w.WriteHeader(http.StatusNotModified) |
| 406 | return nil |
| 407 | } |
| 408 | } |
| 409 | } |
| 410 | |
| 411 | // Handle the content based on the option type |
| 412 | switch { |
| 413 | case option.FilePath != "": |
| 414 | filePath := wavebase.ExpandHomeDirSafe(option.FilePath) |
| 415 | http.ServeFile(w, r, filePath) |
| 416 | |
| 417 | case option.Data != nil: |
| 418 | w.Header().Set("Content-Length", fmt.Sprintf("%d", len(option.Data))) |
| 419 | w.WriteHeader(http.StatusOK) |
| 420 | if _, err := w.Write(option.Data); err != nil { |
| 421 | return fmt.Errorf("failed to write data: %v", err) |
| 422 | } |
| 423 | |
| 424 | case option.File != nil: |
| 425 | if bufferedData != nil { |
| 426 | if _, err := w.Write(bufferedData); err != nil { |
| 427 | return fmt.Errorf("failed to write buffered data: %v", err) |
| 428 | } |
| 429 | } |
| 430 | if _, err := io.Copy(w, option.File); err != nil { |
| 431 | return fmt.Errorf("failed to copy from file: %v", err) |
| 432 | } |
| 433 | |
| 434 | case option.Reader != nil: |
| 435 | if bufferedData != nil { |
| 436 | if _, err := w.Write(bufferedData); err != nil { |
| 437 | return fmt.Errorf("failed to write buffered data: %v", err) |
| 438 | } |
| 439 | } |
| 440 | if _, err := io.Copy(w, option.Reader); err != nil { |
| 441 | return fmt.Errorf("failed to copy from reader: %v", err) |
| 442 | } |
| 443 | |
| 444 | default: |
no test coverage detected