func PostForm(url string, data url.Values) (resp *http.Response, attempts int, err error) {
	return defaultClient.PostForm(url, data)
}
PostForm works the same as HTTPRetryClient.PostForm, but uses the default exponential back off settings
package httpbackoff
import (
	"bufio"
	"bytes"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
	"time"
	"github.com/cenkalti/backoff"
)
var defaultClient Client = Client{
	BackOffSettings: backoff.NewExponentialBackOff(),
}
type Client struct {
	BackOffSettings *backoff.ExponentialBackOff
}
type BadHttpResponseCode struct {
	HttpResponseCode int
	Message          string
}
func (err BadHttpResponseCode) Error() string {
	return err.Message
}
func (httpRetryClient *Client) Retry(httpCall func() (resp *http.Response, tempError error, permError error)) (*http.Response, int, error) {
	var tempError, permError error
	var response *http.Response
	attempts := 0
	doHttpCall := func() error {
		response, tempError, permError = httpCall()
		attempts += 1
		if tempError != nil {
			return tempError
		}
		if permError != nil {
			return nil
		}
		body := func(response *http.Response) string {
			raw, err := httputil.DumpResponse(response, true)
			if err == nil {
				return string(raw)
			}
			return ""
		}
		if respCode := response.StatusCode; respCode/100 == 5 {
			return BadHttpResponseCode{
				HttpResponseCode: respCode,
				Message:          "(Intermittent) HTTP response code " + strconv.Itoa(respCode) + "\n" + body(response),
			}
		}
		if respCode := response.StatusCode; respCode/100 != 2 {
			permError = BadHttpResponseCode{
				HttpResponseCode: respCode,
				Message:          "(Permanent) HTTP response code " + strconv.Itoa(respCode) + "\n" + body(response),
			}
			return nil
		}
		return nil
	}
	b := backoff.ExponentialBackOff(*httpRetryClient.BackOffSettings)
	backoff.RetryNotify(doHttpCall, &b, func(err error, wait time.Duration) {
		log.Printf("Error: %s", err)
	})
	switch {
	case permError != nil:
		return response, attempts, permError
	case tempError != nil:
		return response, attempts, tempError
	default:
		return response, attempts, nil
	}
}
func Retry(httpCall func() (resp *http.Response, tempError error, permError error)) (*http.Response, int, error) {
	return defaultClient.Retry(httpCall)
}
func (httpRetryClient *Client) Get(url string) (resp *http.Response, attempts int, err error) {
	return httpRetryClient.Retry(func() (*http.Response, error, error) {
		resp, err := http.Get(url)
		return resp, err, nil
	})
}
func Get(url string) (resp *http.Response, attempts int, err error) {
	return defaultClient.Get(url)
}
func (httpRetryClient *Client) Head(url string) (resp *http.Response, attempts int, err error) {
	return httpRetryClient.Retry(func() (*http.Response, error, error) {
		resp, err := http.Head(url)
		return resp, err, nil
	})
}
func Head(url string) (resp *http.Response, attempts int, err error) {
	return defaultClient.Head(url)
}
func (httpRetryClient *Client) Post(url string, bodyType string, body []byte) (resp *http.Response, attempts int, err error) {
	return httpRetryClient.Retry(func() (*http.Response, error, error) {
		resp, err := http.Post(url, bodyType, bytes.NewBuffer(body))
		return resp, err, nil
	})
}
func Post(url string, bodyType string, body []byte) (resp *http.Response, attempts int, err error) {
	return defaultClient.Post(url, bodyType, body)
}
func (httpRetryClient *Client) PostForm(url string, data url.Values) (resp *http.Response, attempts int, err error) {
	return httpRetryClient.Retry(func() (*http.Response, error, error) {
		resp, err := http.PostForm(url, data)
		return resp, err, nil
	})
}