ctxhttp.go

 1// Copyright 2016 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// +build go1.7
 6
 7// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
 8//
 9// It's a copy of "golang.org/x/net/context/ctxhttp" with pre-1.7 support dropped,
10// and "golang.org/x/net/context" import replaced with "context".
11// It exists temporarily until "golang.org/x/net/context/ctxhttp" is updated,
12// which will happen "in a couple releases" according to https://golang.org/cl/24620.
13package ctxhttp
14
15import (
16	"context"
17	"io"
18	"net/http"
19	"net/url"
20	"strings"
21)
22
23// Do sends an HTTP request with the provided http.Client and returns
24// an HTTP response.
25//
26// If the client is nil, http.DefaultClient is used.
27//
28// The provided ctx must be non-nil. If it is canceled or times out,
29// ctx.Err() will be returned.
30func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
31	if client == nil {
32		client = http.DefaultClient
33	}
34	resp, err := client.Do(req.WithContext(ctx))
35	// If we got an error, and the context has been canceled,
36	// the context's error is probably more useful.
37	if err != nil {
38		select {
39		case <-ctx.Done():
40			err = ctx.Err()
41		default:
42		}
43	}
44	return resp, err
45}
46
47// Get issues a GET request via the Do function.
48func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
49	req, err := http.NewRequest("GET", url, nil)
50	if err != nil {
51		return nil, err
52	}
53	return Do(ctx, client, req)
54}
55
56// Head issues a HEAD request via the Do function.
57func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
58	req, err := http.NewRequest("HEAD", url, nil)
59	if err != nil {
60		return nil, err
61	}
62	return Do(ctx, client, req)
63}
64
65// Post issues a POST request via the Do function.
66func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
67	req, err := http.NewRequest("POST", url, body)
68	if err != nil {
69		return nil, err
70	}
71	req.Header.Set("Content-Type", bodyType)
72	return Do(ctx, client, req)
73}
74
75// PostForm issues a POST request via the Do function.
76func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
77	return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
78}