3 HTTP server implementation for LuCI - helper class
4 (c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
16 module("luci.httpd.server", package.seeall)
21 VHost = luci.util.class()
23 function VHost.__init__(self, handler)
24 self.handler = handler
28 function VHost.process(self, ...)
29 -- TODO: Dispatch handler
32 function VHost.sethandler(self, handler, match)
34 self.dhandler[match] = handler
36 self.handler = handler
42 Server = luci.util.class()
44 function Server.__init__(self, ip, port, base)
45 self.socket = socket.bind(ip, port)
46 self.socket:settimeout(0, "t")
47 self.clhandler = client_handler
48 self.errhandler = error503
52 -- Clone another server
54 getmetatable(self).__index = base
59 function Server.setvhost(self, vhost, name)
61 self.vhosts[name] = vhost
68 function Server.error400(self, client, msg)
69 client:send( "HTTP/1.0 400 Bad request\r\n" )
70 client:send( "Content-Type: text/plain\r\n\r\n" )
73 client:send( msg .. "\r\n" )
79 function Server.error503(self, client)
80 client:send( "HTTP/1.0 503 Server unavailable\r\n" )
81 client:send( "Content-Type: text/plain\r\n\r\n" )
82 client:send( "There are too many clients connected, try again later\r\n" )
85 function Server.process(self, ...)
86 -- TODO: Dispatch vhost
90 function Server.client_handler(self, client)
92 client:settimeout( 0 )
94 -- Create LTN12 block source
95 local block_source = function()
99 local chunk, err, part = client:receive( READ_BUFSIZE )
101 if chunk == nil and err == "timeout" then
103 elseif chunk ~= nil then
111 -- Create LTN12 line source
112 local line_source = ltn12.source.simplify( function()
116 local chunk, err, part = client:receive("*l")
119 if chunk == nil and err ~= "timeout" then
122 and "Line exceeds maximum allowed length["..part.."]"
129 chunk = chunk:gsub("\r$","")
131 -- We got end of headers, switch to dummy source
133 return "", function()
142 coroutine.yield(client)
146 local message, err = luci.http.protocol.parse_message_header( line_source )
150 -- If we have a HTTP/1.1 client and an Expect: 100-continue header then
151 -- respond with HTTP 100 Continue message
152 if message.http_version == 1.1 and message.headers['Expect'] and
153 message.headers['Expect'] == '100-continue'
155 client:send("HTTP/1.1 100 Continue\r\n\r\n")
159 local s, e = luci.http.protocol.parse_message_body( block_source, message )
162 luci.util.dumptable( message )
165 self:error400( client, e )
168 self:error400( client, err )
172 self:error400( client, "Dummy response" )