Skip to content

Instantly share code, notes, and snippets.

@redraiment
Created January 17, 2016 07:10
Show Gist options
  • Save redraiment/0222d1ca0a69fa50cd0f to your computer and use it in GitHub Desktop.
Save redraiment/0222d1ca0a69fa50cd0f to your computer and use it in GitHub Desktop.
简易的HTTP服务器,用于检测各种HTTP Client对KeepAlive的支持
(ns me.zzp.http
(:require [clojure.string :refer [blank?]])
(:import java.io.PrintStream
java.net.ServerSocket
java.util.Scanner
java.util.concurrent.atomic.AtomicLong)
(:gen-class))
(defonce generitor (AtomicLong.))
(defn info [id message]
(println (format "[%d] %s" id message)))
(defn http-read-header [scanner]
(loop [content-length 0
headers (StringBuilder.)]
(let [line (if (.hasNextLine scanner) (.nextLine scanner) "")]
(if (blank? line)
[content-length (.toString headers)]
(recur (if-let [[_ length] (re-matches #"Content-Length: (\d+)" line)]
(Long/parseLong length)
content-length)
(.. headers
(append "\n ")
(append line)))))))
(defn http-read [scanner]
(let [[length headers] (http-read-header scanner)]
(if (zero? length)
headers
(apply str headers "\n "
(for [_ (range length)]
(if (.hasNext scanner "(?s).")
(.next scanner "(?s).")
""))))))
(defn http-write [stream message]
(. stream print
(format "HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: %d\r\n\r\n%s" (alength (.getBytes message)) message)))
(defn process [logger client]
(logger "open")
(let [scanner (.useDelimiter (Scanner. (.getInputStream client)) "")
stream (PrintStream. (.getOutputStream client))]
(while (.hasNextLine scanner)
(logger "receive request")
(logger (http-read scanner))
(logger "send response")
(http-write stream "OK")
(logger "done")))
(.close client)
(logger "close"))
(defn -main [& args]
(let [server (ServerSocket. (int 8000))]
(println "server start @ 8000")
(loop []
(let [client (.accept server)]
(future (process (partial info (.incrementAndGet generitor)) client))
(recur)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment