github.com/adevinta/lava@v0.7.2/internal/urlutil/urlutil.go (about) 1 // Copyright 2023 Adevinta 2 3 // Package urlutil provides utilities for working with URLs. 4 package urlutil 5 6 import ( 7 "errors" 8 "fmt" 9 "io" 10 "net/http" 11 "net/url" 12 "os" 13 ) 14 15 var ( 16 // ErrInvalidScheme is returned by [Get] when the scheme of 17 // the provided URL is not supported. 18 ErrInvalidScheme = errors.New("invalid scheme") 19 20 // ErrInvalidURL is returned by [Get] when the provided URL is 21 // not valid. 22 ErrInvalidURL = errors.New("invalid URL") 23 ) 24 25 // Get retrieves the contents from a given raw URL. It returns error 26 // if the URL is not valid or if it is not possible to get the 27 // contents. 28 // 29 // It supports the following schemes: http, https. If the provided URL 30 // does not specify a scheme, it is considered a file path. In the 31 // case of http and https, the contents are retrieved issuing an HTTP 32 // GET request. 33 func Get(rawURL string) ([]byte, error) { 34 parsedURL, err := url.Parse(rawURL) 35 if err != nil { 36 return nil, fmt.Errorf("%w: %w", ErrInvalidURL, err) 37 } 38 39 switch parsedURL.Scheme { 40 case "http", "https": 41 return getHTTP(parsedURL) 42 case "": 43 return os.ReadFile(parsedURL.Path) 44 } 45 return nil, fmt.Errorf("%w: %v", ErrInvalidScheme, parsedURL.Scheme) 46 } 47 48 // getHTTP retrieves the contents of a given HTTP URL. 49 func getHTTP(parsedURL *url.URL) ([]byte, error) { 50 resp, err := http.Get(parsedURL.String()) 51 if err != nil { 52 return nil, fmt.Errorf("get %q: %w", parsedURL, err) 53 } 54 defer resp.Body.Close() 55 56 if resp.StatusCode != http.StatusOK { 57 return nil, fmt.Errorf("get %q: invalid status code: %v", parsedURL, resp.StatusCode) 58 } 59 return io.ReadAll(resp.Body) 60 }