Files
podman/pkg/util/filters.go
Philip Dubé 522934d5cf Replace strings.SplitN with strings.Cut
Cut is a cleaner & more performant api relative to SplitN(_, _, 2) added in go 1.18

Previously applied this refactoring to buildah:
https://github.com/containers/buildah/pull/5239

Signed-off-by: Philip Dubé <philip@peerdb.io>
2024-01-11 13:50:15 +00:00

75 lines
2.1 KiB
Go

package util
import (
"encoding/json"
"fmt"
"net/http"
"strings"
)
// filtersFromRequests extracts the "filters" parameter from the specified
// http.Request. The parameter can either be a `map[string][]string` as done
// in new versions of Docker and libpod, or a `map[string]map[string]bool` as
// done in older versions of Docker. We have to do a bit of Yoga to support
// both - just as Docker does as well.
//
// Please refer to https://github.com/containers/podman/issues/6899 for some
// background.
func FiltersFromRequest(r *http.Request) ([]string, error) {
var (
compatFilters map[string]map[string]bool
filters map[string][]string
libpodFilters []string
raw []byte
)
if _, found := r.URL.Query()["filters"]; found {
raw = []byte(r.Form.Get("filters"))
} else if _, found := r.URL.Query()["Filters"]; found {
raw = []byte(r.Form.Get("Filters"))
} else {
return []string{}, nil
}
// Backwards compat with older versions of Docker.
if err := json.Unmarshal(raw, &compatFilters); err == nil {
for filterKey, filterMap := range compatFilters {
for filterValue, toAdd := range filterMap {
if toAdd {
libpodFilters = append(libpodFilters, fmt.Sprintf("%s=%s", filterKey, filterValue))
}
}
}
return libpodFilters, nil
}
if err := json.Unmarshal(raw, &filters); err != nil {
return nil, err
}
for filterKey, filterSlice := range filters {
for _, filterValue := range filterSlice {
libpodFilters = append(libpodFilters, fmt.Sprintf("%s=%s", filterKey, filterValue))
}
}
return libpodFilters, nil
}
// PrepareFilters prepares a *map[string][]string of filters to be later searched
// in lipod and compat API to get desired filters
func PrepareFilters(r *http.Request) (*map[string][]string, error) {
filtersList, err := FiltersFromRequest(r)
if err != nil {
return nil, err
}
filterMap := map[string][]string{}
for _, filter := range filtersList {
fname, filter, hasFilter := strings.Cut(filter, "=")
if hasFilter {
filterMap[fname] = append(filterMap[fname], filter)
}
}
return &filterMap, nil
}