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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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 运行。

感谢您的阅读,本文由 JSPeng | BLOG 版权所有。如若转载,请注明出处:JSPeng | BLOG(http://jspeng.com/2019/02/12/50 行代码实现一个简单的 WEB 服务器/
关于Javascript正则的'反向引用'
浅谈 HTTP 和 HTTPS