podman
121 строка · 3.6 Кб
1// Copyright 2015 go-swagger maintainers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package swag16
17import (18"fmt"19"io"20"log"21"net/http"22"net/url"23"os"24"path/filepath"25"runtime"26"strings"27"time"28)
29
30// LoadHTTPTimeout the default timeout for load requests
31var LoadHTTPTimeout = 30 * time.Second32
33// LoadHTTPBasicAuthUsername the username to use when load requests require basic auth
34var LoadHTTPBasicAuthUsername = ""35
36// LoadHTTPBasicAuthPassword the password to use when load requests require basic auth
37var LoadHTTPBasicAuthPassword = ""38
39// LoadHTTPCustomHeaders an optional collection of custom HTTP headers for load requests
40var LoadHTTPCustomHeaders = map[string]string{}41
42// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
43func LoadFromFileOrHTTP(path string) ([]byte, error) {44return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)45}
46
47// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in
48// timeout arg allows for per request overriding of the request timeout
49func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) {50return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path)51}
52
53// LoadStrategy returns a loader function for a given path or uri
54func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {55if strings.HasPrefix(path, "http") {56return remote57}58return func(pth string) ([]byte, error) {59upth, err := pathUnescape(pth)60if err != nil {61return nil, err62}63
64if strings.HasPrefix(pth, `file://`) {65if runtime.GOOS == "windows" {66// support for canonical file URIs on windows.67// Zero tolerance here for dodgy URIs.68u, _ := url.Parse(upth)69if u.Host != "" {70// assume UNC name (volume share)71// file://host/share/folder\... ==> \\host\share\path\folder72// NOTE: UNC port not yet supported73upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`)74} else {75// file:///c:/folder/... ==> just remove the leading slash76upth = strings.TrimPrefix(upth, `file:///`)77}78} else {79upth = strings.TrimPrefix(upth, `file://`)80}81}82
83return local(filepath.FromSlash(upth))84}85}
86
87func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) {88return func(path string) ([]byte, error) {89client := &http.Client{Timeout: timeout}90req, err := http.NewRequest(http.MethodGet, path, nil) //nolint:noctx91if err != nil {92return nil, err93}94
95if LoadHTTPBasicAuthUsername != "" && LoadHTTPBasicAuthPassword != "" {96req.SetBasicAuth(LoadHTTPBasicAuthUsername, LoadHTTPBasicAuthPassword)97}98
99for key, val := range LoadHTTPCustomHeaders {100req.Header.Set(key, val)101}102
103resp, err := client.Do(req)104defer func() {105if resp != nil {106if e := resp.Body.Close(); e != nil {107log.Println(e)108}109}110}()111if err != nil {112return nil, err113}114
115if resp.StatusCode != http.StatusOK {116return nil, fmt.Errorf("could not access document at %q [%s] ", path, resp.Status)117}118
119return io.ReadAll(resp.Body)120}121}
122