You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

105 lines
2.6 KiB

  1. // Copyright 2015 Google Inc. All rights reserved.
  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 method provides utilities for verifying method type in martian.Proxy.
  15. package method
  16. import (
  17. "encoding/json"
  18. "fmt"
  19. "net/http"
  20. "github.com/google/martian"
  21. "github.com/google/martian/parse"
  22. "github.com/google/martian/verify"
  23. )
  24. type verifier struct {
  25. method string
  26. err *martian.MultiError
  27. }
  28. type verifierJSON struct {
  29. Method string `json:"method"`
  30. Scope []parse.ModifierType `json:"scope"`
  31. }
  32. func init() {
  33. parse.Register("method.Verifier", verifierFromJSON)
  34. }
  35. // NewVerifier returns a new method verifier.
  36. func NewVerifier(method string) (verify.RequestVerifier, error) {
  37. if method == "" {
  38. return nil, fmt.Errorf("%s is not a valid HTTP method", method)
  39. }
  40. return &verifier{
  41. method: method,
  42. err: martian.NewMultiError(),
  43. }, nil
  44. }
  45. // ModifyRequest verifies that the request's method matches the given method
  46. // in all modified requests. An error will be added to the contained *MultiError
  47. // if a method is unmatched.
  48. func (v *verifier) ModifyRequest(req *http.Request) error {
  49. m := req.Method
  50. if v.method != "" && v.method != m {
  51. err := fmt.Errorf("request(%v) method verification error: got %v, want %v", req.URL,
  52. v.method, m)
  53. v.err.Add(err)
  54. }
  55. return nil
  56. }
  57. // VerifyRequests returns an error if verification for any request failed.
  58. // If an error is returned it will be of type *martian.MultiError.
  59. func (v *verifier) VerifyRequests() error {
  60. if v.err.Empty() {
  61. return nil
  62. }
  63. return v.err
  64. }
  65. // ResetRequestVerifications clears all failed request verifications.
  66. func (v *verifier) ResetRequestVerifications() {
  67. v.err = martian.NewMultiError()
  68. }
  69. // verifierFromJSON builds a method.Verifier from JSON.
  70. //
  71. // Example JSON:
  72. // {
  73. // "method.Verifier": {
  74. // "scope": ["request"],
  75. // "method": "POST"
  76. // }
  77. // }
  78. func verifierFromJSON(b []byte) (*parse.Result, error) {
  79. msg := &verifierJSON{}
  80. if err := json.Unmarshal(b, msg); err != nil {
  81. return nil, err
  82. }
  83. v, err := NewVerifier(msg.Method)
  84. if err != nil {
  85. return nil, err
  86. }
  87. return parse.NewResult(v, msg.Scope)
  88. }