( storageDefRepo storage.StorageDefRepo, imageResponseCache *imageResponseCache, )
| 367 | } |
| 368 | |
| 369 | func makeDirectImageHandler( |
| 370 | storageDefRepo storage.StorageDefRepo, |
| 371 | imageResponseCache *imageResponseCache, |
| 372 | ) http.HandlerFunc { |
| 373 | return func(w http.ResponseWriter, r *http.Request) { |
| 374 | // URL format: <storage_definition_identifier>.<file_identifier> |
| 375 | urlSegments := strings.Split(r.URL.Path, "/") |
| 376 | if len(urlSegments) < 1 { |
| 377 | http.Error(w, "Not found", http.StatusNotFound) |
| 378 | httpLogger.Info().Msg("URL is not right") |
| 379 | return |
| 380 | } |
| 381 | lastSeg := urlSegments[len(urlSegments)-1] |
| 382 | segments := strings.SplitN(lastSeg, ".", 2) |
| 383 | if len(segments) != 2 { |
| 384 | http.Error(w, "Not found", http.StatusNotFound) |
| 385 | httpLogger.Info().Msg("URL is not right") |
| 386 | return |
| 387 | } |
| 388 | storageDefIdentifier := segments[0] |
| 389 | fileIdentifier := segments[1] |
| 390 | cacheKey := "direct:" + storageDefIdentifier + ":" + fileIdentifier |
| 391 | if entry, ok := imageResponseCache.get(cacheKey); ok { |
| 392 | writeCachedImageResponse(w, r, entry) |
| 393 | return |
| 394 | } |
| 395 | if r.Header.Get("If-None-Match") == fileIdentifier { |
| 396 | w.WriteHeader(http.StatusNotModified) |
| 397 | return |
| 398 | } |
| 399 | storageDef, err := storageDefRepo.GetStorageDefinitionByIdentifier(storageDefIdentifier) |
| 400 | if err != nil { |
| 401 | http.Error(w, "Not found", http.StatusNotFound) |
| 402 | httpLogger.Error().Str("storage_definition_identifier", storageDefIdentifier).Err(err).Msg("Unable to get storage definition") |
| 403 | return |
| 404 | } |
| 405 | if !storageDef.IsEnabled { |
| 406 | http.Error(w, "Not found", http.StatusNotFound) |
| 407 | httpLogger.Error().Str("storage_definition_identifier", storageDefIdentifier).Msg("Storage definition is not enabled") |
| 408 | return |
| 409 | } |
| 410 | storageInstance, err := storage.GetStorage(storageDef) |
| 411 | if err != nil { |
| 412 | http.Error(w, "Not found", http.StatusNotFound) |
| 413 | httpLogger.Error().Str("storage_definition_identifier", storageDefIdentifier).Err(err).Msg("Unable to get storage instance") |
| 414 | return |
| 415 | } |
| 416 | meta := storage.GetMetaCached(storageInstance, storageDef.Id, fileIdentifier) |
| 417 | w.Header().Set("Content-Type", meta.ContentType) |
| 418 | w.Header().Set("Content-Length", strconv.FormatInt(meta.ByteSize, 10)) |
| 419 | w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") |
| 420 | w.Header().Set("ETag", fileIdentifier) |
| 421 | w.Header().Set("X-imgdd-si", storageDef.Identifier) |
| 422 | w.WriteHeader(http.StatusOK) |
| 423 | if r.Method == http.MethodHead { |
| 424 | return |
| 425 | } |
| 426 | reader := storageInstance.GetReader(fileIdentifier) |
no test coverage detected