-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrequest.lua
More file actions
97 lines (91 loc) · 2.14 KB
/
request.lua
File metadata and controls
97 lines (91 loc) · 2.14 KB
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
local M = {}; M.__index = M
local function construct(socket)
local self = setmetatable({
cli_headers = {},
test='test'
}, M)
self.lines = {}
self.data = ''
return self
end
setmetatable(M, {__call = construct})
function M:parse_request_line(line)
if not self.method then
_,_,self.method,self.uri,self.proto = line:find('^([A-Z]*) ([^ ]*) (HTTP/1.%d)$')
if self.method then
self.request_line = line
if self.proto and self.proto ~= 'HTTP/1.0' then
self.socket:write('HTTP/1.1 100 Continue\r\n\r\n')
end
return true
else
-- HTTP/1.0 maybe?
_,_,self.method,self.uri = string.find(line, '^([A-Z]*) ([^ ]*)$')
if not self.method then
-- Nope, just bad
log('Bad request')
buzz.error(self, 400, '')
return nil
else
self.request_line = line
self.proto = 'HTTP/1.0'
return true
end
end
else
log('Already parsed request line')
return nil
end
end
function M:parse_request()
local lines = self.lines
if #lines == 0 then
return false
end
if not self:parse_request_line(self.lines[1]) then
return false
end
for l=2,#lines do
local _,_, header, value = string.find(lines[l], '([^:]*): (.*)')
if header then
self.cli_headers[header:lower()] = value
else
log('error parsing header '..lines[l])
return false
end
end
self.valid = true
return true
end
function M:check_data_complete()
if not self.cli_headers['content-length'] then
return true
end
if #self.data >= tonumber(self.cli_headers['content-length']) then
self.data_complete = true
end
return self.data_complete
end
function M:add_data(buf)
self.data = self.data .. buf
if self.headers_complete then
self:check_data_complete()
elseif not self.headers_complete then
repeat
local pos = string.find(self.data, '\r\n')
if pos then
if pos == 1 then
self.headers_complete = true
self:parse_request()
self.data = self.data:sub(pos + 2)
self:check_data_complete()
return;
elseif not self.headers_complete then
self.lines[#self.lines + 1] = self.data:sub(1, pos - 1)
self.data = self.data:sub(pos + 2)
end
end
until not pos
end
end
return M