func (c *Client) PutContext(ctx context.Context, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) {
	return c.do(ctx, urlStr, &request{method: http.MethodPut, credentials: credentials, form: form})
}
PutContext uses Context to perform Put.
package oauth  
import (
	"bytes"
	"crypto"
	"crypto/hmac"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"encoding/base64"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"sync/atomic"
	"time"
	"golang.org/x/net/context"
)
var noEscape = [256]bool{
	'A': true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
	'a': true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
	'0': true, true, true, true, true, true, true, true, true, true,
	'-': true,
	'.': true,
	'_': true,
	'~': true,
}
func encode(s string, double bool) []byte {
	m := 3
	if double {
		m = 5
	}
	n := 0
	for i := 0; i < len(s); i++ {
		if noEscape[s[i]] {
			n++
		} else {
			n += m
		}
	}
	p := make([]byte, n)
	j := 0
	for i := 0; i < len(s); i++ {
		b := s[i]
		if noEscape[b] {
			p[j] = b
			j++
		} else if double {
			p[j] = '%'
			p[j+1] = '2'
			p[j+2] = '5'
			p[j+3] = "0123456789ABCDEF"[b>>4]
			p[j+4] = "0123456789ABCDEF"[b&15]
			j += 5
		} else {
			p[j] = '%'
			p[j+1] = "0123456789ABCDEF"[b>>4]
			p[j+2] = "0123456789ABCDEF"[b&15]
			j += 3
		}
	}
	return p
}
type keyValue struct{ key, value []byte }
type byKeyValue []keyValue
func (p byKeyValue) Len() int      { return len(p) }
func (p byKeyValue) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p byKeyValue) Less(i, j int) bool {
	sgn := bytes.Compare(p[i].key, p[j].key)
	if sgn == 0 {
		sgn = bytes.Compare(p[i].value, p[j].value)
	}
	return sgn < 0
}
func (p byKeyValue) appendValues(values url.Values) byKeyValue {
	for k, vs := range values {
		k := encode(k, true)
		for _, v := range vs {
			v := encode(v, true)
			p = append(p, keyValue{k, v})
		}
	}
	return p
}
func writeBaseString(w io.Writer, method string, u *url.URL, form url.Values, oauthParams map[string]string) {
	w.Write(encode(strings.ToUpper(method), false))
	w.Write([]byte{'&'})
	scheme := strings.ToLower(u.Scheme)
	host := strings.ToLower(u.Host)
	uNoQuery := *u
	uNoQuery.RawQuery = ""
	path := uNoQuery.RequestURI()
	switch {
	case scheme == "http" && strings.HasSuffix(host, ":80"):
		host = host[:len(host)-len(":80")]
	case scheme == "https" && strings.HasSuffix(host, ":443"):
		host = host[:len(host)-len(":443")]
	}
	w.Write(encode(scheme, false))
	w.Write(encode("://", false))
	w.Write(encode(host, false))
	w.Write(encode(path, false))
	w.Write([]byte{'&'})
	queryParams := u.Query()
	p := make(byKeyValue, 0, len(form)+len(queryParams)+len(oauthParams))
	p = p.appendValues(form)
	p = p.appendValues(queryParams)
	for k, v := range oauthParams {
		p = append(p, keyValue{encode(k, true), encode(v, true)})
	}
	sort.Sort(p)
	encodedAmp := encode("&", false)
	encodedEqual := encode("=", false)
	sep := false
	for _, kv := range p {
		if sep {
			w.Write(encodedAmp)
		} else {
			sep = true
		}
		w.Write(kv.key)
		w.Write(encodedEqual)
		w.Write(kv.value)
	}
}
var nonceCounter uint64
func init() {
	if err := binary.Read(rand.Reader, binary.BigEndian, &nonceCounter); err != nil {
		nonceCounter = uint64(time.Now().UnixNano())
	}
}
func nonce() string {
	return strconv.FormatUint(atomic.AddUint64(&nonceCounter, 1), 16)
}
type SignatureMethod int
func (sm SignatureMethod) String() string {
	switch sm {
	case RSASHA1:
		return "RSA-SHA1"
	case HMACSHA1:
		return "HMAC-SHA1"
	case PLAINTEXT:
		return "PLAINTEXT"
	default:
		return "unknown"
	}
}
const (
	HMACSHA1  SignatureMethod = iota  
	RSASHA1                           
	PLAINTEXT                         
)
type Credentials struct {
	Token  string  
	Secret string  
}
type Client struct {
	Credentials Credentials
	TemporaryCredentialRequestURI string
	ResourceOwnerAuthorizationURI string
	TokenRequestURI string
	RenewCredentialRequestURI string
	TemporaryCredentialsMethod string
	TokenCredentailsMethod string
	Header http.Header
	SignatureMethod SignatureMethod
	PrivateKey *rsa.PrivateKey
}
type request struct {
	credentials   *Credentials
	method        string
	u             *url.URL
	form          url.Values
	verifier      string
	sessionHandle string
	callbackURL   string
}
var testHook = func(map[string]string) {}
func (c *Client) oauthParams(r *request) (map[string]string, error) {
	oauthParams := map[string]string{
		"oauth_consumer_key":     c.Credentials.Token,
		"oauth_signature_method": c.SignatureMethod.String(),
		"oauth_version":          "1.0",
	}
	if c.SignatureMethod != PLAINTEXT {
		oauthParams["oauth_timestamp"] = strconv.FormatInt(time.Now().Unix(), 10)
		oauthParams["oauth_nonce"] = nonce()
	}
	if r.credentials != nil {
		oauthParams["oauth_token"] = r.credentials.Token
	}
	if r.verifier != "" {
		oauthParams["oauth_verifier"] = r.verifier
	}
	if r.sessionHandle != "" {
		oauthParams["oauth_session_handle"] = r.sessionHandle
	}
	if r.callbackURL != "" {
		oauthParams["oauth_callback"] = r.callbackURL
	}
	testHook(oauthParams)
	var signature string
	switch c.SignatureMethod {
	case HMACSHA1:
		key := encode(c.Credentials.Secret, false)
		key = append(key, '&')
		if r.credentials != nil {
			key = append(key, encode(r.credentials.Secret, false)...)
		}
		h := hmac.New(sha1.New, key)
		writeBaseString(h, r.method, r.u, r.form, oauthParams)
		signature = base64.StdEncoding.EncodeToString(h.Sum(key[:0]))
	case RSASHA1:
		if c.PrivateKey == nil {
			return nil, errors.New("oauth: private key not set")
		}
		h := sha1.New()
		writeBaseString(h, r.method, r.u, r.form, oauthParams)
		rawSignature, err := rsa.SignPKCS1v15(rand.Reader, c.PrivateKey, crypto.SHA1, h.Sum(nil))
		if err != nil {
			return nil, err
		}
		signature = base64.StdEncoding.EncodeToString(rawSignature)
	case PLAINTEXT:
		rawSignature := encode(c.Credentials.Secret, false)
		rawSignature = append(rawSignature, '&')
		if r.credentials != nil {
			rawSignature = append(rawSignature, encode(r.credentials.Secret, false)...)
		}
		signature = string(rawSignature)
	default:
		return nil, errors.New("oauth: unknown signature method")
	}
	oauthParams["oauth_signature"] = signature
	return oauthParams, nil
}
func (c *Client) SignForm(credentials *Credentials, method, urlStr string, form url.Values) error {
	u, err := url.Parse(urlStr)
	switch {
	case err != nil:
		return err
	case u.RawQuery != "":
		return errors.New("oauth: urlStr argument to SignForm must not include a query string")
	}
	p, err := c.oauthParams(&request{credentials: credentials, method: method, u: u, form: form})
	if err != nil {
		return err
	}
	for k, v := range p {
		form.Set(k, v)
	}
	return nil
}
func (c *Client) SignParam(credentials *Credentials, method, urlStr string, params url.Values) {
	u, _ := url.Parse(urlStr)
	u.RawQuery = ""
	p, _ := c.oauthParams(&request{credentials: credentials, method: method, u: u, form: params})
	for k, v := range p {
		params.Set(k, v)
	}
}
var oauthKeys = []string{
	"oauth_consumer_key",
	"oauth_nonce",
	"oauth_signature",
	"oauth_signature_method",
	"oauth_timestamp",
	"oauth_token",
	"oauth_version",
	"oauth_callback",
	"oauth_verifier",
	"oauth_session_handle",
}
func (c *Client) authorizationHeader(r *request) (string, error) {
	p, err := c.oauthParams(r)
	if err != nil {
		return "", err
	}
	var h []byte
	for _, k := range oauthKeys {
		if v, ok := p[k]; ok {
			if h == nil {
				h = []byte(`OAuth `)
			} else {
				h = append(h, ", "...)
			}
			h = append(h, k...)
			h = append(h, `="`...)
			h = append(h, encode(v, false)...)
			h = append(h, '"')
		}
	}
	return string(h), nil
}
func (c *Client) AuthorizationHeader(credentials *Credentials, method string, u *url.URL, params url.Values) string {
	v, _ := c.authorizationHeader(&request{credentials: credentials, method: method, u: u, form: params})
	return v
}
func (c *Client) SetAuthorizationHeader(header http.Header, credentials *Credentials, method string, u *url.URL, form url.Values) error {
	v, err := c.authorizationHeader(&request{credentials: credentials, method: method, u: u, form: form})
	if err != nil {
		return err
	}
	header.Set("Authorization", v)
	return nil
}
func (c *Client) do(ctx context.Context, urlStr string, r *request) (*http.Response, error) {
	var body io.Reader
	if r.method != http.MethodGet {
		body = strings.NewReader(r.form.Encode())
	}
	req, err := http.NewRequest(r.method, urlStr, body)
	if err != nil {
		return nil, err
	}
	if req.URL.RawQuery != "" {
		return nil, errors.New("oauth: url must not contain a query string")
	}
	for k, v := range c.Header {
		req.Header[k] = v
	}
	r.u = req.URL
	auth, err := c.authorizationHeader(r)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Authorization", auth)
	if r.method == http.MethodGet {
		req.URL.RawQuery = r.form.Encode()
	} else {
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}
	req = requestWithContext(ctx, req)
	client := contextClient(ctx)
	return client.Do(req)
}
func (c *Client) Get(client *http.Client, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) {
	ctx := context.WithValue(context.Background(), HTTPClient, client)
	return c.GetContext(ctx, credentials, urlStr, form)
}
func (c *Client) GetContext(ctx context.Context, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) {
	return c.do(ctx, urlStr, &request{method: http.MethodGet, credentials: credentials, form: form})
}
func (c *Client) Post(client *http.Client, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) {
	ctx := context.WithValue(context.Background(), HTTPClient, client)
	return c.PostContext(ctx, credentials, urlStr, form)
}
func (c *Client) PostContext(ctx context.Context, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) {
	return c.do(ctx, urlStr, &request{method: http.MethodPost, credentials: credentials, form: form})
}
func (c *Client) Delete(client *http.Client, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) {
	ctx := context.WithValue(context.Background(), HTTPClient, client)
	return c.DeleteContext(ctx, credentials, urlStr, form)
}
func (c *Client) DeleteContext(ctx context.Context, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) {
	return c.do(ctx, urlStr, &request{method: http.MethodDelete, credentials: credentials, form: form})
}
func (c *Client) Put(client *http.Client, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) {
	ctx := context.WithValue(context.Background(), HTTPClient, client)
	return c.PutContext(ctx, credentials, urlStr, form)
}