This repository has been archived by the owner on Dec 20, 2022. It is now read-only.
/
handler.go
85 lines (73 loc) · 2.23 KB
/
handler.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
/*
Copyright (C) 2018 Yahoo Japan Corporation Athenz team.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"context"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httputil"
"strings"
"github.com/kpango/glg"
"github.com/pkg/errors"
"github.com/yahoojapan/authorization-proxy/v4/config"
"github.com/yahoojapan/authorization-proxy/v4/service"
)
// Func represents the a handle function type
type Func func(http.ResponseWriter, *http.Request) error
// New creates a handler for handling different HTTP requests based on the given services. It also contains a reverse proxy for handling proxy request.
func New(cfg config.Proxy, bp httputil.BufferPool, prov service.Authorizationd) http.Handler {
scheme := "http"
if cfg.Scheme != "" {
scheme = cfg.Scheme
}
host := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
return &httputil.ReverseProxy{
BufferPool: bp,
Director: func(r *http.Request) {
u := *r.URL
u.Scheme = scheme
u.Host = host
req, err := http.NewRequest(r.Method, u.String(), r.Body)
if err != nil {
glg.Fatal(errors.Wrap(err, "NewRequest returned error"))
}
req.Header = r.Header
req.TLS = r.TLS
*r = *req
},
Transport: &transport{
prov: prov,
RoundTripper: &http.Transport{},
cfg: cfg,
},
ErrorHandler: handleError,
}
}
func handleError(rw http.ResponseWriter, r *http.Request, err error) {
if r != nil && r.Body != nil {
io.Copy(ioutil.Discard, r.Body)
r.Body.Close()
}
status := http.StatusUnauthorized
if !strings.Contains(err.Error(), ErrMsgUnverified) {
glg.Warn("handleError: " + err.Error())
status = http.StatusBadGateway
}
// request context canceled
if errors.Cause(err) == context.Canceled {
status = http.StatusRequestTimeout
}
rw.WriteHeader(status)
}