Skip to content

Commit

Permalink
Merge pull request #315 from onaio/use-content-disposition-header-for…
Browse files Browse the repository at this point in the history
…-xls-file-extensions

Use content-disposition header for  file names
  • Loading branch information
FrankApiyo authored Feb 24, 2023
2 parents 718ac4d + 5f1d576 commit aade5d5
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 29 deletions.
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
:milia-http-default-per-route "10"
:milia-http-threads "20"})

(defproject onaio/milia "0.8.0"
(defproject onaio/milia "0.9.1-rc"
:description "The ona.io Clojure Web API Client."
:dependencies [;; CORE MILIA REQUIREMENTS
[cheshire "5.11.0"]
Expand Down
69 changes: 41 additions & 28 deletions src/milia/api/http.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
(:require #?@(:clj [[milia.api.io :refer [parse-response
http-request debug-api
parse-binary-response]]
[slingshot.slingshot :refer [throw+]]]
[slingshot.slingshot :refer [throw+]]
[clojure.string :refer [replace]]]
:cljs [[milia.api.io :refer [build-http-options token->headers
http-request raw-request]]
[cljs-http.client :as http]
Expand Down Expand Up @@ -37,30 +38,42 @@
;; CLJ: synchronous implementation, checks status before returning.
#?(:clj
(let [json-file?
(when (and filename (not raw-response?))
(.endsWith ^String filename ".json"))
(when (and filename (not raw-response?))
(.endsWith ^String filename ".json"))
;; Call http-request if filename extension is not of type json
{:keys [body status] :as response}
(when-not json-file?
(http-request method
url
http-options))
{:keys [body status headers] :as response}
(when-not json-file?
(http-request method
url
http-options))
{:keys [Content-Disposition]} headers
extension
(when Content-Disposition
(cond
(re-find #"\.xlsx" Content-Disposition)
"xlsx"
(re-find #"\.xls" Content-Disposition)
"xls"))
;; use content-disposition header for `.xls` file names
filename (if extension
(replace filename #"\.xls$|\.xlsx$" (str "." extension))
filename)
;; Call parse-binary-response if filename extension is of type json
;; which will then handle the http request
parsed-response (if json-file?
(parse-binary-response nil
filename
:url url
:http-options http-options)
(parse-response body
status
filename
raw-response?))
parsed-response (if json-file?
(parse-binary-response nil
filename
:url url
:http-options http-options)
(parse-response body
status
filename
raw-response?))
filter-http-options
(fn [http-options]
(update-in http-options [:form-params]
(fn [form-params]
(apply dissoc form-params [:email :password]))))
(fn [http-options]
(update-in http-options [:form-params]
(fn [form-params]
(apply dissoc form-params [:email :password]))))
error-fn #(throw-error
% status parsed-response
{:method method
Expand All @@ -69,13 +82,13 @@
(debug-api method url http-options response)
;; Assume that a nil status indicates an exception
(when-not json-file?
(cond
(nil? response) (error-fn :no-http-response)
(nil? status) (error-fn :no-http-status)
(and status
(>= status 400) (< status 500) (not suppress-4xx-exceptions?))
(error-fn :http-client-error)
(>= status 500) (error-fn :http-server-error)))
(cond
(nil? response) (error-fn :no-http-response)
(nil? status) (error-fn :no-http-status)
(and status
(>= status 400) (< status 500) (not suppress-4xx-exceptions?))
(error-fn :http-client-error)
(>= status 500) (error-fn :http-server-error)))
(if as-map?
(assoc response :body parsed-response) parsed-response))
;; CLJS: asynchronous implementation, returns a channel.
Expand Down
27 changes: 27 additions & 0 deletions test/clj/milia/api/http_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,33 @@
(def auth-token "auth-token")

(facts "about parse-http"
(fact "Use Content-Disposition header to name xls file"
(parse-http :method :url {:filename "file-name.xlsx"}) => :response
(provided
(http-request :method :url nil) =>
{:body :body :status 200
:headers
{:Content-Disposition
"attachment; filename=\"transportation.xls; filename*=UTF-8"}}
(parse-response :body 200 "file-name.xls" nil) => :response))
(fact "Use Content-Disposition header to re-name xlsx file -> xls"
(parse-http :method :url {:filename "file-name.xlsx"}) => :response
(provided
(http-request :method :url nil) =>
{:body :body :status 200
:headers
{:Content-Disposition
"attachment; filename=\"transportation.xls"}}
(parse-response :body 200 "file-name.xls" nil) => :response))
(fact "Use Content-Disposition header to name xlsx file"
(parse-http :method :url {:filename "file-name.xlsx"}) => :response
(provided
(http-request :method :url nil) =>
{:body :body :status 200
:headers
{:Content-Disposition
"attachment; filename=\"transportation.xlsx; filename*=UTF-8"}}
(parse-response :body 200 "file-name.xlsx" nil) => :response))
(fact "throws an exception when the API server is not reachable"
(parse-http :method :url)
=> (throws (make-exception-str :no-http-response
Expand Down

0 comments on commit aade5d5

Please sign in to comment.