github.com/wuhuizuo/gomplate@v3.5.0+incompatible/data/datasource_http.go (about)

     1  package data
     2  
     3  import (
     4  	"io/ioutil"
     5  	"mime"
     6  	"net/http"
     7  	"net/url"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  func buildURL(base *url.URL, args ...string) (*url.URL, error) {
    15  	if len(args) == 0 {
    16  		return base, nil
    17  	}
    18  	p, err := url.Parse(args[0])
    19  	if err != nil {
    20  		return nil, errors.Wrapf(err, "bad sub-path %s", args[0])
    21  	}
    22  	return base.ResolveReference(p), nil
    23  }
    24  
    25  func readHTTP(source *Source, args ...string) ([]byte, error) {
    26  	if source.hc == nil {
    27  		source.hc = &http.Client{Timeout: time.Second * 5}
    28  	}
    29  	u, err := buildURL(source.URL, args...)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	req, err := http.NewRequest("GET", u.String(), nil)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	req.Header = source.header
    38  	res, err := source.hc.Do(req)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	body, err := ioutil.ReadAll(res.Body)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	err = res.Body.Close()
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	if res.StatusCode != 200 {
    51  		err := errors.Errorf("Unexpected HTTP status %d on GET from %s: %s", res.StatusCode, source.URL, string(body))
    52  		return nil, err
    53  	}
    54  	ctypeHdr := res.Header.Get("Content-Type")
    55  	if ctypeHdr != "" {
    56  		mediatype, _, e := mime.ParseMediaType(ctypeHdr)
    57  		if e != nil {
    58  			return nil, e
    59  		}
    60  		source.mediaType = mediatype
    61  	}
    62  	return body, nil
    63  }
    64  
    65  func parseHeaderArgs(headerArgs []string) (map[string]http.Header, error) {
    66  	headers := make(map[string]http.Header)
    67  	for _, v := range headerArgs {
    68  		ds, name, value, err := splitHeaderArg(v)
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  		if _, ok := headers[ds]; !ok {
    73  			headers[ds] = make(http.Header)
    74  		}
    75  		headers[ds][name] = append(headers[ds][name], strings.TrimSpace(value))
    76  	}
    77  	return headers, nil
    78  }
    79  
    80  func splitHeaderArg(arg string) (datasourceAlias, name, value string, err error) {
    81  	parts := strings.SplitN(arg, "=", 2)
    82  	if len(parts) != 2 {
    83  		err = errors.Errorf("Invalid datasource-header option '%s'", arg)
    84  		return "", "", "", err
    85  	}
    86  	datasourceAlias = parts[0]
    87  	name, value, err = splitHeader(parts[1])
    88  	return datasourceAlias, name, value, err
    89  }
    90  
    91  func splitHeader(header string) (name, value string, err error) {
    92  	parts := strings.SplitN(header, ":", 2)
    93  	if len(parts) != 2 {
    94  		err = errors.Errorf("Invalid HTTP Header format '%s'", header)
    95  		return "", "", err
    96  	}
    97  	name = http.CanonicalHeaderKey(parts[0])
    98  	value = parts[1]
    99  	return name, value, nil
   100  }