Software /
code /
prosody
Comparison
net/httpserver.lua @ 3497:e9159b325e33
net.httpserver: Removed old HTTP parser, and updated to use util.httpstream.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Fri, 17 Sep 2010 04:06:07 +0500 |
parent | 3473:84fe4d5ac2ed |
child | 3540:bc139431830b |
comparison
equal
deleted
inserted
replaced
3496:9408d1e10e17 | 3497:e9159b325e33 |
---|---|
8 | 8 |
9 | 9 |
10 local socket = require "socket" | 10 local socket = require "socket" |
11 local server = require "net.server" | 11 local server = require "net.server" |
12 local url_parse = require "socket.url".parse; | 12 local url_parse = require "socket.url".parse; |
13 local httpstream_new = require "util.httpstream".new; | |
13 | 14 |
14 local connlisteners_start = require "net.connlisteners".start; | 15 local connlisteners_start = require "net.connlisteners".start; |
15 local connlisteners_get = require "net.connlisteners".get; | 16 local connlisteners_get = require "net.connlisteners".get; |
16 local listener; | 17 local listener; |
17 | 18 |
112 end | 113 end |
113 end | 114 end |
114 end | 115 end |
115 | 116 |
116 local function request_reader(request, data, startpos) | 117 local function request_reader(request, data, startpos) |
117 if not data then | 118 if not request.parser then |
118 if request.body then | 119 local function success_cb(r) |
120 for k,v in pairs(r) do request[k] = v; end | |
121 request.url = url_parse(request.path); | |
122 request.body = { request.body }; | |
119 call_callback(request); | 123 call_callback(request); |
120 else | 124 end |
121 -- Error.. connection was closed prematurely | 125 local function error_cb(r) |
122 call_callback(request, "connection-closed"); | 126 call_callback(request, r or "connection-closed"); |
123 end | 127 destroy_request(request); |
124 -- Here we force a destroy... the connection is gone, so we can't reply later | 128 end |
125 destroy_request(request); | 129 request.parser = httpstream_new(success_cb, error_cb); |
126 return; | 130 end |
127 end | 131 request.parser:feed(data); |
128 if request.state == "body" then | |
129 log("debug", "Reading body...") | |
130 if not request.body then request.body = {}; request.havebodylength, request.bodylength = 0, tonumber(request.headers["content-length"]); end | |
131 if startpos then | |
132 data = data:sub(startpos, -1) | |
133 end | |
134 t_insert(request.body, data); | |
135 if request.bodylength then | |
136 request.havebodylength = request.havebodylength + #data; | |
137 if request.havebodylength >= request.bodylength then | |
138 -- We have the body | |
139 call_callback(request); | |
140 end | |
141 end | |
142 elseif request.state == "headers" then | |
143 log("debug", "Reading headers...") | |
144 local pos = startpos; | |
145 local headers, headers_complete = request.headers; | |
146 if not headers then | |
147 headers = {}; | |
148 request.headers = headers; | |
149 end | |
150 | |
151 for line in data:gmatch("(.-)\r\n") do | |
152 startpos = (startpos or 1) + #line + 2; | |
153 local k, v = line:match("(%S+): (.+)"); | |
154 if k and v then | |
155 k = k:lower(); | |
156 if headers[k] then | |
157 headers[k] = headers[k]..", "..v; | |
158 else | |
159 headers[k] = v; | |
160 end | |
161 --log("debug", "Header: '"..k:lower().."' = '"..v.."'"); | |
162 elseif #line == 0 then | |
163 headers_complete = true; | |
164 break; | |
165 else | |
166 log("debug", "Unhandled header line: "..line); | |
167 end | |
168 end | |
169 | |
170 if not headers_complete then return; end | |
171 | |
172 if not expectbody(request) then | |
173 call_callback(request); | |
174 return; | |
175 end | |
176 | |
177 -- Reached the end of the headers | |
178 request.state = "body"; | |
179 if #data > startpos then | |
180 return request_reader(request, data:sub(startpos, -1)); | |
181 end | |
182 elseif request.state == "request" then | |
183 log("debug", "Reading request line...") | |
184 local method, path, http, linelen = data:match("^(%S+) (%S+) HTTP/(%S+)\r\n()", startpos); | |
185 if not method then | |
186 log("warn", "Invalid HTTP status line, telling callback then closing"); | |
187 local ret = call_callback(request, "invalid-status-line"); | |
188 request:destroy(); | |
189 return ret; | |
190 end | |
191 | |
192 request.method, request.path, request.httpversion = method, path, http; | |
193 | |
194 request.url = url_parse(request.path); | |
195 | |
196 log("debug", method.." request for "..tostring(request.path) .. " on port "..request.handler:serverport()); | |
197 | |
198 if request.onlystatus then | |
199 if not call_callback(request) then | |
200 return; | |
201 end | |
202 end | |
203 | |
204 request.state = "headers"; | |
205 | |
206 if #data > linelen then | |
207 return request_reader(request, data:sub(linelen, -1)); | |
208 end | |
209 end | |
210 end | 132 end |
211 | 133 |
212 -- The default handler for requests | 134 -- The default handler for requests |
213 default_handler = function (method, body, request) | 135 default_handler = function (method, body, request) |
214 log("debug", method.." request for "..tostring(request.path) .. " on port "..request.handler:serverport()); | 136 log("debug", method.." request for "..tostring(request.path) .. " on port "..request.handler:serverport()); |