50 行代码实现一个简单的 WEB 服务器

最近在看 Groovy 正好写一个 WEB 服务器熟悉下语法。

这里的简单是只实现网站根目录的访问,一个完整的 WEB 服务器实现是很复杂的 可参考 nginx

WEB 服务器的原理是先监听一个 Socket 端口,当 TCP 请求完成握手之后 然后根据 HTTP 协议完成通讯。

HTTP_PORT = 9999
HTTP_ROOT = '/Users/kanshan/gitProjects/Coder'

def server = new ServerSocket(HTTP_PORT)
while(true){
    def socket = server.accept()
    new Thread({
        def input = socket.inputStream
        def output = socket.outputStream
        try{
            def outMessage = handler(parserRequest(input))
            output.write(outMessage.getBytes())
        }catch(Exception ex){
            println ex
        }finally{
            input.close()
            output.flush()
            output.close()
        }
    } as Runnable).start()
}
def parserRequest(InputStream input){
    def reader = input.newReader()
    def protocol = []
    while(reader.ready()){
        def line = reader.readLine()
        if(!line.isBlank()) protocol << line
    }
    def firstLine = protocol[0].split(' ')
    def wrapper = [:]
    wrapper.method = firstLine[0]
    wrapper.router = firstLine[1]
    wrapper.version = firstLine[2]
    1.upto(protocol.size() - 1){
        def kv = protocol[it].split(':')
        wrapper."${kv[0]}" = kv[1].trim()
    }
    return wrapper
}
def handler(wrapper){
    def buffer = new StringBuffer()
    buffer.append("${wrapper.version} 200 OK\r\n")
    buffer.append("")
    buffer.append("\r\n")
    def file = new File("${HTTP_ROOT}${File.separator}${wrapper.router}")
    if(!file.isDirectory() && file.exists() && file.canRead()){
        buffer.append(file.text)
    }
    return buffer.toString()
}

之后可以考虑使用 NIO 实现。

以上就是全部的代码,这里监听的是 9999 端口,设置网站根目录为: /Users/kanshan/gitProjects/Coder,改兴趣可以拷贝到 app.groovy 中,使用 groovy app.groovy 运行。