forked from pgaertig/nginx-big-upload
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrc32.lua
57 lines (47 loc) · 1.59 KB
/
crc32.lua
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
-- Copyright (C) 2013 Piotr Gaertig
-- CRC32 checksum
local ffi = require('ffi')
local tonumber = tonumber
local string = string
local ngx = ngx
local table = table
module(...)
local zlib = ffi.load('z')
ffi.cdef[[
unsigned long crc32(unsigned long crc, const char *buf, unsigned len );
]]
function crc32(data, lastnum)
return tonumber(zlib.crc32(lastnum, data, #data))
end
function validhex(crchex) return #crchex <= 8 and string.match(crchex, "^%x+$") end
function tohex(crcnum) return string.format("%08.8x", crcnum) end
function crc32hex(data, last)
local lastnum = last and tonumber(last, 16) or 0
local currnum = crc32(data,lastnum)
return tohex(tonumber(currnum))
end
function handler()
return {
on_body_start = function (self, ctx)
ctx.current_checksum = ctx.last_checksum and tonumber(ctx.last_checksum, 16) or ( ctx.first_chunk and 0 )
-- stop checksum processing if X-Last-Checksum is not present for non first chunk
if not ctx.current_checksum then
self.on_body = nil
self.on_body_end = nil
end
end,
on_body = function (self, ctx, body)
ctx.current_checksum = crc32(body, ctx.current_checksum)
end,
on_body_end = function (self, ctx)
if ctx.checksum then
if tonumber(ctx.checksum,16) ~= ctx.current_checksum then
return {400, string.format("Chunk checksum mismatch client=[%s] server=[%s]", ctx.checksum, tohex(ctx.current_checksum))}
end
else
ctx.checksum = tohex(ctx.current_checksum)
end
if ctx.checksum then ngx.header['X-Checksum'] = ctx.checksum end
end
}
end