/
transport_http.go
123 lines (103 loc) · 3.32 KB
/
transport_http.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Code generated by truss. DO NOT EDIT.
// Rerunning truss will overwrite this file.
// Version: b8d375e642
// Version Date: Fri Aug 4 23:55:38 UTC 2017
package svc
// This file provides server-side bindings for the HTTP transport.
// It utilizes the transport/http.Server.
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"strconv"
"strings"
"context"
httptransport "github.com/go-kit/kit/transport/http"
"github.com/gorilla/mux"
"github.com/pkg/errors"
// This service
pb "github.com/myambition/ambition/services/model/model-service"
)
const contentType = "application/json; charset=utf-8"
var (
_ = fmt.Sprint
_ = bytes.Compare
_ = strconv.Atoi
_ = httptransport.NewServer
_ = ioutil.NopCloser
_ = pb.NewModelClient
_ = io.Copy
_ = errors.Wrap
)
// MakeHTTPHandler returns a handler that makes a set of endpoints available
// on predefined paths.
func MakeHTTPHandler(endpoints Endpoints) http.Handler {
m := mux.NewRouter()
return m
}
// ErrorEncoder writes the error to the ResponseWriter, by default a content
// type of application/json, a body of json with key "error" and the value
// error.Error(), and a status code of 500. If the error implements Headerer,
// the provided headers will be applied to the response. If the error
// implements json.Marshaler, and the marshaling succeeds, the JSON encoded
// form of the error will be used. If the error implements StatusCoder, the
// provided StatusCode will be used instead of 500.
func errorEncoder(_ context.Context, err error, w http.ResponseWriter) {
body, _ := json.Marshal(errorWrapper{Error: err.Error()})
if marshaler, ok := err.(json.Marshaler); ok {
if jsonBody, marshalErr := marshaler.MarshalJSON(); marshalErr == nil {
body = jsonBody
}
}
w.Header().Set("Content-Type", contentType)
if headerer, ok := err.(httptransport.Headerer); ok {
for k := range headerer.Headers() {
w.Header().Set(k, headerer.Headers().Get(k))
}
}
code := http.StatusInternalServerError
if sc, ok := err.(httptransport.StatusCoder); ok {
code = sc.StatusCode()
}
w.WriteHeader(code)
w.Write(body)
}
type errorWrapper struct {
Error string `json:"error"`
}
// httpError satisfies the Headerer and StatusCoder interfaces in
// package github.com/go-kit/kit/transport/http.
type httpError struct {
error
statusCode int
headers map[string][]string
}
func (h httpError) StatusCode() int {
return h.statusCode
}
func (h httpError) Headers() http.Header {
return h.headers
}
// Server Decode
// EncodeHTTPGenericResponse is a transport/http.EncodeResponseFunc that encodes
// the response as JSON to the response writer. Primarily useful in a server.
func EncodeHTTPGenericResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
return encoder.Encode(response)
}
// Helper functions
func headersToContext(ctx context.Context, r *http.Request) context.Context {
for k, _ := range r.Header {
// The key is added both in http format (k) which has had
// http.CanonicalHeaderKey called on it in transport as well as the
// strings.ToLower which is the grpc metadata format of the key so
// that it can be accessed in either format
ctx = context.WithValue(ctx, k, r.Header.Get(k))
ctx = context.WithValue(ctx, strings.ToLower(k), r.Header.Get(k))
}
return ctx
}