route/proto/route.twirp.go

2489 lines
76 KiB
Go

// Code generated by protoc-gen-twirp v5.0.0, DO NOT EDIT.
// source: route.proto
/*
Package proto is a generated twirp stub package.
This code was generated with github.com/twitchtv/twirp/protoc-gen-twirp v5.0.0.
It is generated from these files:
route.proto
*/
package proto
import bytes "bytes"
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"
// Imports only used by utility functions:
import io "io"
import strconv "strconv"
import json "encoding/json"
import url "net/url"
// ================
// Routes Interface
// ================
// Routes lets users manage and manipulate http routes.
type Routes interface {
// Get fetches a single route based on the Host or ID.
Get(context.Context, *GetRouteRequest) (*Route, error)
// GetAll fetches all of the routes that the user owns.
GetAll(context.Context, *Nil) (*GetAllRoutesResponse, error)
// Put creates a new route based on user-supplied details.
Put(context.Context, *Route) (*Route, error)
// Delete removes a route.
Delete(context.Context, *Route) (*Nil, error)
}
// ======================
// Routes Protobuf Client
// ======================
type routesProtobufClient struct {
urlBase string
client *http.Client
}
// NewRoutesProtobufClient creates a Protobuf client that implements the Routes interface.
// It communicates using protobuf messages and can be configured with a custom http.Client.
func NewRoutesProtobufClient(addr string, client *http.Client) Routes {
return &routesProtobufClient{
urlBase: urlBase(addr),
client: withoutRedirects(client),
}
}
func (c *routesProtobufClient) Get(ctx context.Context, in *GetRouteRequest) (*Route, error) {
url := c.urlBase + RoutesPathPrefix + "Get"
out := new(Route)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *routesProtobufClient) GetAll(ctx context.Context, in *Nil) (*GetAllRoutesResponse, error) {
url := c.urlBase + RoutesPathPrefix + "GetAll"
out := new(GetAllRoutesResponse)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *routesProtobufClient) Put(ctx context.Context, in *Route) (*Route, error) {
url := c.urlBase + RoutesPathPrefix + "Put"
out := new(Route)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *routesProtobufClient) Delete(ctx context.Context, in *Route) (*Nil, error) {
url := c.urlBase + RoutesPathPrefix + "Delete"
out := new(Nil)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
// ==================
// Routes JSON Client
// ==================
type routesJSONClient struct {
urlBase string
client *http.Client
}
// NewRoutesJSONClient creates a JSON client that implements the Routes interface.
// It communicates using JSON requests and responses instead of protobuf messages.
func NewRoutesJSONClient(addr string, client *http.Client) Routes {
return &routesJSONClient{
urlBase: urlBase(addr),
client: withoutRedirects(client),
}
}
func (c *routesJSONClient) Get(ctx context.Context, in *GetRouteRequest) (*Route, error) {
url := c.urlBase + RoutesPathPrefix + "Get"
out := new(Route)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *routesJSONClient) GetAll(ctx context.Context, in *Nil) (*GetAllRoutesResponse, error) {
url := c.urlBase + RoutesPathPrefix + "GetAll"
out := new(GetAllRoutesResponse)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *routesJSONClient) Put(ctx context.Context, in *Route) (*Route, error) {
url := c.urlBase + RoutesPathPrefix + "Put"
out := new(Route)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *routesJSONClient) Delete(ctx context.Context, in *Route) (*Nil, error) {
url := c.urlBase + RoutesPathPrefix + "Delete"
out := new(Nil)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
// =====================
// Routes Server Handler
// =====================
type routesServer struct {
Routes
hooks *twirp.ServerHooks
}
func NewRoutesServer(svc Routes, hooks *twirp.ServerHooks) TwirpServer {
return &routesServer{
Routes: svc,
hooks: hooks,
}
}
// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
func (s *routesServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
writeError(ctx, resp, err, s.hooks)
}
// RoutesPathPrefix is used for all URL paths on a twirp Routes server.
// Requests are always: POST RoutesPathPrefix/method
// It can be used in an HTTP mux to route twirp requests along with non-twirp requests on other routes.
const RoutesPathPrefix = "/twirp/xeserv.us.route.Routes/"
func (s *routesServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
ctx := req.Context()
ctx = ctxsetters.WithPackageName(ctx, "xeserv.us.route")
ctx = ctxsetters.WithServiceName(ctx, "Routes")
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/xeserv.us.route.Routes/Get":
s.serveGet(ctx, resp, req)
return
case "/twirp/xeserv.us.route.Routes/GetAll":
s.serveGetAll(ctx, resp, req)
return
case "/twirp/xeserv.us.route.Routes/Put":
s.servePut(ctx, resp, req)
return
case "/twirp/xeserv.us.route.Routes/Delete":
s.serveDelete(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 *routesServer) serveGet(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveGetJSON(ctx, resp, req)
case "application/protobuf":
s.serveGetProtobuf(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 *routesServer) serveGetJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Get")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(GetRouteRequest)
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
}
// Call service method
var respContent *Route
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Get(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Route and nil error while calling Get. 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 *routesServer) serveGetProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Get")
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(GetRouteRequest)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *Route
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Get(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Route and nil error while calling Get. 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 *routesServer) serveGetAll(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveGetAllJSON(ctx, resp, req)
case "application/protobuf":
s.serveGetAllProtobuf(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 *routesServer) serveGetAllJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "GetAll")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(Nil)
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
}
// Call service method
var respContent *GetAllRoutesResponse
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.GetAll(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *GetAllRoutesResponse and nil error while calling GetAll. 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 *routesServer) serveGetAllProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "GetAll")
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(Nil)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *GetAllRoutesResponse
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.GetAll(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *GetAllRoutesResponse and nil error while calling GetAll. 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 *routesServer) servePut(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.servePutJSON(ctx, resp, req)
case "application/protobuf":
s.servePutProtobuf(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 *routesServer) servePutJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Put")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(Route)
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
}
// Call service method
var respContent *Route
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Put(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Route and nil error while calling Put. 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 *routesServer) servePutProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Put")
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(Route)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *Route
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Put(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Route and nil error while calling Put. 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 *routesServer) serveDelete(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveDeleteJSON(ctx, resp, req)
case "application/protobuf":
s.serveDeleteProtobuf(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 *routesServer) serveDeleteJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Delete")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(Route)
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
}
// Call service method
var respContent *Nil
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Delete(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Nil and nil error while calling Delete. 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 *routesServer) serveDeleteProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Delete")
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(Route)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *Nil
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Delete(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Nil and nil error while calling Delete. 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 *routesServer) ServiceDescriptor() ([]byte, int) {
return twirpFileDescriptor0, 0
}
func (s *routesServer) ProtocGenTwirpVersion() string {
return "v5.0.0"
}
// ================
// Tokens Interface
// ================
// Tokens lets a user manage the database authentication tokens.
type Tokens interface {
Get(context.Context, *GetTokenRequest) (*Token, error)
GetAll(context.Context, *Nil) (*TokenSet, error)
Put(context.Context, *Token) (*Token, error)
Delete(context.Context, *Token) (*Nil, error)
Deactivate(context.Context, *Token) (*Nil, error)
}
// ======================
// Tokens Protobuf Client
// ======================
type tokensProtobufClient struct {
urlBase string
client *http.Client
}
// NewTokensProtobufClient creates a Protobuf client that implements the Tokens interface.
// It communicates using protobuf messages and can be configured with a custom http.Client.
func NewTokensProtobufClient(addr string, client *http.Client) Tokens {
return &tokensProtobufClient{
urlBase: urlBase(addr),
client: withoutRedirects(client),
}
}
func (c *tokensProtobufClient) Get(ctx context.Context, in *GetTokenRequest) (*Token, error) {
url := c.urlBase + TokensPathPrefix + "Get"
out := new(Token)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *tokensProtobufClient) GetAll(ctx context.Context, in *Nil) (*TokenSet, error) {
url := c.urlBase + TokensPathPrefix + "GetAll"
out := new(TokenSet)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *tokensProtobufClient) Put(ctx context.Context, in *Token) (*Token, error) {
url := c.urlBase + TokensPathPrefix + "Put"
out := new(Token)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *tokensProtobufClient) Delete(ctx context.Context, in *Token) (*Nil, error) {
url := c.urlBase + TokensPathPrefix + "Delete"
out := new(Nil)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *tokensProtobufClient) Deactivate(ctx context.Context, in *Token) (*Nil, error) {
url := c.urlBase + TokensPathPrefix + "Deactivate"
out := new(Nil)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
// ==================
// Tokens JSON Client
// ==================
type tokensJSONClient struct {
urlBase string
client *http.Client
}
// NewTokensJSONClient creates a JSON client that implements the Tokens interface.
// It communicates using JSON requests and responses instead of protobuf messages.
func NewTokensJSONClient(addr string, client *http.Client) Tokens {
return &tokensJSONClient{
urlBase: urlBase(addr),
client: withoutRedirects(client),
}
}
func (c *tokensJSONClient) Get(ctx context.Context, in *GetTokenRequest) (*Token, error) {
url := c.urlBase + TokensPathPrefix + "Get"
out := new(Token)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *tokensJSONClient) GetAll(ctx context.Context, in *Nil) (*TokenSet, error) {
url := c.urlBase + TokensPathPrefix + "GetAll"
out := new(TokenSet)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *tokensJSONClient) Put(ctx context.Context, in *Token) (*Token, error) {
url := c.urlBase + TokensPathPrefix + "Put"
out := new(Token)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *tokensJSONClient) Delete(ctx context.Context, in *Token) (*Nil, error) {
url := c.urlBase + TokensPathPrefix + "Delete"
out := new(Nil)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *tokensJSONClient) Deactivate(ctx context.Context, in *Token) (*Nil, error) {
url := c.urlBase + TokensPathPrefix + "Deactivate"
out := new(Nil)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
// =====================
// Tokens Server Handler
// =====================
type tokensServer struct {
Tokens
hooks *twirp.ServerHooks
}
func NewTokensServer(svc Tokens, hooks *twirp.ServerHooks) TwirpServer {
return &tokensServer{
Tokens: svc,
hooks: hooks,
}
}
// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
func (s *tokensServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
writeError(ctx, resp, err, s.hooks)
}
// TokensPathPrefix is used for all URL paths on a twirp Tokens server.
// Requests are always: POST TokensPathPrefix/method
// It can be used in an HTTP mux to route twirp requests along with non-twirp requests on other routes.
const TokensPathPrefix = "/twirp/xeserv.us.route.Tokens/"
func (s *tokensServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
ctx := req.Context()
ctx = ctxsetters.WithPackageName(ctx, "xeserv.us.route")
ctx = ctxsetters.WithServiceName(ctx, "Tokens")
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/xeserv.us.route.Tokens/Get":
s.serveGet(ctx, resp, req)
return
case "/twirp/xeserv.us.route.Tokens/GetAll":
s.serveGetAll(ctx, resp, req)
return
case "/twirp/xeserv.us.route.Tokens/Put":
s.servePut(ctx, resp, req)
return
case "/twirp/xeserv.us.route.Tokens/Delete":
s.serveDelete(ctx, resp, req)
return
case "/twirp/xeserv.us.route.Tokens/Deactivate":
s.serveDeactivate(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 *tokensServer) serveGet(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveGetJSON(ctx, resp, req)
case "application/protobuf":
s.serveGetProtobuf(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 *tokensServer) serveGetJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Get")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(GetTokenRequest)
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
}
// Call service method
var respContent *Token
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Get(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Token and nil error while calling Get. 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 *tokensServer) serveGetProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Get")
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(GetTokenRequest)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *Token
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Get(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Token and nil error while calling Get. 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 *tokensServer) serveGetAll(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveGetAllJSON(ctx, resp, req)
case "application/protobuf":
s.serveGetAllProtobuf(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 *tokensServer) serveGetAllJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "GetAll")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(Nil)
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
}
// Call service method
var respContent *TokenSet
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.GetAll(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *TokenSet and nil error while calling GetAll. 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 *tokensServer) serveGetAllProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "GetAll")
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(Nil)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *TokenSet
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.GetAll(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *TokenSet and nil error while calling GetAll. 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 *tokensServer) servePut(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.servePutJSON(ctx, resp, req)
case "application/protobuf":
s.servePutProtobuf(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 *tokensServer) servePutJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Put")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(Token)
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
}
// Call service method
var respContent *Token
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Put(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Token and nil error while calling Put. 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 *tokensServer) servePutProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Put")
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(Token)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *Token
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Put(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Token and nil error while calling Put. 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 *tokensServer) serveDelete(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveDeleteJSON(ctx, resp, req)
case "application/protobuf":
s.serveDeleteProtobuf(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 *tokensServer) serveDeleteJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Delete")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(Token)
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
}
// Call service method
var respContent *Nil
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Delete(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Nil and nil error while calling Delete. 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 *tokensServer) serveDeleteProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Delete")
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(Token)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *Nil
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Delete(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Nil and nil error while calling Delete. 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 *tokensServer) serveDeactivate(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveDeactivateJSON(ctx, resp, req)
case "application/protobuf":
s.serveDeactivateProtobuf(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 *tokensServer) serveDeactivateJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Deactivate")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(Token)
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
}
// Call service method
var respContent *Nil
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Deactivate(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Nil and nil error while calling Deactivate. 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 *tokensServer) serveDeactivateProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Deactivate")
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(Token)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *Nil
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Deactivate(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Nil and nil error while calling Deactivate. 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 *tokensServer) ServiceDescriptor() ([]byte, int) {
return twirpFileDescriptor0, 1
}
func (s *tokensServer) ProtocGenTwirpVersion() string {
return "v5.0.0"
}
// ==================
// Backends Interface
// ==================
type Backends interface {
List(context.Context, *BackendSelector) (*BackendList, error)
Kill(context.Context, *BackendID) (*Nil, error)
}
// ========================
// Backends Protobuf Client
// ========================
type backendsProtobufClient struct {
urlBase string
client *http.Client
}
// NewBackendsProtobufClient creates a Protobuf client that implements the Backends interface.
// It communicates using protobuf messages and can be configured with a custom http.Client.
func NewBackendsProtobufClient(addr string, client *http.Client) Backends {
return &backendsProtobufClient{
urlBase: urlBase(addr),
client: withoutRedirects(client),
}
}
func (c *backendsProtobufClient) List(ctx context.Context, in *BackendSelector) (*BackendList, error) {
url := c.urlBase + BackendsPathPrefix + "List"
out := new(BackendList)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *backendsProtobufClient) Kill(ctx context.Context, in *BackendID) (*Nil, error) {
url := c.urlBase + BackendsPathPrefix + "Kill"
out := new(Nil)
err := doProtoRequest(ctx, c.client, url, in, out)
return out, err
}
// ====================
// Backends JSON Client
// ====================
type backendsJSONClient struct {
urlBase string
client *http.Client
}
// NewBackendsJSONClient creates a JSON client that implements the Backends interface.
// It communicates using JSON requests and responses instead of protobuf messages.
func NewBackendsJSONClient(addr string, client *http.Client) Backends {
return &backendsJSONClient{
urlBase: urlBase(addr),
client: withoutRedirects(client),
}
}
func (c *backendsJSONClient) List(ctx context.Context, in *BackendSelector) (*BackendList, error) {
url := c.urlBase + BackendsPathPrefix + "List"
out := new(BackendList)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
func (c *backendsJSONClient) Kill(ctx context.Context, in *BackendID) (*Nil, error) {
url := c.urlBase + BackendsPathPrefix + "Kill"
out := new(Nil)
err := doJSONRequest(ctx, c.client, url, in, out)
return out, err
}
// =======================
// Backends Server Handler
// =======================
type backendsServer struct {
Backends
hooks *twirp.ServerHooks
}
func NewBackendsServer(svc Backends, hooks *twirp.ServerHooks) TwirpServer {
return &backendsServer{
Backends: svc,
hooks: hooks,
}
}
// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
func (s *backendsServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
writeError(ctx, resp, err, s.hooks)
}
// BackendsPathPrefix is used for all URL paths on a twirp Backends server.
// Requests are always: POST BackendsPathPrefix/method
// It can be used in an HTTP mux to route twirp requests along with non-twirp requests on other routes.
const BackendsPathPrefix = "/twirp/xeserv.us.route.Backends/"
func (s *backendsServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
ctx := req.Context()
ctx = ctxsetters.WithPackageName(ctx, "xeserv.us.route")
ctx = ctxsetters.WithServiceName(ctx, "Backends")
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/xeserv.us.route.Backends/List":
s.serveList(ctx, resp, req)
return
case "/twirp/xeserv.us.route.Backends/Kill":
s.serveKill(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 *backendsServer) serveList(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveListJSON(ctx, resp, req)
case "application/protobuf":
s.serveListProtobuf(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 *backendsServer) serveListJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "List")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(BackendSelector)
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
}
// Call service method
var respContent *BackendList
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.List(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *BackendList and nil error while calling List. 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 *backendsServer) serveListProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "List")
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(BackendSelector)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *BackendList
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.List(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *BackendList and nil error while calling List. 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 *backendsServer) serveKill(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
switch req.Header.Get("Content-Type") {
case "application/json":
s.serveKillJSON(ctx, resp, req)
case "application/protobuf":
s.serveKillProtobuf(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 *backendsServer) serveKillJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Kill")
ctx, err = callRequestRouted(ctx, s.hooks)
if err != nil {
s.writeError(ctx, resp, err)
return
}
defer closebody(req.Body)
reqContent := new(BackendID)
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
}
// Call service method
var respContent *Nil
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Kill(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Nil and nil error while calling Kill. 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 *backendsServer) serveKillProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
var err error
ctx = ctxsetters.WithMethodName(ctx, "Kill")
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(BackendID)
if err = proto.Unmarshal(buf, reqContent); err != nil {
err = wrapErr(err, "failed to parse request proto")
s.writeError(ctx, resp, twirp.InternalErrorWith(err))
return
}
// Call service method
var respContent *Nil
func() {
defer func() {
// In case of a panic, serve a 500 error and then panic.
if r := recover(); r != nil {
s.writeError(ctx, resp, twirp.InternalError("Internal service panic"))
panic(r)
}
}()
respContent, err = s.Kill(ctx, reqContent)
}()
if err != nil {
s.writeError(ctx, resp, err)
return
}
if respContent == nil {
s.writeError(ctx, resp, twirp.InternalError("received a nil *Nil and nil error while calling Kill. 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 *backendsServer) ServiceDescriptor() ([]byte, int) {
return twirpFileDescriptor0, 2
}
func (s *backendsServer) ProtocGenTwirpVersion() string {
return "v5.0.0"
}
// =====
// Utils
// =====
// TwirpServer is the interface generated server structs will support: they're
// HTTP handlers with additional methods for accessing metadata about the
// service. Those accessors are a low-level API for building reflection tools.
// Most people can think of TwirpServers as just http.Handlers.
type TwirpServer interface {
http.Handler
// ServiceDescriptor returns gzipped bytes describing the .proto file that
// this service was generated from. Once unzipped, the bytes can be
// unmarshaled as a
// github.com/golang/protobuf/protoc-gen-go/descriptor.FileDescriptorProto.
//
// The returned integer is the index of this particular service within that
// FileDescriptorProto's 'Service' slice of ServiceDescriptorProtos. This is a
// low-level field, expected to be used for reflection.
ServiceDescriptor() ([]byte, int)
// ProtocGenTwirpVersion is the semantic version string of the version of
// twirp used to generate this file.
ProtocGenTwirpVersion() string
}
// done returns ctx.Err() if ctx.Done() indicates that the context done
func done(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
default:
return nil
}
}
// WriteError writes an HTTP response with a valid Twirp error format.
// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
func WriteError(resp http.ResponseWriter, err error) {
writeError(context.Background(), resp, err, nil)
}
// writeError writes Twirp errors in the response and triggers hooks.
func writeError(ctx context.Context, resp http.ResponseWriter, err error, hooks *twirp.ServerHooks) {
// Non-twirp errors are wrapped as Internal (default)
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") // Error responses are always JSON (instead of protobuf)
resp.WriteHeader(statusCode) // HTTP response status code
respBody := marshalErrorToJSON(twerr)
_, err2 := resp.Write(respBody)
if err2 != nil {
log.Printf("unable to send error message %q: %s", twerr, err2)
}
callResponseSent(ctx, hooks)
}
// urlBase helps ensure that addr specifies a scheme. If it is unparsable
// as a URL, it returns addr unchanged.
func urlBase(addr string) string {
// If the addr specifies a scheme, use it. If not, default to
// http. If url.Parse fails on it, return it unchanged.
url, err := url.Parse(addr)
if err != nil {
return addr
}
if url.Scheme == "" {
url.Scheme = "http"
}
return url.String()
}
// getCustomHTTPReqHeaders retrieves a copy of any headers that are set in
// a context through the twirp.WithHTTPRequestHeaders function.
// If there are no headers set, or if they have the wrong type, nil is returned.
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
}
// closebody closes a response or request body and just logs
// any error encountered while closing, since errors are
// considered very unusual.
func closebody(body io.Closer) {
if err := body.Close(); err != nil {
log.Printf("error closing body: %q", err)
}
}
// newRequest makes an http.Request from a client, adding common headers.
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.0.0")
return req, nil
}
// JSON serialization for errors
type twerrJSON struct {
Code string `json:"code"`
Msg string `json:"msg"`
Meta map[string]string `json:"meta,omitempty"`
}
// marshalErrorToJSON returns JSON from a twirp.Error, that can be used as HTTP error response body.
// If serialization fails, it will use a descriptive Internal error instead.
func marshalErrorToJSON(twerr twirp.Error) []byte {
// make sure that msg is not too large
msg := twerr.Msg()
if len(msg) > 1e6 {
msg = msg[:1e6]
}
tj := twerrJSON{
Code: string(twerr.Code()),
Msg: msg,
Meta: twerr.MetaMap(),
}
buf, err := json.Marshal(&tj)
if err != nil {
buf = []byte("{\"type\": \"" + twirp.Internal + "\", \"msg\": \"There was an error but it could not be serialized into JSON\"}") // fallback
}
return buf
}
// errorFromResponse builds a twirp.Error from a non-200 HTTP response.
// If the response has a valid serialized Twirp error, then it's returned.
// If not, the response status code is used to generate a similar twirp
// error. See twirpErrorFromIntermediary for more info on intermediary errors.
func errorFromResponse(resp *http.Response) twirp.Error {
statusCode := resp.StatusCode
statusText := http.StatusText(statusCode)
if isHTTPRedirect(statusCode) {
// Unexpected redirect: it must be an error from an intermediary.
// Twirp clients dont't follow redirects automatically, Twirp only handles
// POST requests, redirects should only happen on GET and HEAD requests.
location := resp.Header.Get("Location")
msg := fmt.Sprintf("unexpected HTTP status code %d %q received, Location=%q", statusCode, statusText, location)
return twirpErrorFromIntermediary(statusCode, msg, location)
}
respBodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return clientError("failed to read server error response body", err)
}
var tj twerrJSON
if err := json.Unmarshal(respBodyBytes, &tj); err != nil {
// Invalid JSON response; it must be an error from an intermediary.
msg := fmt.Sprintf("Error from intermediary with HTTP status code %d %q", statusCode, statusText)
return twirpErrorFromIntermediary(statusCode, msg, string(respBodyBytes))
}
errorCode := twirp.ErrorCode(tj.Code)
if !twirp.IsValidErrorCode(errorCode) {
msg := "invalid type returned from server error response: " + tj.Code
return twirp.InternalError(msg)
}
twerr := twirp.NewError(errorCode, tj.Msg)
for k, v := range tj.Meta {
twerr = twerr.WithMeta(k, v)
}
return twerr
}
// twirpErrorFromIntermediary maps HTTP errors from non-twirp sources to twirp errors.
// The mapping is similar to gRPC: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
// Returned twirp Errors have some additional metadata for inspection.
func twirpErrorFromIntermediary(status int, msg string, bodyOrLocation string) twirp.Error {
var code twirp.ErrorCode
if isHTTPRedirect(status) { // 3xx
code = twirp.Internal
} else {
switch status {
case 400: // Bad Request
code = twirp.Internal
case 401: // Unauthorized
code = twirp.Unauthenticated
case 403: // Forbidden
code = twirp.PermissionDenied
case 404: // Not Found
code = twirp.BadRoute
case 429, 502, 503, 504: // Too Many Requests, Bad Gateway, Service Unavailable, Gateway Timeout
code = twirp.Unavailable
default: // All other codes
code = twirp.Unknown
}
}
twerr := twirp.NewError(code, msg)
twerr = twerr.WithMeta("http_error_from_intermediary", "true") // to easily know if this error was from intermediary
twerr = twerr.WithMeta("status_code", strconv.Itoa(status))
if isHTTPRedirect(status) {
twerr = twerr.WithMeta("location", bodyOrLocation)
} else {
twerr = twerr.WithMeta("body", bodyOrLocation)
}
return twerr
}
func isHTTPRedirect(status int) bool {
return status >= 300 && status <= 399
}
// wrappedError implements the github.com/pkg/errors.Causer interface, allowing errors to be
// examined for their root cause.
type wrappedError struct {
msg string
cause error
}
func wrapErr(err error, msg string) error { return &wrappedError{msg: msg, cause: err} }
func (e *wrappedError) Cause() error { return e.cause }
func (e *wrappedError) Error() string { return e.msg + ": " + e.cause.Error() }
// clientError adds consistency to errors generated in the client
func clientError(desc string, err error) twirp.Error {
return twirp.InternalErrorWith(wrapErr(err, desc))
}
// badRouteError is used when the twirp server cannot route a request
func badRouteError(msg string, method, url string) twirp.Error {
err := twirp.NewError(twirp.BadRoute, msg)
err = err.WithMeta("twirp_invalid_route", method+" "+url)
return err
}
// The standard library will, by default, redirect requests (including POSTs) if it gets a 302 or
// 303 response, and also 301s in go1.8. It redirects by making a second request, changing the
// method to GET and removing the body. This produces very confusing error messages, so instead we
// set a redirect policy that always errors. This stops Go from executing the redirect.
//
// We have to be a little careful in case the user-provided http.Client has its own CheckRedirect
// policy - if so, we'll run through that policy first.
//
// Because this requires modifying the http.Client, we make a new copy of the client and return it.
func withoutRedirects(in *http.Client) *http.Client {
copy := *in
copy.CheckRedirect = func(req *http.Request, via []*http.Request) error {
if in.CheckRedirect != nil {
// Run the input's redirect if it exists, in case it has side effects, but ignore any error it
// returns, since we want to use ErrUseLastResponse.
err := in.CheckRedirect(req, via)
_ = err // Silly, but this makes sure generated code passes errcheck -blank, which some people use.
}
return http.ErrUseLastResponse
}
return &copy
}
// doProtoRequest is common code to make a request to the remote twirp service.
func doProtoRequest(ctx context.Context, client *http.Client, url string, in, out proto.Message) error {
var err error
reqBodyBytes, err := proto.Marshal(in)
if err != nil {
return clientError("failed to marshal proto request", err)
}
reqBody := bytes.NewBuffer(reqBodyBytes)
if err = done(ctx); err != nil {
return clientError("aborted because context was done", err)
}
req, err := newRequest(ctx, url, reqBody, "application/protobuf")
if err != nil {
return clientError("could not build request", err)
}
resp, err := client.Do(req)
if err != nil {
return clientError("failed to do request", err)
}
defer closebody(resp.Body)
if err = done(ctx); err != nil {
return clientError("aborted because context was done", err)
}
if resp.StatusCode != 200 {
return errorFromResponse(resp)
}
respBodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return clientError("failed to read response body", err)
}
if err = done(ctx); err != nil {
return clientError("aborted because context was done", err)
}
if err = proto.Unmarshal(respBodyBytes, out); err != nil {
return clientError("failed to unmarshal proto response", err)
}
return nil
}
// doJSONRequest is common code to make a request to the remote twirp service.
func doJSONRequest(ctx context.Context, client *http.Client, url string, in, out proto.Message) error {
var err error
reqBody := bytes.NewBuffer(nil)
marshaler := &jsonpb.Marshaler{OrigName: true}
if err = marshaler.Marshal(reqBody, in); err != nil {
return clientError("failed to marshal json request", err)
}
if err = done(ctx); err != nil {
return clientError("aborted because context was done", err)
}
req, err := newRequest(ctx, url, reqBody, "application/json")
if err != nil {
return clientError("could not build request", err)
}
resp, err := client.Do(req)
if err != nil {
return clientError("failed to do request", err)
}
defer closebody(resp.Body)
if err = done(ctx); err != nil {
return clientError("aborted because context was done", err)
}
if resp.StatusCode != 200 {
return errorFromResponse(resp)
}
unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
if err = unmarshaler.Unmarshal(resp.Body, out); err != nil {
return clientError("failed to unmarshal json response", err)
}
if err = done(ctx); err != nil {
return clientError("aborted because context was done", err)
}
return nil
}
// Call twirp.ServerHooks.RequestReceived if the hook is available
func callRequestReceived(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) {
if h == nil || h.RequestReceived == nil {
return ctx, nil
}
return h.RequestReceived(ctx)
}
// Call twirp.ServerHooks.RequestRouted if the hook is available
func callRequestRouted(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) {
if h == nil || h.RequestRouted == nil {
return ctx, nil
}
return h.RequestRouted(ctx)
}
// Call twirp.ServerHooks.ResponsePrepared if the hook is available
func callResponsePrepared(ctx context.Context, h *twirp.ServerHooks) context.Context {
if h == nil || h.ResponsePrepared == nil {
return ctx
}
return h.ResponsePrepared(ctx)
}
// Call twirp.ServerHooks.ResponseSent if the hook is available
func callResponseSent(ctx context.Context, h *twirp.ServerHooks) {
if h == nil || h.ResponseSent == nil {
return
}
h.ResponseSent(ctx)
}
// Call twirp.ServerHooks.Error if the hook is available
func callError(ctx context.Context, h *twirp.ServerHooks, err twirp.Error) context.Context {
if h == nil || h.Error == nil {
return ctx
}
return h.Error(ctx, err)
}
var twirpFileDescriptor0 = []byte{
// 579 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0x8d, 0xed, 0xd8, 0x49, 0x27, 0x12, 0x41, 0xa3, 0xa8, 0x32, 0x81, 0x83, 0xb5, 0x12, 0x52,
0x4e, 0x16, 0x0a, 0x48, 0x85, 0x02, 0x87, 0x56, 0x81, 0x50, 0x81, 0x2a, 0xe4, 0x70, 0x82, 0x93,
0x1d, 0x8f, 0x54, 0xab, 0x26, 0x0e, 0xde, 0x75, 0x05, 0x5f, 0xc0, 0x95, 0x2b, 0x9f, 0xc2, 0xdf,
0x21, 0xcf, 0x6e, 0xda, 0x12, 0xc7, 0xa9, 0x38, 0x65, 0x66, 0xf6, 0xcd, 0xfa, 0xbd, 0xb7, 0x33,
0x81, 0x41, 0x59, 0x54, 0x8a, 0xc2, 0x75, 0x59, 0xa8, 0x02, 0x87, 0xdf, 0x49, 0x52, 0x79, 0x15,
0x56, 0x32, 0xe4, 0xb2, 0x70, 0xc1, 0x39, 0xcf, 0x72, 0xf1, 0x02, 0x86, 0x73, 0x52, 0x51, 0x5d,
0x8a, 0xe8, 0x5b, 0x45, 0x52, 0xe1, 0x21, 0x78, 0xd5, 0xaa, 0x92, 0x94, 0xfa, 0x56, 0x60, 0x4d,
0x0e, 0x22, 0x93, 0xe1, 0x3d, 0xb0, 0xb3, 0xd4, 0xb7, 0xb9, 0x66, 0x67, 0xa9, 0x78, 0x03, 0x2e,
0xf7, 0x99, 0x03, 0x6b, 0x73, 0x80, 0x3e, 0xf4, 0x96, 0x25, 0xc5, 0xaa, 0x28, 0x0d, 0x7a, 0x93,
0x22, 0x42, 0xf7, 0xa2, 0x90, 0xca, 0x77, 0xb8, 0xcc, 0xb1, 0x78, 0x0b, 0xa3, 0x39, 0xa9, 0x93,
0x3c, 0xe7, 0xcb, 0x64, 0x44, 0x72, 0x5d, 0xac, 0x24, 0x61, 0x08, 0x1e, 0x33, 0x95, 0xbe, 0x15,
0x38, 0x93, 0xc1, 0xf4, 0x30, 0xdc, 0x92, 0x10, 0x6a, 0xd6, 0x06, 0x25, 0xbe, 0x80, 0xfb, 0xa9,
0xb8, 0xa4, 0x55, 0x83, 0x0e, 0x42, 0x37, 0x29, 0xd2, 0x1f, 0x86, 0x0b, 0xc7, 0xb5, 0x46, 0xb9,
0x2c, 0xd6, 0x24, 0x7d, 0x27, 0x70, 0x6a, 0x8d, 0x3a, 0xab, 0xeb, 0xf1, 0x52, 0x65, 0x57, 0xe4,
0x77, 0x03, 0x6b, 0xd2, 0x8f, 0x4c, 0x26, 0x8e, 0xa1, 0xcf, 0x97, 0x2f, 0x48, 0xd5, 0xc4, 0x54,
0x1d, 0xb7, 0x13, 0x63, 0x68, 0x64, 0x50, 0xe2, 0x88, 0x2d, 0xd6, 0x35, 0x63, 0xf1, 0x08, 0x5c,
0x3e, 0x34, 0x2c, 0x75, 0xd2, 0x30, 0xf8, 0xb7, 0x05, 0xbd, 0xd3, 0x78, 0x79, 0x49, 0xab, 0xb4,
0x21, 0x6a, 0x04, 0x2e, 0x3f, 0xac, 0x81, 0xeb, 0xa4, 0x96, 0x5a, 0x49, 0x2a, 0x37, 0xfe, 0xd6,
0x71, 0x2d, 0x29, 0x2d, 0xbe, 0xc6, 0xd9, 0x8a, 0x25, 0x1d, 0x44, 0x26, 0xc3, 0xfb, 0xe0, 0xac,
0x2f, 0x32, 0xdf, 0x0d, 0xac, 0x89, 0x1d, 0xd5, 0xe1, 0xf5, 0xeb, 0x78, 0x37, 0xaf, 0xc3, 0xc3,
0x20, 0xe3, 0x24, 0x27, 0xbf, 0xa7, 0x0d, 0xd1, 0x99, 0xa8, 0x60, 0x60, 0xa8, 0x7d, 0xc8, 0xa4,
0xc2, 0x27, 0x60, 0x27, 0x92, 0xe9, 0x0d, 0xa6, 0x41, 0xc3, 0x0f, 0x83, 0x5c, 0x50, 0x4e, 0x4b,
0x55, 0x94, 0x91, 0x9d, 0x48, 0x7c, 0x06, 0xfd, 0x44, 0x97, 0xa5, 0x6f, 0xb3, 0x8f, 0x7e, 0x5b,
0x5f, 0x74, 0x8d, 0x14, 0xaf, 0x61, 0xb8, 0x75, 0xd9, 0x2d, 0x7d, 0xd6, 0x3f, 0xfa, 0x36, 0x5e,
0xd8, 0x37, 0x5e, 0x88, 0x87, 0x70, 0x60, 0xda, 0xcf, 0x66, 0xdb, 0x96, 0x4e, 0x7f, 0xda, 0xe0,
0xe9, 0x19, 0xc4, 0x13, 0x70, 0xe6, 0xa4, 0xb0, 0xa9, 0x64, 0x6b, 0x57, 0xc6, 0x2d, 0x43, 0x29,
0x3a, 0x38, 0x07, 0x4f, 0x8f, 0x35, 0x8e, 0x1a, 0x98, 0xf3, 0x2c, 0x1f, 0x3f, 0xde, 0x75, 0x77,
0x63, 0x0b, 0x44, 0x07, 0x8f, 0xc0, 0xf9, 0x58, 0x29, 0x6c, 0xf9, 0xd2, 0x1e, 0x06, 0xcf, 0xc1,
0x9b, 0x51, 0x4e, 0x8a, 0x5a, 0x7b, 0x77, 0x32, 0x13, 0x9d, 0xe9, 0x1f, 0x1b, 0x3c, 0x9e, 0xd7,
0xfd, 0x4e, 0xdc, 0x1e, 0xe9, 0x71, 0xcb, 0x16, 0x88, 0x0e, 0xbe, 0xbc, 0xc3, 0x89, 0x07, 0xbb,
0x3b, 0x17, 0xa4, 0xf6, 0xa9, 0x67, 0xcc, 0x9e, 0xaf, 0xee, 0x53, 0xaf, 0x7b, 0x5b, 0xd4, 0xe3,
0x2b, 0x80, 0x19, 0xf1, 0xde, 0xc7, 0xff, 0xdf, 0x3d, 0xfd, 0x65, 0x41, 0xdf, 0xcc, 0x98, 0xc4,
0x77, 0xd0, 0xe5, 0xf5, 0xb8, 0x73, 0x25, 0xc6, 0x8f, 0xda, 0x10, 0x75, 0xbf, 0xe8, 0xe0, 0x31,
0x74, 0xdf, 0x67, 0x79, 0x8e, 0xe3, 0x36, 0xdc, 0xd9, 0xac, 0x8d, 0xd2, 0x69, 0xef, 0xb3, 0xfe,
0x7b, 0x48, 0x3c, 0xfe, 0x79, 0xfa, 0x37, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x50, 0x5f, 0x13, 0x1a,
0x06, 0x00, 0x00,
}