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.
 
 
 

760 lines
20 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 messageview
  15. import (
  16. "bufio"
  17. "bytes"
  18. "compress/flate"
  19. "compress/gzip"
  20. "io"
  21. "io/ioutil"
  22. "net/http"
  23. "strings"
  24. "testing"
  25. "github.com/google/martian/proxyutil"
  26. )
  27. func TestRequestViewHeadersOnly(t *testing.T) {
  28. body := strings.NewReader("body content")
  29. req, err := http.NewRequest("GET", "http://example.com/path?k=v", body)
  30. if err != nil {
  31. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  32. }
  33. req.ContentLength = int64(body.Len())
  34. req.Header.Set("Request-Header", "true")
  35. mv := New()
  36. mv.SkipBody(true)
  37. if err := mv.SnapshotRequest(req); err != nil {
  38. t.Fatalf("SnapshotRequest(): got %v, want no error", err)
  39. }
  40. got, err := ioutil.ReadAll(mv.HeaderReader())
  41. if err != nil {
  42. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  43. }
  44. hdrwant := "GET http://example.com/path?k=v HTTP/1.1\r\n" +
  45. "Host: example.com\r\n" +
  46. "Content-Length: 12\r\n" +
  47. "Request-Header: true\r\n\r\n"
  48. if !bytes.Equal(got, []byte(hdrwant)) {
  49. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  50. }
  51. br, err := mv.BodyReader()
  52. if err != nil {
  53. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  54. }
  55. if _, err := br.Read(nil); err != io.EOF {
  56. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want io.EOF", err)
  57. }
  58. r, err := mv.Reader()
  59. if err != nil {
  60. t.Fatalf("mv.Reader(): got %v, want no error", err)
  61. }
  62. got, err = ioutil.ReadAll(r)
  63. if err != nil {
  64. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  65. }
  66. if want := []byte(hdrwant); !bytes.Equal(got, want) {
  67. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  68. }
  69. }
  70. func TestRequestView(t *testing.T) {
  71. body := strings.NewReader("body content")
  72. req, err := http.NewRequest("GET", "http://example.com/path?k=v", body)
  73. if err != nil {
  74. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  75. }
  76. req.Header.Set("Request-Header", "true")
  77. // Force Content Length to be unset to simulate lack of Content-Length and
  78. // Transfer-Encoding which is valid.
  79. req.ContentLength = -1
  80. mv := New()
  81. if err := mv.SnapshotRequest(req); err != nil {
  82. t.Fatalf("SnapshotRequest(): got %v, want no error", err)
  83. }
  84. got, err := ioutil.ReadAll(mv.HeaderReader())
  85. if err != nil {
  86. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  87. }
  88. hdrwant := "GET http://example.com/path?k=v HTTP/1.1\r\n" +
  89. "Host: example.com\r\n" +
  90. "Request-Header: true\r\n\r\n"
  91. if !bytes.Equal(got, []byte(hdrwant)) {
  92. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  93. }
  94. br, err := mv.BodyReader()
  95. if err != nil {
  96. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  97. }
  98. got, err = ioutil.ReadAll(br)
  99. if err != nil {
  100. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want no error", err)
  101. }
  102. bodywant := "body content"
  103. if !bytes.Equal(got, []byte(bodywant)) {
  104. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  105. }
  106. r, err := mv.Reader()
  107. if err != nil {
  108. t.Fatalf("mv.Reader(): got %v, want no error", err)
  109. }
  110. got, err = ioutil.ReadAll(r)
  111. if err != nil {
  112. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  113. }
  114. if want := []byte(hdrwant + bodywant); !bytes.Equal(got, want) {
  115. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  116. }
  117. // Sanity check to ensure it still parses.
  118. if _, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(got))); err != nil {
  119. t.Fatalf("http.ReadRequest(): got %v, want no error", err)
  120. }
  121. }
  122. func TestRequestViewSkipBodyUnlessContentType(t *testing.T) {
  123. req, err := http.NewRequest("GET", "http://example.com", strings.NewReader("body content"))
  124. if err != nil {
  125. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  126. }
  127. req.ContentLength = 12
  128. req.Header.Set("Content-Type", "text/plain; charset=utf-8")
  129. mv := New()
  130. mv.SkipBodyUnlessContentType("text/plain")
  131. if err := mv.SnapshotRequest(req); err != nil {
  132. t.Fatalf("SnapshotRequest(): got %v, want no error", err)
  133. }
  134. br, err := mv.BodyReader()
  135. if err != nil {
  136. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  137. }
  138. got, err := ioutil.ReadAll(br)
  139. if err != nil {
  140. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want no error", err)
  141. }
  142. bodywant := "body content"
  143. if !bytes.Equal(got, []byte(bodywant)) {
  144. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  145. }
  146. req.Header.Set("Content-Type", "image/png")
  147. mv = New()
  148. mv.SkipBodyUnlessContentType("text/plain")
  149. if err := mv.SnapshotRequest(req); err != nil {
  150. t.Fatalf("SnapshotRequest(): got %v, want no error", err)
  151. }
  152. br, err = mv.BodyReader()
  153. if err != nil {
  154. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  155. }
  156. if _, err := br.Read(nil); err != io.EOF {
  157. t.Fatalf("br.Read(): got %v, want io.EOF", err)
  158. }
  159. }
  160. func TestRequestViewChunkedTransferEncoding(t *testing.T) {
  161. req, err := http.NewRequest("GET", "http://example.com/path?k=v", strings.NewReader("body content"))
  162. if err != nil {
  163. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  164. }
  165. req.TransferEncoding = []string{"chunked"}
  166. req.Header.Set("Trailer", "Trailer-Header")
  167. req.Trailer = http.Header{
  168. "Trailer-Header": []string{"true"},
  169. }
  170. mv := New()
  171. if err := mv.SnapshotRequest(req); err != nil {
  172. t.Fatalf("SnapshotRequest(): got %v, want no error", err)
  173. }
  174. got, err := ioutil.ReadAll(mv.HeaderReader())
  175. if err != nil {
  176. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  177. }
  178. hdrwant := "GET http://example.com/path?k=v HTTP/1.1\r\n" +
  179. "Host: example.com\r\n" +
  180. "Transfer-Encoding: chunked\r\n" +
  181. "Trailer: Trailer-Header\r\n\r\n"
  182. if !bytes.Equal(got, []byte(hdrwant)) {
  183. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  184. }
  185. br, err := mv.BodyReader()
  186. if err != nil {
  187. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  188. }
  189. got, err = ioutil.ReadAll(br)
  190. if err != nil {
  191. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want no error", err)
  192. }
  193. bodywant := "c\r\nbody content\r\n0\r\n"
  194. if !bytes.Equal(got, []byte(bodywant)) {
  195. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  196. }
  197. got, err = ioutil.ReadAll(mv.TrailerReader())
  198. if err != nil {
  199. t.Fatalf("ioutil.ReadAll(mv.TrailerReader()): got %v, want no error", err)
  200. }
  201. trailerwant := "Trailer-Header: true\r\n"
  202. if !bytes.Equal(got, []byte(trailerwant)) {
  203. t.Fatalf("mv.TrailerReader(): got %q, want %q", got, trailerwant)
  204. }
  205. r, err := mv.Reader()
  206. if err != nil {
  207. t.Fatalf("mv.Reader(): got %v, want no error", err)
  208. }
  209. got, err = ioutil.ReadAll(r)
  210. if err != nil {
  211. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  212. }
  213. if want := []byte(hdrwant + bodywant + trailerwant); !bytes.Equal(got, want) {
  214. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  215. }
  216. // Sanity check to ensure it still parses.
  217. if _, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(got))); err != nil {
  218. t.Fatalf("http.ReadRequest(): got %v, want no error", err)
  219. }
  220. }
  221. func TestRequestViewDecodeGzipContentEncoding(t *testing.T) {
  222. body := new(bytes.Buffer)
  223. gw := gzip.NewWriter(body)
  224. gw.Write([]byte("body content"))
  225. gw.Flush()
  226. gw.Close()
  227. req, err := http.NewRequest("GET", "http://example.com/path?k=v", body)
  228. if err != nil {
  229. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  230. }
  231. req.TransferEncoding = []string{"chunked"}
  232. req.Header.Set("Content-Encoding", "gzip")
  233. mv := New()
  234. if err := mv.SnapshotRequest(req); err != nil {
  235. t.Fatalf("SnapshotRequest(): got %v, want no error", err)
  236. }
  237. got, err := ioutil.ReadAll(mv.HeaderReader())
  238. if err != nil {
  239. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  240. }
  241. hdrwant := "GET http://example.com/path?k=v HTTP/1.1\r\n" +
  242. "Host: example.com\r\n" +
  243. "Transfer-Encoding: chunked\r\n" +
  244. "Content-Encoding: gzip\r\n\r\n"
  245. if !bytes.Equal(got, []byte(hdrwant)) {
  246. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  247. }
  248. br, err := mv.BodyReader(Decode())
  249. if err != nil {
  250. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  251. }
  252. got, err = ioutil.ReadAll(br)
  253. if err != nil {
  254. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, wt o error", err)
  255. }
  256. bodywant := "body content"
  257. if !bytes.Equal(got, []byte(bodywant)) {
  258. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  259. }
  260. r, err := mv.Reader(Decode())
  261. if err != nil {
  262. t.Fatalf("mv.Reader(): got %v, want no error", err)
  263. }
  264. got, err = ioutil.ReadAll(r)
  265. if err != nil {
  266. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  267. }
  268. if want := []byte(hdrwant + bodywant + "\r\n"); !bytes.Equal(got, want) {
  269. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  270. }
  271. }
  272. func TestRequestViewDecodeDeflateContentEncoding(t *testing.T) {
  273. body := new(bytes.Buffer)
  274. dw, err := flate.NewWriter(body, -1)
  275. if err != nil {
  276. t.Fatalf("flate.NewWriter(): got %v, want no error", err)
  277. }
  278. dw.Write([]byte("body content"))
  279. dw.Flush()
  280. dw.Close()
  281. req, err := http.NewRequest("GET", "http://example.com/path?k=v", body)
  282. if err != nil {
  283. t.Fatalf("http.NewRequest(): got %v, want no error", err)
  284. }
  285. req.TransferEncoding = []string{"chunked"}
  286. req.Header.Set("Content-Encoding", "deflate")
  287. mv := New()
  288. if err := mv.SnapshotRequest(req); err != nil {
  289. t.Fatalf("SnapshotRequest(): got %v, want no error", err)
  290. }
  291. got, err := ioutil.ReadAll(mv.HeaderReader())
  292. if err != nil {
  293. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  294. }
  295. hdrwant := "GET http://example.com/path?k=v HTTP/1.1\r\n" +
  296. "Host: example.com\r\n" +
  297. "Transfer-Encoding: chunked\r\n" +
  298. "Content-Encoding: deflate\r\n\r\n"
  299. if !bytes.Equal(got, []byte(hdrwant)) {
  300. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  301. }
  302. br, err := mv.BodyReader(Decode())
  303. if err != nil {
  304. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  305. }
  306. got, err = ioutil.ReadAll(br)
  307. if err != nil {
  308. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want no error", err)
  309. }
  310. bodywant := "body content"
  311. if !bytes.Equal(got, []byte(bodywant)) {
  312. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  313. }
  314. r, err := mv.Reader(Decode())
  315. if err != nil {
  316. t.Fatalf("mv.Reader(): got %v, want no error", err)
  317. }
  318. got, err = ioutil.ReadAll(r)
  319. if err != nil {
  320. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  321. }
  322. if want := []byte(hdrwant + bodywant + "\r\n"); !bytes.Equal(got, want) {
  323. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  324. }
  325. }
  326. func TestResponseViewHeadersOnly(t *testing.T) {
  327. body := strings.NewReader("body content")
  328. res := proxyutil.NewResponse(200, body, nil)
  329. res.ContentLength = 12
  330. res.Header.Set("Response-Header", "true")
  331. mv := New()
  332. mv.SkipBody(true)
  333. if err := mv.SnapshotResponse(res); err != nil {
  334. t.Fatalf("SnapshotResponse(): got %v, want no error", err)
  335. }
  336. got, err := ioutil.ReadAll(mv.HeaderReader())
  337. if err != nil {
  338. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  339. }
  340. hdrwant := "HTTP/1.1 200 OK\r\n" +
  341. "Content-Length: 12\r\n" +
  342. "Response-Header: true\r\n\r\n"
  343. if !bytes.Equal(got, []byte(hdrwant)) {
  344. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  345. }
  346. br, err := mv.BodyReader()
  347. if err != nil {
  348. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  349. }
  350. if _, err := br.Read(nil); err != io.EOF {
  351. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want io.EOF", err)
  352. }
  353. r, err := mv.Reader()
  354. if err != nil {
  355. t.Fatalf("mv.Reader(): got %v, want no error", err)
  356. }
  357. got, err = ioutil.ReadAll(r)
  358. if err != nil {
  359. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  360. }
  361. if want := []byte(hdrwant); !bytes.Equal(got, want) {
  362. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  363. }
  364. }
  365. func TestResponseView(t *testing.T) {
  366. body := strings.NewReader("body content")
  367. res := proxyutil.NewResponse(200, body, nil)
  368. res.ContentLength = 12
  369. res.Header.Set("Response-Header", "true")
  370. mv := New()
  371. if err := mv.SnapshotResponse(res); err != nil {
  372. t.Fatalf("SnapshotResponse(): got %v, want no error", err)
  373. }
  374. got, err := ioutil.ReadAll(mv.HeaderReader())
  375. if err != nil {
  376. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  377. }
  378. hdrwant := "HTTP/1.1 200 OK\r\n" +
  379. "Content-Length: 12\r\n" +
  380. "Response-Header: true\r\n\r\n"
  381. if !bytes.Equal(got, []byte(hdrwant)) {
  382. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  383. }
  384. br, err := mv.BodyReader()
  385. if err != nil {
  386. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  387. }
  388. got, err = ioutil.ReadAll(br)
  389. if err != nil {
  390. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want no error", err)
  391. }
  392. bodywant := "body content"
  393. if !bytes.Equal(got, []byte(bodywant)) {
  394. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  395. }
  396. r, err := mv.Reader()
  397. if err != nil {
  398. t.Fatalf("mv.Reader(): got %v, want no error", err)
  399. }
  400. got, err = ioutil.ReadAll(r)
  401. if err != nil {
  402. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  403. }
  404. if want := []byte(hdrwant + bodywant); !bytes.Equal(got, want) {
  405. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  406. }
  407. // Sanity check to ensure it still parses.
  408. if _, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(got)), nil); err != nil {
  409. t.Fatalf("http.ReadResponse(): got %v, want no error", err)
  410. }
  411. }
  412. func TestResponseViewSkipBodyUnlessContentType(t *testing.T) {
  413. res := proxyutil.NewResponse(200, strings.NewReader("body content"), nil)
  414. res.ContentLength = 12
  415. res.Header.Set("Content-Type", "text/plain; charset=utf-8")
  416. mv := New()
  417. mv.SkipBodyUnlessContentType("text/plain")
  418. if err := mv.SnapshotResponse(res); err != nil {
  419. t.Fatalf("SnapshotResponse(): got %v, want no error", err)
  420. }
  421. br, err := mv.BodyReader()
  422. if err != nil {
  423. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  424. }
  425. got, err := ioutil.ReadAll(br)
  426. if err != nil {
  427. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want no error", err)
  428. }
  429. bodywant := "body content"
  430. if !bytes.Equal(got, []byte(bodywant)) {
  431. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  432. }
  433. res.Header.Set("Content-Type", "image/png")
  434. mv = New()
  435. mv.SkipBodyUnlessContentType("text/plain")
  436. if err := mv.SnapshotResponse(res); err != nil {
  437. t.Fatalf("SnapshotResponse(): got %v, want no error", err)
  438. }
  439. br, err = mv.BodyReader()
  440. if err != nil {
  441. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  442. }
  443. if _, err := br.Read(nil); err != io.EOF {
  444. t.Fatalf("br.Read(): got %v, want io.EOF", err)
  445. }
  446. }
  447. func TestResponseViewChunkedTransferEncoding(t *testing.T) {
  448. body := strings.NewReader("body content")
  449. res := proxyutil.NewResponse(200, body, nil)
  450. res.TransferEncoding = []string{"chunked"}
  451. res.Header.Set("Trailer", "Trailer-Header")
  452. res.Trailer = http.Header{
  453. "Trailer-Header": []string{"true"},
  454. }
  455. mv := New()
  456. if err := mv.SnapshotResponse(res); err != nil {
  457. t.Fatalf("SnapshotResponse(): got %v, want no error", err)
  458. }
  459. got, err := ioutil.ReadAll(mv.HeaderReader())
  460. if err != nil {
  461. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  462. }
  463. hdrwant := "HTTP/1.1 200 OK\r\n" +
  464. "Transfer-Encoding: chunked\r\n" +
  465. "Trailer: Trailer-Header\r\n\r\n"
  466. if !bytes.Equal(got, []byte(hdrwant)) {
  467. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  468. }
  469. br, err := mv.BodyReader()
  470. if err != nil {
  471. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  472. }
  473. got, err = ioutil.ReadAll(br)
  474. if err != nil {
  475. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, want no error", err)
  476. }
  477. bodywant := "c\r\nbody content\r\n0\r\n"
  478. if !bytes.Equal(got, []byte(bodywant)) {
  479. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  480. }
  481. got, err = ioutil.ReadAll(mv.TrailerReader())
  482. if err != nil {
  483. t.Fatalf("ioutil.ReadAll(mv.TrailerReader()): got %v, want no error", err)
  484. }
  485. trailerwant := "Trailer-Header: true\r\n"
  486. if !bytes.Equal(got, []byte(trailerwant)) {
  487. t.Fatalf("mv.TrailerReader(): got %q, want %q", got, trailerwant)
  488. }
  489. r, err := mv.Reader()
  490. if err != nil {
  491. t.Fatalf("mv.Reader(): got %v, want no error", err)
  492. }
  493. got, err = ioutil.ReadAll(r)
  494. if err != nil {
  495. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  496. }
  497. if want := []byte(hdrwant + bodywant + trailerwant); !bytes.Equal(got, want) {
  498. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  499. }
  500. // Sanity check to ensure it still parses.
  501. if _, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(got)), nil); err != nil {
  502. t.Fatalf("http.ReadResponse(): got %v, want no error", err)
  503. }
  504. }
  505. func TestResponseViewDecodeGzipContentEncoding(t *testing.T) {
  506. body := new(bytes.Buffer)
  507. gw := gzip.NewWriter(body)
  508. gw.Write([]byte("body content"))
  509. gw.Flush()
  510. gw.Close()
  511. res := proxyutil.NewResponse(200, body, nil)
  512. res.TransferEncoding = []string{"chunked"}
  513. res.Header.Set("Content-Encoding", "gzip")
  514. mv := New()
  515. if err := mv.SnapshotResponse(res); err != nil {
  516. t.Fatalf("SnapshotResponse(): got %v, want no error", err)
  517. }
  518. got, err := ioutil.ReadAll(mv.HeaderReader())
  519. if err != nil {
  520. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  521. }
  522. hdrwant := "HTTP/1.1 200 OK\r\n" +
  523. "Transfer-Encoding: chunked\r\n" +
  524. "Content-Encoding: gzip\r\n\r\n"
  525. if !bytes.Equal(got, []byte(hdrwant)) {
  526. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  527. }
  528. br, err := mv.BodyReader(Decode())
  529. if err != nil {
  530. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  531. }
  532. got, err = ioutil.ReadAll(br)
  533. if err != nil {
  534. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, wt o error", err)
  535. }
  536. bodywant := "body content"
  537. if !bytes.Equal(got, []byte(bodywant)) {
  538. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  539. }
  540. r, err := mv.Reader(Decode())
  541. if err != nil {
  542. t.Fatalf("mv.Reader(): got %v, want no error", err)
  543. }
  544. got, err = ioutil.ReadAll(r)
  545. if err != nil {
  546. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  547. }
  548. if want := []byte(hdrwant + bodywant + "\r\n"); !bytes.Equal(got, want) {
  549. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  550. }
  551. }
  552. func TestResponseViewDecodeGzipContentEncodingPartial(t *testing.T) {
  553. bodywant := "partial content"
  554. res := proxyutil.NewResponse(206, strings.NewReader(bodywant), nil)
  555. res.TransferEncoding = []string{"chunked"}
  556. res.Header.Set("Content-Encoding", "gzip")
  557. mv := New()
  558. if err := mv.SnapshotResponse(res); err != nil {
  559. t.Fatalf("SnapshotResponse(): got %v, want no error", err)
  560. }
  561. br, err := mv.BodyReader(Decode())
  562. if err != nil {
  563. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  564. }
  565. got, err := ioutil.ReadAll(br)
  566. if err != nil {
  567. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, wt o error", err)
  568. }
  569. if !bytes.Equal(got, []byte(bodywant)) {
  570. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  571. }
  572. }
  573. func TestResponseViewDecodeDeflateContentEncoding(t *testing.T) {
  574. body := new(bytes.Buffer)
  575. dw, err := flate.NewWriter(body, -1)
  576. if err != nil {
  577. t.Fatalf("flate.NewWriter(): got %v, want no error", err)
  578. }
  579. dw.Write([]byte("body content"))
  580. dw.Flush()
  581. dw.Close()
  582. res := proxyutil.NewResponse(200, body, nil)
  583. res.TransferEncoding = []string{"chunked"}
  584. res.Header.Set("Content-Encoding", "deflate")
  585. mv := New()
  586. if err := mv.SnapshotResponse(res); err != nil {
  587. t.Fatalf("SnapshotResponse(): got %v, want no error", err)
  588. }
  589. got, err := ioutil.ReadAll(mv.HeaderReader())
  590. if err != nil {
  591. t.Fatalf("ioutil.ReadAll(mv.HeaderReader()): got %v, want no error", err)
  592. }
  593. hdrwant := "HTTP/1.1 200 OK\r\n" +
  594. "Transfer-Encoding: chunked\r\n" +
  595. "Content-Encoding: deflate\r\n\r\n"
  596. if !bytes.Equal(got, []byte(hdrwant)) {
  597. t.Fatalf("mv.HeaderReader(): got %q, want %q", got, hdrwant)
  598. }
  599. br, err := mv.BodyReader(Decode())
  600. if err != nil {
  601. t.Fatalf("mv.BodyReader(): got %v, want no error", err)
  602. }
  603. got, err = ioutil.ReadAll(br)
  604. if err != nil {
  605. t.Fatalf("ioutil.ReadAll(mv.BodyReader()): got %v, wt o error", err)
  606. }
  607. bodywant := "body content"
  608. if !bytes.Equal(got, []byte(bodywant)) {
  609. t.Fatalf("mv.BodyReader(): got %q, want %q", got, bodywant)
  610. }
  611. r, err := mv.Reader(Decode())
  612. if err != nil {
  613. t.Fatalf("mv.Reader(): got %v, want no error", err)
  614. }
  615. got, err = ioutil.ReadAll(r)
  616. if err != nil {
  617. t.Fatalf("ioutil.ReadAll(mv.Reader()): got %v, want no error", err)
  618. }
  619. if want := []byte(hdrwant + bodywant + "\r\n"); !bytes.Equal(got, want) {
  620. t.Fatalf("mv.Read(): got %q, want %q", got, want)
  621. }
  622. }