func newRequest(ctx context.Context, absUrl, contentType string, payload io.Reader) (*http.Request, error) {
	req, err := http.NewRequest("POST", absUrl, payload)
	if err != nil {
		return nil, err
	}
	req = req.WithContext(ctx)
	req.Header.Set("X-Gogo-Version", "v1.0.0")
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("Accept", contentType)
	return req, nil
}
newRequest makes an http.Request from a client, adding common headers.
package protocol
import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"sync"
	"github.com/dolab/gogo/pkgs/errors"
)
type Request struct {
	Protocoler
	HTTPClient
	mux sync.RWMutex
}
func (r *Request) WithHTTPClient(client HTTPClient) *Request {
	r.mux.Lock()
	r.HTTPClient = client
	r.mux.Unlock()
	return r
}
func (r *Request) Do(ctx context.Context, absUrl string, in, out interface{}) (err error) {
	if err := ctx.Err(); err != nil {
		return ErrContextTimeout.WithError(err)
	}
	payload, err := r.Marshal(in)
	if err != nil {
		return ErrMalformedRequestMessage.WithError(err)
	}
	req, err := newRequest(ctx, absUrl, r.ContentType(), bytes.NewBuffer(payload))
	if err != nil {
		return ErrInvalidPOSTRequest.WithError(err)
	}
	if err := ctx.Err(); err != nil {
		return ErrContextTimeout.WithError(err)
	}
	resp, err := r.HTTPClient.Do(req)
	if err != nil {
		return ErrDoPOSTRequest.WithError(err)
	}
	defer func() {
		tmperr := resp.Body.Close()
		if err == nil && tmperr != nil {
			err = ErrCloseResponse.WithError(tmperr)
		}
	}()
	if err = ctx.Err(); err != nil {
		return ErrContextTimeout.WithError(err)
	}
	if resp.StatusCode/100 != 2 {
		return newErrorFromResponse(resp)
	}
	err = r.Unmarshal(resp.Body, out)
	if err != nil {
		return ErrInvalidResponseMessage.WithError(err)
	}
	if err = ctx.Err(); err != nil {
		return ErrContextTimeout.WithError(err)
	}
	return nil
}
func hijackHTTPClientRedirects(client *http.Client) *http.Client {
	copy := *client
	copy.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		if client.CheckRedirect != nil {
			err := client.CheckRedirect(req, via)
			_ = err  
		}
		return http.ErrUseLastResponse
	}
	return &copy
}