func newRequest(ctx context.Context, url string, reqBody io.Reader, contentType string) (*http.Request, error) {
	req, err := http.NewRequest("POST", url, reqBody)
	if err != nil {
		return nil, err
	}
	req = req.WithContext(ctx)
	if customHeader := getCustomHTTPReqHeaders(ctx); customHeader != nil {
		req.Header = customHeader
	}
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("Twirp-Version", "v5.2.0")
	return req, nil
}
newRequest makes an http.Request from a client, adding common headers.
package haberdasher
import bytes "bytes"
import strings "strings"
import context "context"
import fmt "fmt"
import ioutil "io/ioutil"
import log "log"
import http "net/http"
import jsonpb "github.com/golang/protobuf/jsonpb"
import proto "github.com/golang/protobuf/proto"
import twirp "github.com/twitchtv/twirp"
import ctxsetters "github.com/twitchtv/twirp/ctxsetters"
import io "io"
import strconv "strconv"
import json "encoding/json"
import url "net/url"
type Haberdasher interface {
	MakeHat(context.Context, *Size) (*Hat, error)
}
type haberdasherProtobufClient struct {
	client HTTPClient
	urls   [1]string
}
func NewHaberdasherProtobufClient(addr string, client HTTPClient) Haberdasher {
	prefix := urlBase(addr) + HaberdasherPathPrefix
	urls := [1]string{
		prefix + "MakeHat",
	}
	if httpClient, ok := client.(*http.Client); ok {
		return &haberdasherProtobufClient{
			client: withoutRedirects(httpClient),
			urls:   urls,
		}
	}
	return &haberdasherProtobufClient{
		client: client,
		urls:   urls,
	}
}
func (c *haberdasherProtobufClient) MakeHat(ctx context.Context, in *Size) (*Hat, error) {
	ctx = ctxsetters.WithPackageName(ctx, "twitch.twirp.example.haberdasher")
	ctx = ctxsetters.WithServiceName(ctx, "Haberdasher")
	ctx = ctxsetters.WithMethodName(ctx, "MakeHat")
	out := new(Hat)
	err := doProtobufRequest(ctx, c.client, c.urls[0], in, out)
	return out, err
}
type haberdasherJSONClient struct {
	client HTTPClient
	urls   [1]string
}
func NewHaberdasherJSONClient(addr string, client HTTPClient) Haberdasher {
	prefix := urlBase(addr) + HaberdasherPathPrefix
	urls := [1]string{
		prefix + "MakeHat",
	}
	if httpClient, ok := client.(*http.Client); ok {
		return &haberdasherJSONClient{
			client: withoutRedirects(httpClient),
			urls:   urls,
		}
	}
	return &haberdasherJSONClient{
		client: client,
		urls:   urls,
	}
}
func (c *haberdasherJSONClient) MakeHat(ctx context.Context, in *Size) (*Hat, error) {
	ctx = ctxsetters.WithPackageName(ctx, "twitch.twirp.example.haberdasher")
	ctx = ctxsetters.WithServiceName(ctx, "Haberdasher")
	ctx = ctxsetters.WithMethodName(ctx, "MakeHat")
	out := new(Hat)
	err := doJSONRequest(ctx, c.client, c.urls[0], in, out)
	return out, err
}
type haberdasherServer struct {
	Haberdasher
	hooks *twirp.ServerHooks
}
func NewHaberdasherServer(svc Haberdasher, hooks *twirp.ServerHooks) TwirpServer {
	return &haberdasherServer{
		Haberdasher: svc,
		hooks:       hooks,
	}
}
func (s *haberdasherServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
	writeError(ctx, resp, err, s.hooks)
}
const HaberdasherPathPrefix = "/twirp/twitch.twirp.example.haberdasher.Haberdasher/"
func (s *haberdasherServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	ctx := req.Context()
	ctx = ctxsetters.WithPackageName(ctx, "twitch.twirp.example.haberdasher")
	ctx = ctxsetters.WithServiceName(ctx, "Haberdasher")
	ctx = ctxsetters.WithResponseWriter(ctx, resp)
	var err error
	ctx, err = callRequestReceived(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if req.Method != "POST" {
		msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method)
		err = badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, err)
		return
	}
	switch req.URL.Path {
	case "/twirp/twitch.twirp.example.haberdasher.Haberdasher/MakeHat":
		s.serveMakeHat(ctx, resp, req)
		return
	default:
		msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
		err = badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, err)
		return
	}
}
func (s *haberdasherServer) serveMakeHat(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveMakeHatJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveMakeHatProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}
func (s *haberdasherServer) serveMakeHatJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "MakeHat")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	defer closebody(req.Body)
	reqContent := new(Size)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		err = wrapErr(err, "failed to parse request json")
		s.writeError(ctx, resp, twirp.InternalErrorWith(err))
		return
	}
	var respContent *Hat
	func() {
		defer func() {
			if r := recover(); r != nil {
				s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
				panic(r)
			}
		}()
		respContent, err = s.MakeHat(ctx, reqContent)
	}()
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *Hat and nil error while calling MakeHat. nil responses are not supported"))
		return
	}
	ctx = callResponsePrepared(ctx, s.hooks)
	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		err = wrapErr(err, "failed to marshal json response")
		s.writeError(ctx, resp, twirp.InternalErrorWith(err))
		return
	}
	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/json")
	resp.WriteHeader(http.StatusOK)
	if _, err = resp.Write(buf.Bytes()); err != nil {
		log.Printf("errored while writing response to client, but already sent response status code to 200: %s", err)
	}
	callResponseSent(ctx, s.hooks)
}
func (s *haberdasherServer) serveMakeHatProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "MakeHat")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	defer closebody(req.Body)
	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		err = wrapErr(err, "failed to read request body")
		s.writeError(ctx, resp, twirp.InternalErrorWith(err))
		return
	}
	reqContent := new(Size)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		err = wrapErr(err, "failed to parse request proto")
		s.writeError(ctx, resp, twirp.InternalErrorWith(err))
		return
	}
	var respContent *Hat
	func() {
		defer func() {
			if r := recover(); r != nil {
				s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
				panic(r)
			}
		}()
		respContent, err = s.MakeHat(ctx, reqContent)
	}()
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *Hat and nil error while calling MakeHat. nil responses are not supported"))
		return
	}
	ctx = callResponsePrepared(ctx, s.hooks)
	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		err = wrapErr(err, "failed to marshal proto response")
		s.writeError(ctx, resp, twirp.InternalErrorWith(err))
		return
	}
	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.WriteHeader(http.StatusOK)
	if _, err = resp.Write(respBytes); err != nil {
		log.Printf("errored while writing response to client, but already sent response status code to 200: %s", err)
	}
	callResponseSent(ctx, s.hooks)
}
func (s *haberdasherServer) ServiceDescriptor() ([]byte, int) {
	return twirpFileDescriptor0, 0
}
func (s *haberdasherServer) ProtocGenTwirpVersion() string {
	return "v5.2.0"
}
type HTTPClient interface {
	Do(req *http.Request) (*http.Response, error)
}
type TwirpServer interface {
	http.Handler
	ServiceDescriptor() ([]byte, int)
	ProtocGenTwirpVersion() string
}
func WriteError(resp http.ResponseWriter, err error) {
	writeError(context.Background(), resp, err, nil)
}
func writeError(ctx context.Context, resp http.ResponseWriter, err error, hooks *twirp.ServerHooks) {
	twerr, ok := err.(twirp.Error)
	if !ok {
		twerr = twirp.InternalErrorWith(err)
	}
	statusCode := twirp.ServerHTTPStatusFromErrorCode(twerr.Code())
	ctx = ctxsetters.WithStatusCode(ctx, statusCode)
	ctx = callError(ctx, hooks, twerr)
	resp.Header().Set("Content-Type", "application/json")  
	resp.WriteHeader(statusCode)                           
	respBody := marshalErrorToJSON(twerr)
	_, err2 := resp.Write(respBody)
	if err2 != nil {
		log.Printf("unable to send error message %q: %s", twerr, err2)
	}
	callResponseSent(ctx, hooks)
}
func urlBase(addr string) string {
	url, err := url.Parse(addr)
	if err != nil {
		return addr
	}
	if url.Scheme == "" {
		url.Scheme = "http"
	}
	return url.String()
}
func getCustomHTTPReqHeaders(ctx context.Context) http.Header {
	header, ok := twirp.HTTPRequestHeaders(ctx)
	if !ok || header == nil {
		return nil
	}
	copied := make(http.Header)
	for k, vv := range header {
		if vv == nil {
			copied[k] = nil
			continue
		}
		copied[k] = make([]string, len(vv))
		copy(copied[k], vv)
	}
	return copied
}
func closebody(body io.Closer) {
	if err := body.Close(); err != nil {
		log.Printf("error closing body: %q", err)
	}
}