DEPRECATED: prefer `sec-websocket-accept`


(as-channel ring-req {:keys [on-receive on-ping on-close on-open init on-handshake-error], :or {on-handshake-error (fn [ch] (send! ch {:status 400, :headers {"Content-Type" "text/plain"}, :body "Bad Sec-Websocket-Key header"} true))}})
Returns `{:body ch}`, where `ch` is the request's underlying
asynchronous HTTP or WebSocket `AsyncChannel`.

Main options:
  :init       - (fn [ch])         for misc pre-handshake setup.
  :on-receive - (fn [ch message]) called for client WebSocket messages.
  :on-ping    - (fn [ch data])    called for client WebSocket pings.
  :on-close   - (fn [ch status])  called when AsyncChannel is closed.
  :on-open    - (fn [ch])         called when AsyncChannel is ready for `send!`, etc.

See `Channel` protocol for more info on handlers and `AsyncChannel`s.
See `org.httpkit.timer` ns for optional timeout utils.


Example - Async HTTP response:

  (def clients_ (atom #{}))
  (defn my-async-handler [ring-req]
    (as-channel ring-req
      {:on-open (fn [ch] (swap! clients_ conj ch))}))

  ;; Somewhere else in your code
  (doseq [ch @clients_]
    (swap! clients_ disj ch)
    (send! ch {:status 200 :headers {"Content-Type" "text/html"}
               :body "Your async response"}
      ;; false ; Uncomment to use chunk encoding for HTTP streaming

Example - WebSocket response:

  (defn my-chatroom-handler [ring-req]
    (if-not (:websocket? ring-req)
      {:status 200 :body "Welcome to the chatroom! JS client connecting..."}
      (as-channel ring-req
        {:on-receive (fn [ch message] (println "on-receive:" message))
         :on-close   (fn [ch status]  (println "on-close:"   status))
         :on-open    (fn [ch]         (println "on-open:"    ch))})))



Unified asynchronous channel interface for HTTP (streaming or long-polling)
and WebSocket.



(close ch)
Closes the channel. Idempotent: returns true if the channel was actually
closed, or false if it was already closed.


(on-close ch callback)
Sets handler (fn [status]) for notification of channel being closed by the
server or client. Handler will be invoked at most once. Useful for clean-up.

Callback status argument:
  :server-close   : Channel closed by sever
  :client-close   : HTTP channel closed by client
  :normal         : WebSocket closed by client (CLOSE_NORMAL)
  :going-away     : WebSocket closed by client (CLOSE_GOING_AWAY)
  :protocol-error : WebSocket closed by client (CLOSE_PROTOCOL_ERROR)
  :unsupported    : WebSocket closed by client (CLOSE_UNSUPPORTED)
  :unknown        : WebSocket closed by client (unknown reason)


(on-ping ch callback)
Sets handler (fn [data]) for notification of client WebSocket pings. The
data param represents application data and will by a byte[].


(on-receive ch callback)
Sets handler (fn [message]) for notification of client WebSocket
messages. Message ordering is guaranteed by server.

The message argument could be a string or a byte[].


(open? ch)
Returns true iff channel is open.


(send! ch data)(send! ch data close-after-send?)
Sends data to client and returns true if the data was successfully sent,
or false if the channel is closed. Data is sent directly to the client,

When unspecified, `close-after-send?` defaults to true for HTTP channels
and false for WebSocket.

Data form: {:headers _ :status _ :body _} or just body. Note that :headers
and :status will be stripped for WebSocket and for HTTP streaming responses
after the first.

For WebSocket, a text frame is sent to client if data is String,
a binary frame when data is byte[] or InputStream. For for HTTP streaming
responses, data can be one of the type defined by Ring spec


(websocket? ch)
Returns true iff channel is a WebSocket.





(-server-stop! http-server opts)


(server-port http-server)
Given an HttpServer, returns server's local port.


(server-status http-server)
Given an HttpServer, returns server's status e/o #{:stopped :running :stopping}.


(run-server handler & [{:keys [ip port thread queue-size max-body max-ws max-line proxy-protocol worker-name-prefix worker-pool error-logger warn-logger event-logger event-names legacy-return-value? server-header], :or {max-ws 4194304, max-body 8388608, max-line 8192, server-header "http-kit", ip "", queue-size 20480, proxy-protocol :disable, port 8090, legacy-return-value? true, thread 4, worker-name-prefix "worker-"}}])
Starts a mostly[1] Ring-compatible HttpServer with options:

  :ip                 ; Which ip (if has many ips) to bind
  :port               ; Which port listen incomming request
  :thread             ; Http worker thread count
  :queue-size         ; Max job queued before reject to project self
  :max-body           ; Max http body: 8m
  :max-ws             ; Max websocket message size
  :max-line           ; Max http inital line length
  :proxy-protocol     ; Proxy protocol e/o #{:disable :enable :optional}
  :worker-name-prefix ; Worker thread name prefix
  :worker-pool        ; ExecutorService to use for request-handling (:thread,
                        :worker-name-prefix, :queue-size are ignored if set)
  :error-logger       ; Arity-2 fn (args: string text, exception) to log errors
  :warn-logger        ; Arity-2 fn (args: string text, exception) to log warnings
  :event-logger       ; Arity-1 fn (arg: string event name)
  :event-names        ; map of HTTP-Kit event names to respective loggable event names
  :server-header      ; The "Server" header. If missing, defaults to "http-kit", disabled if nil.

If :legacy-return-value? is
  true  (default)     ; Returns a (fn stop-server [& {:keys [timeout] :or {timeout 100}}])
  false (recommended) ; Returns the HttpServer which can be used with `server-port`,
                      ; `server-status`, `server-stop!`, etc.

[1] Ref. for differences.


(sec-websocket-accept sec-websocket-key)


(send-checked-websocket-handshake! ch sec-ws-accept)
Given an AsyncChannel and `sec-ws-accept` string, unconditionally
sends handshake to upgrade given AsyncChannel to a WebSocket.
See also `websocket-handshake-check`.


(send-websocket-handshake! ch ring-req)
Returns true iff successfully upgraded a valid WebSocket request.


(server-stop! http-server)(server-stop! http-server opts)
Signals given HttpServer to stop.

If     already stopping: returns nil.
If not already stopping: returns a Promise that will be delivered once
server thread actually completes.

  :timeout ; Max msecs to allow existing requests to complete before attempting
           ; interrupt (default 100).


(websocket-handshake-check ring-req)
Returns `sec-ws-accept` string iff given Ring request is a valid
WebSocket handshake.



(with-channel ring-req ch-name & body)
DEPRECATED: this macro has potential race conditions, Ref. #318.
Prefer `as-channel` instead.