func onEC2() bool {
	if loc == nil {
		loc = &location{}
	}
	if !(loc.checked) {
		c, err := net.DialTimeout("tcp", "169.254.169.254:80", time.Millisecond*100)
		if err != nil {
			loc.ec2 = false
		} else {
			c.Close()
			loc.ec2 = true
		}
		loc.checked = true
	}
	return loc.ec2
}
onEC2 checks to see if the program is running on an EC2 instance.
It does this by looking for the EC2 metadata service.
This caches that information in a struct so that it doesn't waste time.
package awsauth
import (
	"bufio"
	"bytes"
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"
)
type location struct {
	ec2     bool
	checked bool
}
var loc *location
func serviceAndRegion(host string) (service string, region string) {
	region = "us-east-1"
	service = "s3"
	parts := strings.Split(host, ".")
	if len(parts) == 4 {
		if parts[1] == "s3" {
			service = "s3"
		} else if strings.HasPrefix(parts[1], "s3-") {
			region = parts[1][3:]
			service = "s3"
		} else {
			service = parts[0]
			region = parts[1]
		}
	} else if len(parts) == 5 {
		service = parts[2]
		region = parts[1]
	} else {
		if strings.HasPrefix(parts[0], "s3-") {
			region = parts[0][3:]
		} else {
			service = parts[0]
		}
	}
	if region == "external-1" {
		region = "us-east-1"
	}
	return
}
func newKeys() (newCredentials Credentials) {
	newCredentials.AccessKeyID = os.Getenv(envAccessKeyID)
	if newCredentials.AccessKeyID == "" {
		newCredentials.AccessKeyID = os.Getenv(envAccessKey)
	}
	newCredentials.SecretAccessKey = os.Getenv(envSecretAccessKey)
	if newCredentials.SecretAccessKey == "" {
		newCredentials.SecretAccessKey = os.Getenv(envSecretKey)
	}
	newCredentials.SecurityToken = os.Getenv(envSecurityToken)
	if (newCredentials.AccessKeyID == "" || newCredentials.SecretAccessKey == "") && onEC2() {
		newCredentials = *getIAMRoleCredentials()
	}
	if newCredentials.expired() && onEC2() {
		newCredentials = *getIAMRoleCredentials()
	}
	return newCredentials
}
func chooseKeys(cred []Credentials) Credentials {
	if len(cred) == 0 {
		return newKeys()
	} else {
		return cred[0]
	}
}