* libs/core: Moved ltn12 inside LuCI to avoid package conflicts with luasocket
[project/luci.git] / libs / http / luasrc / http / protocol / filter.lua
1 --[[
2
3 HTTP protocol implementation for LuCI - filter implementation
4 (c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
5
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
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 $Id$
13
14 ]]--
15
16 module("luci.http.protocol.filter", package.seeall)
17
18 local ltn12 = require("luci.ltn12")
19
20
21 -- Factory that produces a filter which normalizes chunked transfer encoding
22 function decode_chunked()
23
24 local length = 0
25 local read = 0
26
27 return ltn12.filter.cycle(
28 function( chunk, ctx )
29
30 if chunk ~= nil then
31
32 -- EOF
33 if ctx == nil then
34 if ( length - read ) > 0 then
35 return nil, "Unexpected EOF"
36 else
37 return ""
38 end
39 end
40
41 chunk = ctx .. chunk
42
43 local buf = ""
44 while true do
45
46 if read == length then
47
48 -- Find chunk length indicator
49 local spos, epos = chunk:find("^\r?\n?[a-fA-F0-9]+ *\r\n")
50 if spos and spos == 1 then
51 read = 0
52 length = tonumber(
53 chunk:sub( 1, epos ):gsub( "[^a-fA-F0-9]", "" ), 16
54 )
55
56 -- Check for end of chunk
57 if length > 0 then
58 chunk = chunk:sub( epos + 1, #chunk )
59 else
60 return buf, ""
61 end
62 else
63 return "", nil
64 end
65 else
66 if ( read + #chunk ) <= length then
67 read = read + #chunk
68 return buf .. chunk, ""
69 else
70 local rest = length - read
71 read = read + rest
72 buf = buf .. chunk:sub( 1, rest )
73 chunk = chunk:sub( rest + 1, #chunk )
74 end
75 end
76 end
77 end
78 end,
79 ""
80 )
81 end