github.com/freddyisaac/sicortex-golang@v0.0.0-20231019035217-e03519e66f60/src/cmd/pprof/internal/fetch/fetch.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package fetch provides an extensible mechanism to fetch a profile 6 // from a data source. 7 package fetch 8 9 import ( 10 "crypto/tls" 11 "fmt" 12 "io" 13 "io/ioutil" 14 "net/http" 15 "net/url" 16 "os" 17 "strings" 18 "time" 19 20 "cmd/pprof/internal/plugin" 21 "internal/pprof/profile" 22 ) 23 24 // FetchProfile reads from a data source (network, file) and generates a 25 // profile. 26 func FetchProfile(source string, timeout time.Duration) (*profile.Profile, error) { 27 return Fetcher(source, timeout, plugin.StandardUI()) 28 } 29 30 // Fetcher is the plugin.Fetcher version of FetchProfile. 31 func Fetcher(source string, timeout time.Duration, ui plugin.UI) (*profile.Profile, error) { 32 var f io.ReadCloser 33 var err error 34 35 url, err := url.Parse(source) 36 if err == nil && url.Host != "" { 37 f, err = FetchURL(source, timeout) 38 } else { 39 f, err = os.Open(source) 40 } 41 if err != nil { 42 return nil, err 43 } 44 defer f.Close() 45 return profile.Parse(f) 46 } 47 48 // FetchURL fetches a profile from a URL using HTTP. 49 func FetchURL(source string, timeout time.Duration) (io.ReadCloser, error) { 50 resp, err := httpGet(source, timeout) 51 if err != nil { 52 return nil, fmt.Errorf("http fetch %s: %v", source, err) 53 } 54 if resp.StatusCode != http.StatusOK { 55 return nil, fmt.Errorf("server response: %s", resp.Status) 56 } 57 58 return resp.Body, nil 59 } 60 61 // PostURL issues a POST to a URL over HTTP. 62 func PostURL(source, post string) ([]byte, error) { 63 resp, err := http.Post(source, "application/octet-stream", strings.NewReader(post)) 64 if err != nil { 65 return nil, fmt.Errorf("http post %s: %v", source, err) 66 } 67 if resp.StatusCode != http.StatusOK { 68 return nil, fmt.Errorf("server response: %s", resp.Status) 69 } 70 defer resp.Body.Close() 71 return ioutil.ReadAll(resp.Body) 72 } 73 74 // httpGet is a wrapper around http.Get; it is defined as a variable 75 // so it can be redefined during for testing. 76 var httpGet = func(source string, timeout time.Duration) (*http.Response, error) { 77 url, err := url.Parse(source) 78 if err != nil { 79 return nil, err 80 } 81 82 var tlsConfig *tls.Config 83 if url.Scheme == "https+insecure" { 84 tlsConfig = &tls.Config{ 85 InsecureSkipVerify: true, 86 } 87 url.Scheme = "https" 88 source = url.String() 89 } 90 91 client := &http.Client{ 92 Transport: &http.Transport{ 93 ResponseHeaderTimeout: timeout + 5*time.Second, 94 TLSClientConfig: tlsConfig, 95 }, 96 } 97 return client.Get(source) 98 }