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.
 
 
 

129 rivejä
3.1 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 header
  15. import (
  16. "encoding/json"
  17. "net/http"
  18. "regexp"
  19. "github.com/google/martian"
  20. "github.com/google/martian/parse"
  21. )
  22. // ValueRegexFilter executes resmod and reqmod when the header
  23. // value matches regex.
  24. type ValueRegexFilter struct {
  25. regex *regexp.Regexp
  26. header string
  27. reqmod martian.RequestModifier
  28. resmod martian.ResponseModifier
  29. }
  30. type headerValueRegexFilterJSON struct {
  31. Regex string `json:"regex"`
  32. HeaderName string `json:"header"`
  33. Modifier json.RawMessage `json:"modifier"`
  34. Scope []parse.ModifierType `json:"scope"`
  35. }
  36. func init() {
  37. parse.Register("header.RegexFilter", headerValueRegexFilterFromJSON)
  38. }
  39. // NewValueRegexFilter builds a new header value regex filter.
  40. func NewValueRegexFilter(regex *regexp.Regexp, header string) *ValueRegexFilter {
  41. return &ValueRegexFilter{
  42. regex: regex,
  43. header: header,
  44. reqmod: noop,
  45. resmod: noop,
  46. }
  47. }
  48. func headerValueRegexFilterFromJSON(b []byte) (*parse.Result, error) {
  49. msg := &headerValueRegexFilterJSON{}
  50. if err := json.Unmarshal(b, msg); err != nil {
  51. return nil, err
  52. }
  53. cr, err := regexp.Compile(msg.Regex)
  54. if err != nil {
  55. return nil, err
  56. }
  57. filter := NewValueRegexFilter(cr, msg.HeaderName)
  58. r, err := parse.FromJSON(msg.Modifier)
  59. if err != nil {
  60. return nil, err
  61. }
  62. reqmod := r.RequestModifier()
  63. filter.SetRequestModifier(reqmod)
  64. resmod := r.ResponseModifier()
  65. filter.SetResponseModifier(resmod)
  66. return parse.NewResult(filter, msg.Scope)
  67. }
  68. // ModifyRequest runs reqmod iff the value of header matches regex.
  69. func (f *ValueRegexFilter) ModifyRequest(req *http.Request) error {
  70. hvalue := req.Header.Get(f.header)
  71. if hvalue == "" {
  72. return nil
  73. }
  74. if f.regex.MatchString(hvalue) {
  75. return f.reqmod.ModifyRequest(req)
  76. }
  77. return nil
  78. }
  79. // ModifyResponse runs resmod iff the value of request header matches regex.
  80. func (f *ValueRegexFilter) ModifyResponse(res *http.Response) error {
  81. hvalue := res.Request.Header.Get(f.header)
  82. if hvalue == "" {
  83. return nil
  84. }
  85. if f.regex.MatchString(hvalue) {
  86. return f.resmod.ModifyResponse(res)
  87. }
  88. return nil
  89. }
  90. // SetRequestModifier sets the request modifier of HeaderValueRegexFilter.
  91. func (f *ValueRegexFilter) SetRequestModifier(reqmod martian.RequestModifier) {
  92. if reqmod == nil {
  93. f.reqmod = noop
  94. return
  95. }
  96. f.reqmod = reqmod
  97. }
  98. // SetResponseModifier sets the response modifier of HeaderValueRegexFilter.
  99. func (f *ValueRegexFilter) SetResponseModifier(resmod martian.ResponseModifier) {
  100. if resmod == nil {
  101. f.resmod = noop
  102. return
  103. }
  104. f.resmod = resmod
  105. }