lib/popcorn: App uses pre / post middlewares
[nit.git] / lib / popcorn / popcorn.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2016 Alexandre Terrasa <alexandre@moz-code.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Application server abstraction on top of nitcorn.
18 module popcorn
19
20 import nitcorn
21 import pop_middlewares
22 intrude import pop_handlers
23
24 # App acts like a wrapper around a nitcorn `Action`.
25 redef class App
26 super Action
27
28 # Do not show anything on console
29 var quiet = false is writable
30
31 # Start listening on `host:port`.
32 fun listen(host: String, port: Int) do
33 var iface = "{host}:{port}"
34 var vh = new VirtualHost(iface)
35
36 vh.routes.add new Route("/", self)
37
38 var fac = new HttpFactory.and_libevent
39 fac.config.virtual_hosts.add vh
40
41 if not quiet then
42 print "Launching server on http://{iface}/"
43 end
44 fac.run
45 end
46
47 # Handle request from nitcorn
48 redef fun answer(req, uri) do
49 uri = uri.simplify_path
50 var res = new HttpResponse(404)
51 for route, handler in pre_handlers do
52 handler.handle(route, uri, req, res)
53 end
54 for route, handler in handlers do
55 handler.handle(route, uri, req, res)
56 if res.sent then break
57 end
58 if not res.sent then
59 res.send(error_tpl(res.status_code, res.status_message), 404)
60 end
61 for route, handler in post_handlers do
62 handler.handle(route, uri, req, res)
63 end
64 res.session = req.session
65 return res
66 end
67
68 #
69 fun error_tpl(status: Int, message: nullable String): Template do
70 return new ErrorTpl(status, message)
71 end
72 end
73
74 #
75 class ErrorTpl
76 super Template
77
78 #
79 var status: Int
80
81 #
82 var message: nullable String
83
84 redef fun rendering do add """
85 <!DOCTYPE html>
86 <html>
87 <head>
88 <meta charset="utf-8">
89 <title>{{{message or else status}}}</title>
90 </head>
91 <body>
92 <h1>{{{status}}} {{{message or else ""}}}</h1>
93 </body>
94 </html>"""
95
96 end