cb5de4555d
In the previous commit, if gzip compression was applied to a request input stream, the stream was not automatically closed when the request was complete. The Apache HTTP async library, however, closes an input stream in cases where gzip compression is not being added. In this commit, the original request input stream is closed immediately after attempts to copy the data from it to the downstream gzipped input stream have been completed, for compatibility with the pre-existing Apache HTTP async library behavior.
138 lines
6.2 KiB
Clojure
138 lines
6.2 KiB
Clojure
(ns puppetlabs.http.client.gzip-request-test
|
||
(:import (com.puppetlabs.http.client Sync
|
||
SimpleRequestOptions
|
||
ResponseBodyType
|
||
CompressType)
|
||
(java.io ByteArrayInputStream FilterInputStream)
|
||
(java.net URI)
|
||
(java.util.zip GZIPInputStream))
|
||
(:require [clojure.test :refer :all]
|
||
[cheshire.core :as cheshire]
|
||
[schema.test :as schema-test]
|
||
[puppetlabs.http.client.sync :as http-client]
|
||
[puppetlabs.http.client.test-common :refer :all]
|
||
[puppetlabs.trapperkeeper.testutils.webserver :as testwebserver]))
|
||
|
||
(use-fixtures :once schema-test/validate-schemas)
|
||
|
||
(defn req-body-app
|
||
[req]
|
||
(let [response {:request-content-encoding (get-in req [:headers "content-encoding"])
|
||
:request-body-decompressed (slurp
|
||
(GZIPInputStream. (:body req))
|
||
:encoding "utf-8")}]
|
||
{:status 200
|
||
:headers {"Content-Type" "application/json; charset=utf-8"}
|
||
:body (cheshire/generate-string response)}))
|
||
|
||
(def short-request-body "gzip me<6D>")
|
||
|
||
(def big-request-body
|
||
(apply str (repeat 4000 "and<6E>i<EFBFBD>said<69>hey<65>yeah<61>yeah<61>whats<74>going<6E>on")))
|
||
|
||
(defn string->byte-array-input-stream
|
||
[source is-closed-atom]
|
||
(let [bis (-> source
|
||
(.getBytes)
|
||
(ByteArrayInputStream.))]
|
||
(proxy [FilterInputStream] [bis]
|
||
(close []
|
||
(reset! is-closed-atom true)
|
||
(proxy-super close)))))
|
||
|
||
(defn post-gzip-clj-request
|
||
[port body]
|
||
(-> (http-client/post (format "http://localhost:%d" port)
|
||
{:body body
|
||
:headers {"Content-Type" "text/plain; charset=utf-8"}
|
||
:compress-request-body :gzip
|
||
:as :text})
|
||
:body
|
||
(cheshire/parse-string true)))
|
||
|
||
(defn post-gzip-java-request
|
||
[port body]
|
||
(-> (SimpleRequestOptions. (URI. (format "http://localhost:%d/hello/" port)))
|
||
(.setBody body)
|
||
(.setHeaders {"Content-Type" "text/plain; charset=utf-8"})
|
||
(.setRequestBodyCompression CompressType/GZIP)
|
||
(.setAs ResponseBodyType/TEXT)
|
||
(Sync/post)
|
||
(.getBody)
|
||
(cheshire/parse-string true)))
|
||
|
||
(deftest clj-sync-client-gzip-requests
|
||
(testing "for clojure sync client"
|
||
(testwebserver/with-test-webserver
|
||
req-body-app
|
||
port
|
||
(testing "short string body is gzipped in request"
|
||
(let [response (post-gzip-clj-request port short-request-body)]
|
||
(is (= "gzip" (:request-content-encoding response)))
|
||
(is (= short-request-body (:request-body-decompressed response)))))
|
||
(testing "big string body is gzipped in request"
|
||
(let [response (post-gzip-clj-request port big-request-body)]
|
||
(is (= "gzip" (:request-content-encoding response)))
|
||
(is (= big-request-body (:request-body-decompressed response)))))
|
||
(testing "short inputstream body is gzipped in request"
|
||
(let [is-closed (atom false)
|
||
response (post-gzip-clj-request
|
||
port
|
||
(string->byte-array-input-stream short-request-body
|
||
is-closed))]
|
||
(is (= "gzip" (:request-content-encoding response)))
|
||
(is (= short-request-body (:request-body-decompressed response)))
|
||
(is @is-closed "input stream was not closed after request")))
|
||
(testing "big inputstream body is gzipped in request"
|
||
(let [is-closed (atom false)
|
||
response (post-gzip-clj-request
|
||
port
|
||
(string->byte-array-input-stream big-request-body
|
||
is-closed))]
|
||
(is (= "gzip" (:request-content-encoding response)))
|
||
(is (= big-request-body (:request-body-decompressed response)))
|
||
(is @is-closed "input stream was not closed after request"))))))
|
||
|
||
(deftest java-sync-client-gzip-requests
|
||
(testing "for java sync client"
|
||
(testwebserver/with-test-webserver
|
||
req-body-app
|
||
port
|
||
(testing "short string body is gzipped in request"
|
||
(let [response (post-gzip-java-request port short-request-body)]
|
||
(is (= "gzip" (:request-content-encoding response)))
|
||
(is (= short-request-body (:request-body-decompressed response)))))
|
||
(testing "big string body is gzipped in request"
|
||
(let [response (post-gzip-java-request port big-request-body)]
|
||
(is (= "gzip" (:request-content-encoding response)))
|
||
(is (= big-request-body (:request-body-decompressed response)))))
|
||
(testing "short inputstream body is gzipped in request"
|
||
(let [is-closed (atom false)
|
||
response (post-gzip-java-request
|
||
port
|
||
(string->byte-array-input-stream short-request-body
|
||
is-closed))]
|
||
(is (= "gzip" (:request-content-encoding response)))
|
||
(is (= short-request-body (:request-body-decompressed response)))
|
||
(is @is-closed "input stream was not closed after request")))
|
||
(testing "big inputstream body is gzipped in request"
|
||
(let [is-closed (atom false)
|
||
response (post-gzip-java-request
|
||
port
|
||
(string->byte-array-input-stream big-request-body
|
||
is-closed))]
|
||
(is (= "gzip" (:request-content-encoding response)))
|
||
(is (= big-request-body (:request-body-decompressed response)))
|
||
(is @is-closed "input stream was not closed after request"))))))
|
||
|
||
(deftest connect-exception-during-gzip-request-returns-failure
|
||
(testing "connection exception during gzip request returns failure"
|
||
(let [is-closed (atom false)]
|
||
(is (connect-exception-thrown?
|
||
(http-client/post "http://localhost:65535"
|
||
{:body (string->byte-array-input-stream
|
||
short-request-body
|
||
is-closed)
|
||
:compress-request-body :gzip
|
||
:as :text})))
|
||
(is @is-closed "input stream was not closed after request"))))
|