blob: c6956893e1479f23537192a7ed43186bb864e774 [file] [log] [blame]
khenaidoo59ce9dd2019-11-11 13:05:32 -05001// Copyright 2015 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package v2http
16
17import (
18 "math"
19 "net/http"
20 "strings"
21 "time"
22
23 "go.etcd.io/etcd/etcdserver/api/etcdhttp"
24 "go.etcd.io/etcd/etcdserver/api/v2auth"
25 "go.etcd.io/etcd/etcdserver/api/v2http/httptypes"
26 "go.etcd.io/etcd/pkg/logutil"
27
28 "github.com/coreos/pkg/capnslog"
29 "go.uber.org/zap"
30)
31
32const (
33 // time to wait for a Watch request
34 defaultWatchTimeout = time.Duration(math.MaxInt64)
35)
36
37var (
38 plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/api/v2http")
39 mlog = logutil.NewMergeLogger(plog)
40)
41
42func writeError(lg *zap.Logger, w http.ResponseWriter, r *http.Request, err error) {
43 if err == nil {
44 return
45 }
46 if e, ok := err.(v2auth.Error); ok {
47 herr := httptypes.NewHTTPError(e.HTTPStatus(), e.Error())
48 if et := herr.WriteTo(w); et != nil {
49 if lg != nil {
50 lg.Debug(
51 "failed to write v2 HTTP error",
52 zap.String("remote-addr", r.RemoteAddr),
53 zap.String("v2auth-error", e.Error()),
54 zap.Error(et),
55 )
56 } else {
57 plog.Debugf("error writing HTTPError (%v) to %s", et, r.RemoteAddr)
58 }
59 }
60 return
61 }
62 etcdhttp.WriteError(lg, w, r, err)
63}
64
65// allowMethod verifies that the given method is one of the allowed methods,
66// and if not, it writes an error to w. A boolean is returned indicating
67// whether or not the method is allowed.
68func allowMethod(w http.ResponseWriter, m string, ms ...string) bool {
69 for _, meth := range ms {
70 if m == meth {
71 return true
72 }
73 }
74 w.Header().Set("Allow", strings.Join(ms, ","))
75 http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
76 return false
77}
78
79func requestLogger(lg *zap.Logger, handler http.Handler) http.Handler {
80 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
81 if lg != nil {
82 lg.Debug(
83 "handling HTTP request",
84 zap.String("method", r.Method),
85 zap.String("request-uri", r.RequestURI),
86 zap.String("remote-addr", r.RemoteAddr),
87 )
88 } else {
89 plog.Debugf("[%s] %s remote:%s", r.Method, r.RequestURI, r.RemoteAddr)
90 }
91 handler.ServeHTTP(w, r)
92 })
93}