mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-11-07 00:05:14 +00:00
72 lines
2.3 KiB
Go
72 lines
2.3 KiB
Go
package dockerhub
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type SearchItem struct {
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
}
|
|
|
|
type SearchResult struct {
|
|
Items []SearchItem `json:"items"`
|
|
Total int64 `json:"total"`
|
|
ProxyRequired bool `json:"proxyRequired"`
|
|
}
|
|
|
|
// Search uses the panel HTTP client, not the Docker daemon's proxy settings.
|
|
func Search(ctx context.Context, client *http.Client, query string, page, pageSize int) (SearchResult, error) {
|
|
result := SearchResult{Items: []SearchItem{}}
|
|
query = strings.TrimSpace(query)
|
|
if query == "" || len([]rune(query)) > 256 || page < 1 || pageSize < 1 || pageSize > 100 {
|
|
return result, fmt.Errorf("invalid Docker Hub search parameters")
|
|
}
|
|
params := url.Values{"query": {query}, "page": {strconv.Itoa(page)}, "page_size": {strconv.Itoa(pageSize)}}
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://hub.docker.com/v2/search/repositories/?"+params.Encode(), nil)
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
req.Header.Set("Accept", "application/json")
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
// Transport errors can contain proxy credentials; do not expose their raw text.
|
|
if ctx.Err() != nil {
|
|
return result, ctx.Err()
|
|
}
|
|
return result, fmt.Errorf("Docker Hub connection failed; check network and proxy settings")
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
return result, fmt.Errorf("Docker Hub search: HTTP %d", resp.StatusCode)
|
|
}
|
|
var body struct {
|
|
Count *int64 `json:"count"`
|
|
Results []struct {
|
|
Name string `json:"repo_name"`
|
|
Description string `json:"short_description"`
|
|
} `json:"results"`
|
|
}
|
|
if err := json.NewDecoder(io.LimitReader(resp.Body, 4<<20)).Decode(&body); err != nil {
|
|
return result, fmt.Errorf("invalid Docker Hub search response")
|
|
}
|
|
if body.Count == nil || *body.Count < 0 {
|
|
return result, fmt.Errorf("invalid Docker Hub search response")
|
|
}
|
|
result.Total = *body.Count
|
|
for _, item := range body.Results {
|
|
if item.Name == "" {
|
|
return result, fmt.Errorf("invalid Docker Hub repository name")
|
|
}
|
|
result.Items = append(result.Items, SearchItem{Name: item.Name, Description: item.Description})
|
|
}
|
|
return result, nil
|
|
}
|