Software /
code /
prosody
Annotate
util/httpstream.lua @ 3496:9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Fri, 17 Sep 2010 03:52:11 +0500 |
parent | 3495:bd7699a6d536 |
child | 3562:98f9dca3eb94 |
rev | line source |
---|---|
3494
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
1 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
2 local coroutine = coroutine; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
3 local tonumber = tonumber; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
4 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
5 local deadroutine = coroutine.create(function() end); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
6 coroutine.resume(deadroutine); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
7 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
8 module("httpstream") |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
9 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
10 local function parser(data, success_cb) |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
11 local function readline() |
3496
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
12 local pos = data:find("\r\n", nil, true); |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
13 while not pos do |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
14 data = data..coroutine.yield(); |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
15 pos = data:find("\r\n", nil, true); |
3494
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
16 end |
3496
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
17 local r = data:sub(1, pos-1); |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
18 data = data:sub(pos+2); |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
19 return r; |
3494
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
20 end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
21 local function readlength(n) |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
22 while #data < n do |
3496
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
23 data = data..coroutine.yield(); |
3494
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
24 end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
25 local r = data:sub(1, n); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
26 data = data:sub(n + 1); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
27 return r; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
28 end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
29 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
30 while true do |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
31 -- read status line |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
32 local status_line = readline(); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
33 local method, path, httpversion = status_line:match("^(%S+)%s+(%S+)%s+HTTP/(%S+)$"); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
34 if not method then coroutine.yield("invalid-status-line"); end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
35 -- TODO parse url |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
36 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
37 local headers = {}; -- read headers |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
38 while true do |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
39 local line = readline(); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
40 if line == "" then break; end -- headers done |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
41 local key, val = line:match("^([^%s:]+): *(.*)$"); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
42 if not key then coroutine.yield("invalid-header-line"); end -- TODO handle multi-line and invalid headers |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
43 key = key:lower(); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
44 headers[key] = headers[key] and headers[key]..","..val or val; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
45 end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
46 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
47 -- read body |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
48 local len = tonumber(headers["content-length"]); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
49 len = len or 0; -- TODO check for invalid len |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
50 local body = readlength(len); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
51 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
52 success_cb({ |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
53 method = method; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
54 path = path; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
55 httpversion = httpversion; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
56 headers = headers; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
57 body = body; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
58 }); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
59 end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
60 end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
61 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
62 function new(success_cb, error_cb) |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
63 local co = coroutine.create(parser); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
64 return { |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
65 feed = function(self, data) |
3496
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
66 if not data then |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
67 co = deadroutine; |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
68 return error_cb(); |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
69 end |
3494
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
70 local success, result = coroutine.resume(co, data, success_cb); |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
71 if result then |
3496
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
72 co = deadroutine; |
9408d1e10e17
util.httpstream: Refactored and simplified code to improve readability.
Waqas Hussain <waqas20@gmail.com>
parents:
3495
diff
changeset
|
73 return error_cb(result); |
3494
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
74 end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
75 end; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
76 }; |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
77 end |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
78 |
0f185563a4e4
util.httpstream: Initial commit of the new HTTP parser.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
79 return _M; |