github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/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 "fmt" 11 "io" 12 "io/ioutil" 13 "net/http" 14 "net/url" 15 "os" 16 "strings" 17 "time" 18 19 "cmd/pprof/internal/plugin" 20 "cmd/pprof/internal/profile" 21 ) 22 23 // FetchProfile reads from a data source (network, file) and generates a 24 // profile. 25 func FetchProfile(source string, timeout time.Duration) (*profile.Profile, error) { 26 return Fetcher(source, timeout, plugin.StandardUI()) 27 } 28 29 // Fetcher is the plugin.Fetcher version of FetchProfile. 30 func Fetcher(source string, timeout time.Duration, ui plugin.UI) (*profile.Profile, error) { 31 var f io.ReadCloser 32 var err error 33 34 url, err := url.Parse(source) 35 if err == nil && url.Host != "" { 36 f, err = FetchURL(source, timeout) 37 } else { 38 f, err = os.Open(source) 39 } 40 if err != nil { 41 return nil, err 42 } 43 defer f.Close() 44 return profile.Parse(f) 45 } 46 47 // FetchURL fetches a profile from a URL using HTTP. 48 func FetchURL(source string, timeout time.Duration) (io.ReadCloser, error) { 49 resp, err := httpGet(source, timeout) 50 if err != nil { 51 return nil, fmt.Errorf("http fetch %s: %v", source, err) 52 } 53 if resp.StatusCode != http.StatusOK { 54 return nil, fmt.Errorf("server response: %s", resp.Status) 55 } 56 57 return resp.Body, nil 58 } 59 60 // PostURL issues a POST to a URL over HTTP. 61 func PostURL(source, post string) ([]byte, error) { 62 resp, err := http.Post(source, "application/octet-stream", strings.NewReader(post)) 63 if err != nil { 64 return nil, fmt.Errorf("http post %s: %v", source, err) 65 } 66 if resp.StatusCode != http.StatusOK { 67 return nil, fmt.Errorf("server response: %s", resp.Status) 68 } 69 defer resp.Body.Close() 70 return ioutil.ReadAll(resp.Body) 71 } 72 73 // httpGet is a wrapper around http.Get; it is defined as a variable 74 // so it can be redefined during for testing. 75 var httpGet = func(url string, timeout time.Duration) (*http.Response, error) { 76 client := &http.Client{ 77 Transport: &http.Transport{ 78 ResponseHeaderTimeout: timeout + 5*time.Second, 79 }, 80 } 81 return client.Get(url) 82 }