<commit_before>(ns gin.system.ring.jetty-async-adapter
  "Adapter for the Jetty webserver, with async HTTP."
  (:import (org.eclipse.jetty.server.handler AbstractHandler)
           (org.eclipse.jetty.server Server Request Response)
           (org.eclipse.jetty.server.nio SelectChannelConnector)
           (org.eclipse.jetty.continuation Continuation ContinuationSupport ContinuationListener)
           (org.eclipse.jetty.io EofException)
           (javax.servlet.http HttpServletRequest))
  (:require [clojure.tools.logging :refer [info debug]]
            [ring.util.servlet :as servlet]
            [com.stuartsierra.component :as component]
            [clojure.core.async :refer [go <! close!] :as async]
            [clojure.core.async.impl.protocols :as async-protocols]))

;; Based on ring-jetty-async-adapter by <NAME>
;; (https://github.com/mmcgrana/ring/tree/jetty-async)
;; This has failed write support


(defn- proxy-handler
  "Returns an Jetty Handler implementation for the given Ring handler."
  [handler options]
  (proxy [AbstractHandler] []
    (handle [target ^Request base-request ^HttpServletRequest request response]
      (let [request-map (servlet/build-request-map request)
            response-map (handler request-map)]
        (if-not (satisfies? async-protocols/Channel (:body response-map))
          (do
            (servlet/update-servlet-response response response-map)
            (.setHandled base-request true))
          (let [;; continuation lives until written to!
                continuation (.startAsync request)
                servlet-response (.getServletResponse continuation)
                _ (doto servlet-response
                    (servlet/set-status (:status response-map))
                    (servlet/set-headers (:headers response-map))
                    (.flushBuffer))
                chunks (:body response-map)]
            (.addContinuationListener continuation
                                      (proxy [ContinuationListener] []
                                        (onComplete [c]
                                          (close! chunks))
                                        (onTimeout [c]
                                          (try (.complete c)
                                               (catch Exception e
                                                 nil)))))
            (go (try
                  (loop []
                    (if-let [chunk (<! chunks)]
                      (do
                        (doto (.getWriter response)
                          (.write chunk)
                          (.flush))
                        (when (.checkError (.getWriter response))
                          (close! chunks))
                        (recur))
                      (.complete continuation)))
                  (catch Exception e
                    (close! chunks)
                    (try (.complete continuation)
                         (catch Exception e
                           nil)))))
            ;; 4 minutes is google default
            (.setTimeout continuation (get options :response-timeout (* 4
                                                                        60 1000)))<commit_msg>Eventsource IE support (IE10 or higher only)<commit_after>(ns gin.system.ring.jetty-async-adapter
  "Adapter for the Jetty webserver, with async HTTP."
  (:import (org.eclipse.jetty.server.handler AbstractHandler)
           (org.eclipse.jetty.server Server Request Response)
           (org.eclipse.jetty.server.nio SelectChannelConnector)
           (org.eclipse.jetty.continuation Continuation ContinuationSupport ContinuationListener)
           (org.eclipse.jetty.io EofException)
           (javax.servlet.http HttpServletRequest))
  (:require [clojure.tools.logging :refer [info debug]]
            [ring.util.servlet :as servlet]
            [com.stuartsierra.component :as component]
            [clojure.core.async :refer [go <! close!] :as async]
            [clojure.core.async.impl.protocols :as async-protocols]))

(def IE_PADDING_COMMENT (str ": " (apply str (repeatedly 2056 #(long (* (rand) 10)))) "\r\n\r\n"))

;; Based on ring-jetty-async-adapter by <NAME>
;; (https://github.com/mmcgrana/ring/tree/jetty-async)
;; This has failed write support


(defn- proxy-handler
  "Returns an Jetty Handler implementation for the given Ring handler."
  [handler options]
  (proxy [AbstractHandler] []
    (handle [target ^Request base-request ^HttpServletRequest request response]
      (let [request-map (servlet/build-request-map request)
            response-map (handler request-map)]
        (if-not (satisfies? async-protocols/Channel (:body response-map))
          (do
            (servlet/update-servlet-response response response-map)
            (.setHandled base-request true))
          (let [;; continuation lives until written to!
                continuation (.startAsync request)
                servlet-response (.getServletResponse continuation)
                _ (doto servlet-response
                    (servlet/set-status (:status response-map))
                    (servlet/set-headers (:headers response-map))
                    (.flushBuffer))
                chunks (:body response-map)]
            (.addContinuationListener continuation
                                      (proxy [ContinuationListener] []
                                        (onComplete [c]
                                          (close! chunks))
                                        (onTimeout [c]
                                          (try (.complete c)
                                               (catch Exception e
                                                 nil)))))
            ;; IE EventSource polyfill padding
            (when (.contains (str "" (:query-string request-map)) "evs_preamble")
              (try (doto (.getWriter response)
                     (.write IE_PADDING_COMMENT)
                     (.flush))
                   (catch Exception e
                     nil)))
            (go (try
                  (loop []
                    (if-let [chunk (<! chunks)]
                      (do
                        (doto (.getWriter response)
                          (.write chunk)
                          (.flush))
                        (when (.checkError (.getWriter response))
                          (close! chunks))
                        (recur))
                      (.complete continuation)))
                  (catch Exception e
                    (close! chunks)
                    (try (.complete continuation)
                         (catch Exception e
                           nil)))))
            ;; 4 minutes is google default
            (.setTimeout continuation (get options :response-timeout (* 4
                                                                        60 1000)))
{'fraction_non_alphanumeric': 0.0958884207467674, 'fraction_numerical': 0.0034868516635188146, 'mean_word_length': 1.364823084850567, 'pattern_counts': {'":': 1, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7476750', 'n_tokens_mistral': 1644, 'n_tokens_neox': 1518, 'n_words': 413}