7. • HTTP server written in Common Lisp
• HTTP/0.9, HTTP/1.x
• Clack compliant
Woo
8. Clack?
• Abstraction layer of HTTP servers
Web server
Application
Web server Web server
Application Application
9. Clack?
• Abstraction layer of HTTP servers
Web server
Application
Web server Web server
Application Application
Clack
10. ex) Caveman2
• built on top of Clack
Web serverWeb server Web server
Caveman2
(Web framework)
Clack
11. ex) RESTAS (without Clack)
• directly built on top of Hunchentoot
Web server
Depends on Hunchentoot.
Can’t switch the backend!!
Supports only Hunchentoot
Web server Web server
RESTAS
(Web framework)
23. 3 difficulties in HTTP server
• Network I/O is the largest bottleneck
• Need to handle a vast amount of requests
at once
• Need to handle various HTTP clients
(fast / slow / unstable)
24. 3 tactics (no silver bullet)
1. Better architecture
2. Fast HTTP parsing
3. The libev event library
29. Event-driven
• Handle many
clients at the same
time
• Asnyc ACCEPT/
READ/WRITE
• ex) Woo, Wookie,
Tornado, nginxServer process
(single-threaded)
Event loop
34. HTTP parsing can be a bottleneck
• Wookie's largest bottleneck is HTTP parsing
• http-parse (uses regular expression)
• fast-http (byte by byte parser)
• 6000 times faster than http-parse
37. HTTP request look like…
GET /media HTTP/1.1↵
Host: somewrite.jp↵
Connection: keep-alive↵
Accept: */*↵
↵
First Line
Headers
Body (empty, in this case)
38. HTTP request look like…
GET /media HTTP/1.1↵
Host: somewrite.jp↵
Connection: keep-alive↵
Accept: */*↵
↵ CR + LF
CRLF * 2 at the end of headers
45. http-parser (used in Node.js)
• https://github.com/joyent/http-parser
• Written in C
• Ported from Nginx’s HTTP parser
• Written as Node.js’s HTTP parser
• Stateful
46. http-parser (used in Node.js)
for (p=data; p != data + len; p++) {
…
switch (parser->state) {
case s_dead:
…
case s_start_req_or_res:
…
case s_res_or_resp_H:
…
}
}
47. http-parser (used in Node.js)
for (p=data; p != data + len; p++) {
…
switch (parser->state) {
case s_dead:
…
case s_start_req_or_res:
…
case s_res_or_resp_H:
…
}
}
Process char by char
Do something
for each state
48. http-parser (used in Node.js)
for (p=data; p != data + len; p++) {
…
switch (parser->state) {
case s_dead:
…
case s_start_req_or_res:
…
case s_res_or_resp_H:
…
}
}
Process char by char
Do something
for each state
Executed
for every char!!
50. PicoHTTPParser (used in H2O)
• https://github.com/h2o/picohttpparser
• Written in C
• Stateless
51. PicoHTTPParser (used in H2O)
• https://github.com/h2o/picohttpparser
• Written in C
• Stateless
• Reparse when the data is incomplete
• Most HTTP request is small