http.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // 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. package v2http
  15. import (
  16. "math"
  17. "net/http"
  18. "strings"
  19. "time"
  20. "go.etcd.io/etcd/etcdserver/api/etcdhttp"
  21. "go.etcd.io/etcd/etcdserver/api/v2auth"
  22. "go.etcd.io/etcd/etcdserver/api/v2http/httptypes"
  23. "go.etcd.io/etcd/pkg/logutil"
  24. "github.com/coreos/pkg/capnslog"
  25. "go.uber.org/zap"
  26. )
  27. const (
  28. // time to wait for a Watch request
  29. defaultWatchTimeout = time.Duration(math.MaxInt64)
  30. )
  31. var (
  32. plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/api/v2http")
  33. mlog = logutil.NewMergeLogger(plog)
  34. )
  35. func writeError(lg *zap.Logger, w http.ResponseWriter, r *http.Request, err error) {
  36. if err == nil {
  37. return
  38. }
  39. if e, ok := err.(v2auth.Error); ok {
  40. herr := httptypes.NewHTTPError(e.HTTPStatus(), e.Error())
  41. if et := herr.WriteTo(w); et != nil {
  42. if lg != nil {
  43. lg.Debug(
  44. "failed to write v2 HTTP error",
  45. zap.String("remote-addr", r.RemoteAddr),
  46. zap.String("v2auth-error", e.Error()),
  47. zap.Error(et),
  48. )
  49. } else {
  50. plog.Debugf("error writing HTTPError (%v) to %s", et, r.RemoteAddr)
  51. }
  52. }
  53. return
  54. }
  55. etcdhttp.WriteError(lg, w, r, err)
  56. }
  57. // allowMethod verifies that the given method is one of the allowed methods,
  58. // and if not, it writes an error to w. A boolean is returned indicating
  59. // whether or not the method is allowed.
  60. func allowMethod(w http.ResponseWriter, m string, ms ...string) bool {
  61. for _, meth := range ms {
  62. if m == meth {
  63. return true
  64. }
  65. }
  66. w.Header().Set("Allow", strings.Join(ms, ","))
  67. http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
  68. return false
  69. }
  70. func requestLogger(lg *zap.Logger, handler http.Handler) http.Handler {
  71. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  72. if lg != nil {
  73. lg.Debug(
  74. "handling HTTP request",
  75. zap.String("method", r.Method),
  76. zap.String("request-uri", r.RequestURI),
  77. zap.String("remote-addr", r.RemoteAddr),
  78. )
  79. } else {
  80. plog.Debugf("[%s] %s remote:%s", r.Method, r.RequestURI, r.RemoteAddr)
  81. }
  82. handler.ServeHTTP(w, r)
  83. })
  84. }