func ImageHandler(deps *service.Dependencies) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		l := logger.SugaredWithRequest(r)
		res := deps.Storage.Get(r.Context(), r.URL.Path)
		if res.Error() != nil {
			l.Errorf("error from Storage.Get: %s", res.Error())
			deps.MetricService.CountImageHandlerErrors(StorageGetErrorKey)
			w.WriteHeader(res.Status())
			return
		}
		var data []byte
		var err error
		data = res.Data()
		params := make(map[string]string)
		values := r.URL.Query()
		if len(values) > 0 || deps.Manipulator.HasDefaultParams() {
			for v := range values {
				if len(values.Get(v)) != 0 {
					params[v] = values.Get(v)
				}
			}
			data, err = deps.Manipulator.Process(service.NewSpecBuilder().WithImageData(data).WithParams(params).Build())
			if err != nil {
				l.Errorf("error from Manipulator.Process: %s", err)
				deps.MetricService.CountImageHandlerErrors(ProcessorErrorKey)
				w.WriteHeader(http.StatusUnprocessableEntity)
				return
			}
		}
		w.Header().Set(CacheControlHeader, fmt.Sprintf("public,max-age=%d", config.CacheTime()))
		w.Header().Set(VaryHeader, "Accept")
		w.Header().Set(ContentLengthHeader, fmt.Sprintf("%d", len(data)))
		_, _ = w.Write(data)
	}
}
ImageHandler is responsible for fetching the path from the storage backend and processing it if required
package handler
import (
	"fmt"
	"net/http"
	"github.com/gojek/darkroom/pkg/config"
	"github.com/gojek/darkroom/pkg/logger"
	"github.com/gojek/darkroom/pkg/service"
)
const (
	ContentLengthHeader = "Content-Length"
	CacheControlHeader = "Cache-Control"
	VaryHeader = "Vary"
	StorageGetErrorKey = "storage_get_error"
	ProcessorErrorKey = "processor_error"
)