Skip to content

Instantly share code, notes, and snippets.

@jamesdavidson
Last active May 29, 2024 02:47
Show Gist options
  • Save jamesdavidson/da5f807993cd3ce4ff0e6922055d281a to your computer and use it in GitHub Desktop.
Save jamesdavidson/da5f807993cd3ce4ff0e6922055d281a to your computer and use it in GitHub Desktop.
gzipper.clj
;; 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