func DefaultErrorRenderer(ctx context.Context, st *status.Status, w http.ResponseWriter) {
	if (st.Code() == codes.Canceled || st.Code() == codes.DeadlineExceeded) && ctx.Err() != nil {
		http.Error(w, "Client Closed Request", 499)
		return
	}
	code := httpStatusFromCode(st.Code())
	msg := http.StatusText(code)
	if msg == "" {
		msg = st.Code().String()
	}
	http.Error(w, msg, code)
}
DefaultErrorRenderer translates the gRPC code in the given status to an HTTP
error response. The following table shows how status codes are translated:
Canceled:         * 502 Bad Gateway
Unknown:            500 Internal Server Error
InvalidArgument:    400 Bad Request
DeadlineExceeded: * 504 Gateway Timeout
NotFound:           404 Not Found
AlreadyExists:      409 Conflict
PermissionDenied:   403 Forbidden
Unauthenticated:    401 Unauthorized
ResourceExhausted:  429 Too Many Requests
FailedPrecondition: 412 Precondition Failed
Aborted:            409 Conflict
OutOfRange:         422 Unprocessable Entity
Unimplemented:      501 Not Implemented
Internal:           500 Internal Server Error
Unavailable:        503 Service Unavailable
DataLoss:           500 Internal Server Error

* If the gRPC status indicates Canceled or DeadlineExceeded
and the given request context ALSO indicates a context error
(meaning that the request was cancelled by the client), then
a 499 Client Closed Request code is used instead.

If any other gRPC status code is observed, it would get translated into a
500 Internal Server Error.

Note that OK is absent from the mapping because the error renderer will never
be called for a non-error status.

This function uses http.Error to render the computed code (and corresponding
status text) to the given ResponseWriter.
package httpgrpc
import (
	"context"
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"path"
	"strconv"
	"sync"
	"time"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/encoding"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/peer"
	"google.golang.org/grpc/status"
	"github.com/fullstorydev/grpchan"
	"github.com/fullstorydev/grpchan/internal"
)
type Mux func(pattern string, handler func(http.ResponseWriter, *http.Request))
type HandlerOption func(*handlerOpts)
type handlerOpts struct {
	errFunc func(context.Context, *status.Status, http.ResponseWriter)
}
func ErrorRenderer(errFunc func(reqCtx context.Context, st *status.Status, response http.ResponseWriter)) HandlerOption {
	return func(h *handlerOpts) {
		h.errFunc = errFunc
	}
}