Last active
May 29, 2024 02:47
-
-
Save jamesdavidson/da5f807993cd3ce4ff0e6922055d281a to your computer and use it in GitHub Desktop.
gzipper.clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; clj -Sdeps '{:deps {org.clojure/data.csv {:mvn/version "1.1.0"} org.clojure/data.json {:mvn/version "2.5.0"}}}' --main gzipper | |
(ns gzipper | |
(:require [clojure.java.io :as io] | |
[clojure.walk :as walk] | |
[clojure.string :as string] | |
[clojure.data.json :as json] | |
[clojure.data.csv :as csv]) | |
(:import [java.net InetSocketAddress HttpURLConnection] | |
[java.util.zip GZIPOutputStream] | |
[com.sun.net.httpserver HttpServer HttpHandler])) | |
(def prefix "/") | |
(defn respond [exch] | |
(let [url-path (.replace (str (.getRequestURI exch)) prefix "") | |
res-headers (.getResponseHeaders exch) | |
res-body (.getResponseBody exch)] | |
(cond | |
(contains? #{"" "/"} url-path) | |
(with-open [w (io/writer res-body)] | |
(.set res-headers "Content-Type" "text/html") | |
(.sendResponseHeaders exch HttpURLConnection/HTTP_OK 0) | |
(.write w "<a href=test.csv.gz>test.csv.gz</a>")) | |
(= "test.csv.gz" url-path) | |
(do | |
(.set res-headers "Content-Type" "application/x-gzip") | |
(.set res-headers "Content-Disposition" "attachment; filename=\"test.csv.gz\"") | |
(.sendResponseHeaders exch HttpURLConnection/HTTP_OK 0) | |
(with-open [gzipper (new GZIPOutputStream res-body) | |
w (io/writer gzipper)] | |
;; generate some fake data | |
(loop [rows (->> ["foo" "bar" "baz"] | |
cycle | |
(take 100) | |
(partition 2))] | |
(when-let [row (first rows)] | |
(csv/write-csv w [row]) | |
(recur (rest rows)))))) | |
:default | |
(.sendResponseHeaders exch HttpURLConnection/HTTP_NOT_FOUND -1)))) | |
(def handler | |
(reify HttpHandler | |
(handle [this exchange] | |
(try | |
(#'respond exchange) | |
(catch Exception e | |
(with-open [response (io/writer (.getResponseBody exchange))] | |
(.set (.getResponseHeaders exchange) "content-type" "text/plain") | |
(.sendResponseHeaders exchange HttpURLConnection/HTTP_UNAVAILABLE 0) | |
(.write response (json/write-str (Throwable->map e))))))))) | |
(defonce server | |
(doto (HttpServer/create) | |
(.createContext prefix handler))) | |
(defn -main [& args] | |
(doto server | |
(.bind (new InetSocketAddress "127.0.0.1" 8080) 0) | |
(.start))) | |
(comment | |
(.bind server (new InetSocketAddress "127.0.0.1" 8080) 0) | |
(.start server) | |
(.stop server 0) | |
(use 'clojure.pprint 'clojure.repl) | |
(with-open [is (io/input-stream (io/file "manifest.csv.gz")) | |
gunzipper (new GZIPInputStream is) | |
rdr (io/reader gunzipper)] | |
(def rows | |
(into [] | |
(csv/read-csv rdr)))) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment