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.
 
 
 

340 lines
8.9 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 querystring
  15. import (
  16. "errors"
  17. "net/http"
  18. "strings"
  19. "testing"
  20. "github.com/google/martian"
  21. "github.com/google/martian/martiantest"
  22. "github.com/google/martian/parse"
  23. "github.com/google/martian/proxyutil"
  24. "github.com/google/martian/verify"
  25. // Import to register header.Modifier with JSON parser.
  26. _ "github.com/google/martian/header"
  27. )
  28. func TestNoModifiers(t *testing.T) {
  29. f := NewFilter("", "")
  30. f.SetRequestModifier(nil)
  31. f.SetResponseModifier(nil)
  32. req, err := http.NewRequest("GET", "http://example.com", nil)
  33. if err != nil {
  34. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  35. }
  36. if err := f.ModifyRequest(req); err != nil {
  37. t.Errorf("ModifyRequest(): got %v, want no error", err)
  38. }
  39. res := proxyutil.NewResponse(200, nil, req)
  40. if err := f.ModifyResponse(res); err != nil {
  41. t.Errorf("ModifyResponse(): got %v, want no error", err)
  42. }
  43. }
  44. func TestQueryStringFilterWithQuery(t *testing.T) {
  45. // Name only, no value.
  46. f := NewFilter("match", "")
  47. tm := martiantest.NewModifier()
  48. f.SetRequestModifier(tm)
  49. f.SetResponseModifier(tm)
  50. req, err := http.NewRequest("GET", "http://martian.local?match=any", nil)
  51. if err != nil {
  52. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  53. }
  54. if err := f.ModifyRequest(req); err != nil {
  55. t.Errorf("ModifyRequest(): got %v, want no error", err)
  56. }
  57. if !tm.RequestModified() {
  58. t.Error("tm.RequestModified(): got false, want true")
  59. }
  60. res := proxyutil.NewResponse(200, nil, req)
  61. if err := f.ModifyResponse(res); err != nil {
  62. t.Errorf("ModifyResponse(): got %v, want no error", err)
  63. }
  64. if !tm.ResponseModified() {
  65. t.Error("tm.ResponseModified(): got false, want true")
  66. }
  67. tm.Reset()
  68. req, err = http.NewRequest("GET", "http://martian.local?nomatch", nil)
  69. if err != nil {
  70. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  71. }
  72. if err := f.ModifyRequest(req); err != nil {
  73. t.Errorf("ModifyRequest(): got %v, want no error", err)
  74. }
  75. res = proxyutil.NewResponse(200, nil, req)
  76. if err := f.ModifyResponse(res); err != nil {
  77. t.Errorf("ModifyResponse(): got %v, want no error", err)
  78. }
  79. if tm.RequestModified() {
  80. t.Error("tm.RequestModified(): got true, want false")
  81. }
  82. if tm.ResponseModified() {
  83. t.Error("tm.ResponseModified(): got true, want false")
  84. }
  85. tm.Reset()
  86. // Name and value.
  87. f = NewFilter("match", "value")
  88. f.SetRequestModifier(tm)
  89. f.SetResponseModifier(tm)
  90. req, err = http.NewRequest("GET", "http://martian.local?match=value", nil)
  91. if err != nil {
  92. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  93. }
  94. if err := f.ModifyRequest(req); err != nil {
  95. t.Errorf("ModifyRequest(): got %v, want no error", err)
  96. }
  97. res = proxyutil.NewResponse(200, nil, req)
  98. if err := f.ModifyResponse(res); err != nil {
  99. t.Errorf("ModifyResponse(): got %v, want no error", err)
  100. }
  101. if !tm.RequestModified() {
  102. t.Error("tm.RequestModified(): got false, want true")
  103. }
  104. if !tm.ResponseModified() {
  105. t.Error("tm.ResponseModified(): got false, want true")
  106. }
  107. tm.Reset()
  108. req, err = http.NewRequest("GET", "http://martian.local?match=notvalue", nil)
  109. if err != nil {
  110. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  111. }
  112. if err := f.ModifyRequest(req); err != nil {
  113. t.Errorf("ModifyRequest(): got %v, want no error", err)
  114. }
  115. res = proxyutil.NewResponse(200, nil, req)
  116. if err := f.ModifyResponse(res); err != nil {
  117. t.Errorf("ModifyResponse(): got %v, want no error", err)
  118. }
  119. if tm.RequestModified() {
  120. t.Error("tm.RequestModified(): got true, want false")
  121. }
  122. if tm.ResponseModified() {
  123. t.Error("tm.ResponseModified(): got true, want false")
  124. }
  125. tm.Reset()
  126. // Explicitly do not match POST data.
  127. req, err = http.NewRequest("GET", "http://martian.local", strings.NewReader("match=value"))
  128. if err != nil {
  129. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  130. }
  131. if err := f.ModifyRequest(req); err != nil {
  132. t.Errorf("ModifyRequest(): got %v, want no error", err)
  133. }
  134. res = proxyutil.NewResponse(200, nil, req)
  135. if err := f.ModifyResponse(res); err != nil {
  136. t.Errorf("ModifyResponse(): got %v, want no error", err)
  137. }
  138. if tm.RequestModified() {
  139. t.Error("tm.RequestModified(): got true, want false")
  140. }
  141. if tm.ResponseModified() {
  142. t.Error("tm.ResponseModified(): got true, want false")
  143. }
  144. tm.Reset()
  145. }
  146. func TestFilterFromJSON(t *testing.T) {
  147. msg := []byte(`{
  148. "querystring.Filter": {
  149. "scope": ["request", "response"],
  150. "name": "param",
  151. "value": "true",
  152. "modifier": {
  153. "header.Modifier": {
  154. "scope": ["request", "response"],
  155. "name": "Martian-Modified",
  156. "value": "true"
  157. }
  158. }
  159. }
  160. }`)
  161. r, err := parse.FromJSON(msg)
  162. if err != nil {
  163. t.Fatalf("parse.FromJSON(): got %v, want no error", err)
  164. }
  165. reqmod := r.RequestModifier()
  166. if reqmod == nil {
  167. t.Fatal("reqmod: got nil, want not nil")
  168. }
  169. req, err := http.NewRequest("GET", "https://martian.test?param=true", nil)
  170. if err != nil {
  171. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  172. }
  173. if err := reqmod.ModifyRequest(req); err != nil {
  174. t.Fatalf("reqmod.ModifyRequest(): got %v, want no error", err)
  175. }
  176. if got, want := req.Header.Get("Martian-Modified"), "true"; got != want {
  177. t.Errorf("req.Header.Get(%q): got %q, want %q", "Martian-Modified", got, want)
  178. }
  179. resmod := r.ResponseModifier()
  180. if resmod == nil {
  181. t.Fatalf("resmod: got nil, want not nil")
  182. }
  183. res := proxyutil.NewResponse(200, nil, req)
  184. if err := resmod.ModifyResponse(res); err != nil {
  185. t.Fatalf("resmod.ModifyResponse(): got %v, want no error", err)
  186. }
  187. if got, want := res.Header.Get("Martian-Modified"), "true"; got != want {
  188. t.Errorf("res.Header.Get(%q): got %q, want %q", "Martian-Modified", got, want)
  189. }
  190. }
  191. func TestElseCondition(t *testing.T) {
  192. msg := []byte(`{
  193. "querystring.Filter": {
  194. "scope": ["request", "response"],
  195. "name": "param",
  196. "value": "true",
  197. "modifier": {
  198. "header.Modifier": {
  199. "scope": ["request", "response"],
  200. "name": "Martian-Modified",
  201. "value": "true"
  202. }
  203. },
  204. "else": {
  205. "header.Modifier": {
  206. "scope": ["request", "response"],
  207. "name": "Martian-Modified",
  208. "value": "false"
  209. }
  210. }
  211. }
  212. }`)
  213. r, err := parse.FromJSON(msg)
  214. if err != nil {
  215. t.Fatalf("parse.FromJSON(): got %v, want no error", err)
  216. }
  217. reqmod := r.RequestModifier()
  218. if reqmod == nil {
  219. t.Fatal("reqmod: got nil, want not nil")
  220. }
  221. req, err := http.NewRequest("GET", "https://martian.test?param=false", nil)
  222. if err != nil {
  223. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  224. }
  225. if err := reqmod.ModifyRequest(req); err != nil {
  226. t.Fatalf("reqmod.ModifyRequest(): got %v, want no error", err)
  227. }
  228. if got, want := req.Header.Get("Martian-Modified"), "false"; got != want {
  229. t.Errorf("req.Header.Get(%q): got %q, want %q", "Martian-Modified", got, want)
  230. }
  231. resmod := r.ResponseModifier()
  232. if resmod == nil {
  233. t.Fatalf("resmod: got nil, want not nil")
  234. }
  235. res := proxyutil.NewResponse(200, nil, req)
  236. if err := resmod.ModifyResponse(res); err != nil {
  237. t.Fatalf("resmod.ModifyResponse(): got %v, want no error", err)
  238. }
  239. if got, want := res.Header.Get("Martian-Modified"), "false"; got != want {
  240. t.Errorf("res.Header.Get(%q): got %q, want %q", "Martian-Modified", got, want)
  241. }
  242. }
  243. func TestVerifyRequests(t *testing.T) {
  244. f := NewFilter("", "")
  245. if err := f.VerifyRequests(); err != nil {
  246. t.Fatalf("VerifyRequest(): got %v, want no error", err)
  247. }
  248. tv := &verify.TestVerifier{
  249. RequestError: errors.New("verify request failure"),
  250. }
  251. f.SetRequestModifier(tv)
  252. want := martian.NewMultiError()
  253. want.Add(tv.RequestError)
  254. if got := f.VerifyRequests(); got.Error() != want.Error() {
  255. t.Fatalf("VerifyRequests(): got %v, want %v", got, want)
  256. }
  257. f.ResetRequestVerifications()
  258. if err := f.VerifyRequests(); err != nil {
  259. t.Fatalf("VerifyRequest(): got %v, want no error", err)
  260. }
  261. }
  262. func TestVerifyResponses(t *testing.T) {
  263. f := NewFilter("", "")
  264. if err := f.VerifyResponses(); err != nil {
  265. t.Fatalf("VerifyResponses(): got %v, want no error", err)
  266. }
  267. tv := &verify.TestVerifier{
  268. ResponseError: errors.New("verify response failure"),
  269. }
  270. f.SetResponseModifier(tv)
  271. want := martian.NewMultiError()
  272. want.Add(tv.ResponseError)
  273. if got := f.VerifyResponses(); got.Error() != want.Error() {
  274. t.Fatalf("VerifyResponses(): got %v, want %v", got, want)
  275. }
  276. f.ResetResponseVerifications()
  277. if err := f.VerifyResponses(); err != nil {
  278. t.Fatalf("VerifyResponses(): got %v, want no error", err)
  279. }
  280. }