mirror of
				https://github.com/lunarmodules/luasocket.git
				synced 2025-10-31 02:15:38 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			300 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			300 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local socket = require("socket")
 | ||
| local ltn12 = require("ltn12")
 | ||
| local mime = require("mime")
 | ||
| 
 | ||
| local unpack = unpack or table.unpack
 | ||
| 
 | ||
| dofile("testsupport.lua")
 | ||
| 
 | ||
| local qptest = "qptest.bin"
 | ||
| local eqptest = "qptest.bin2"
 | ||
| local dqptest = "qptest.bin3"
 | ||
| 
 | ||
| local b64test = "b64test.bin"
 | ||
| local eb64test = "b64test.bin2"
 | ||
| local db64test = "b64test.bin3"
 | ||
| 
 | ||
| 
 | ||
| -- from Machado de Assis, "A M<>o e a Rosa"
 | ||
| local mao = [[
 | ||
|     Cursavam estes dois mo<6D>os a academia de S. Paulo, estando
 | ||
|     Lu<4C>s Alves no quarto ano e Est<73>v<EFBFBD>o no terceiro.
 | ||
|     Conheceram-se na academia, e ficaram amigos <20>ntimos, tanto
 | ||
|     quanto podiam s<>-lo dois esp<73>ritos diferentes, ou talvez por
 | ||
|     isso mesmo que o eram. Est<73>v<EFBFBD>o, dotado de extrema
 | ||
|     sensibilidade, e n<>o menor fraqueza de <20>nimo, afetuoso e
 | ||
|     bom, n<>o daquela bondade varonil, que <20> apan<61>gio de uma alma
 | ||
|     forte, mas dessa outra bondade mole e de cera, que vai <20>
 | ||
|     merc<72> de todas as circunst<73>ncias, tinha, al<61>m de tudo isso,
 | ||
|     o infort<72>nio de trazer ainda sobre o nariz os <20>culos
 | ||
|     cor-de-rosa de suas virginais ilus<75>es. Lu<4C>s Alves via bem
 | ||
|     com os olhos da cara. N<>o era mau rapaz, mas tinha o seu
 | ||
|     gr<67>o de ego<67>smo, e se n<>o era incapaz de afei<65><69>es, sabia
 | ||
|     reg<65>-las, moder<65>-las, e sobretudo gui<75>-las ao seu pr<70>prio
 | ||
|     interesse.  Entre estes dois homens travara-se amizade
 | ||
|     <20>ntima, nascida para um na simpatia, para outro no costume.
 | ||
|     Eram eles os naturais confidentes um do outro, com a
 | ||
|     diferen<65>a que Lu<4C>s Alves dava menos do que recebia, e, ainda
 | ||
|     assim, nem tudo o que dava exprimia grande confian<61>a.
 | ||
| ]]
 | ||
| 
 | ||
| local function random(handle, io_err)
 | ||
|     if handle then
 | ||
|         return function()
 | ||
|             if not handle then error("source is empty!", 2) end
 | ||
|             local len = math.random(0, 1024)
 | ||
|             local chunk = handle:read(len)
 | ||
|             if not chunk then
 | ||
|                 handle:close()
 | ||
|                 handle = nil
 | ||
|             end
 | ||
|             return chunk
 | ||
|         end
 | ||
|     else return ltn12.source.empty(io_err or "unable to open file") end
 | ||
| end
 | ||
| 
 | ||
| 
 | ||
| local function named(f)
 | ||
|     return f
 | ||
| end
 | ||
| 
 | ||
| local what = nil
 | ||
| local function transform(input, output, filter)
 | ||
|     local source = random(io.open(input, "rb"))
 | ||
|     local sink = ltn12.sink.file(io.open(output, "wb"))
 | ||
|     if what then
 | ||
|         sink = ltn12.sink.chain(filter, sink)
 | ||
|     else
 | ||
|         source = ltn12.source.chain(source, filter)
 | ||
|     end
 | ||
|     --what = not what
 | ||
|     ltn12.pump.all(source, sink)
 | ||
| end
 | ||
| 
 | ||
| local function encode_qptest(mode)
 | ||
|     local encode = mime.encode("quoted-printable", mode)
 | ||
|     local split = mime.wrap("quoted-printable")
 | ||
|     local chain = ltn12.filter.chain(encode, split)
 | ||
|     transform(qptest, eqptest, chain)
 | ||
| end
 | ||
| 
 | ||
| local function compare_qptest()
 | ||
| io.write("testing qp encoding and wrap: ")
 | ||
|     compare(qptest, dqptest)
 | ||
| end
 | ||
| 
 | ||
| local function decode_qptest()
 | ||
|     local decode = mime.decode("quoted-printable")
 | ||
|     transform(eqptest, dqptest, decode)
 | ||
| end
 | ||
| 
 | ||
| local function create_qptest()
 | ||
|     local f, err = io.open(qptest, "wb")
 | ||
|     if not f then fail(err) end
 | ||
|     -- try all characters
 | ||
|     for i = 0, 255 do
 | ||
|         f:write(string.char(i))
 | ||
|     end
 | ||
|     -- try all characters and different line sizes
 | ||
|     for i = 0, 255 do
 | ||
|         for j = 0, i do
 | ||
|             f:write(string.char(i))
 | ||
|         end
 | ||
|         f:write("\r\n")
 | ||
|     end
 | ||
|     -- test latin text
 | ||
|     f:write(mao)
 | ||
|     -- force soft line breaks and treatment of space/tab in end of line
 | ||
|     local tab
 | ||
|     f:write(string.gsub(mao, "(%s)", function(c)
 | ||
|         if tab then
 | ||
|             tab = nil
 | ||
|             return "\t"
 | ||
|         else
 | ||
|             tab = 1
 | ||
|             return " "
 | ||
|         end
 | ||
|     end))
 | ||
|     -- test crazy end of line conventions
 | ||
|     local eol = { "\r\n", "\r", "\n", "\n\r" }
 | ||
|     local which = 0
 | ||
|     f:write(string.gsub(mao, "(\n)", function(c)
 | ||
|         which = which + 1
 | ||
|         if which > 4 then which = 1 end
 | ||
|         return eol[which]
 | ||
|     end))
 | ||
|     for i = 1, 4 do
 | ||
|         for j = 1, 4 do
 | ||
|             f:write(eol[i])
 | ||
|             f:write(eol[j])
 | ||
|         end
 | ||
|     end
 | ||
|     -- try long spaced and tabbed lines
 | ||
|     f:write("\r\n")
 | ||
|     for i = 0, 255 do
 | ||
|         f:write(string.char(9))
 | ||
|     end
 | ||
|     f:write("\r\n")
 | ||
|     for i = 0, 255 do
 | ||
|         f:write(' ')
 | ||
|     end
 | ||
|     f:write("\r\n")
 | ||
|     for i = 0, 255 do
 | ||
|         f:write(string.char(9),' ')
 | ||
|     end
 | ||
|     f:write("\r\n")
 | ||
|     for i = 0, 255 do
 | ||
|         f:write(' ',string.char(32))
 | ||
|     end
 | ||
|     f:write("\r\n")
 | ||
| 
 | ||
|     f:close()
 | ||
| end
 | ||
| 
 | ||
| local function cleanup_qptest()
 | ||
|     os.remove(qptest)
 | ||
|     os.remove(eqptest)
 | ||
|     os.remove(dqptest)
 | ||
| end
 | ||
| 
 | ||
| -- create test file
 | ||
| local function create_b64test()
 | ||
|     local f = assert(io.open(b64test, "wb"))
 | ||
|     local t = {}
 | ||
|     for j = 1, 100 do
 | ||
|         for i = 1, 100 do
 | ||
|             t[i] = math.random(0, 255)
 | ||
|         end
 | ||
|         f:write(string.char(unpack(t)))
 | ||
|     end
 | ||
|     f:close()
 | ||
| end
 | ||
| 
 | ||
| local function encode_b64test()
 | ||
|     local e1 = mime.encode("base64")
 | ||
|     local e2 = mime.encode("base64")
 | ||
|     local e3 = mime.encode("base64")
 | ||
|     local e4 = mime.encode("base64")
 | ||
|     local sp4 = mime.wrap()
 | ||
|     local sp3 = mime.wrap(59)
 | ||
|     local sp2 = mime.wrap("base64", 30)
 | ||
|     local sp1 = mime.wrap(27)
 | ||
|     local chain = ltn12.filter.chain(e1, sp1, e2, sp2, e3, sp3, e4, sp4)
 | ||
|     transform(b64test, eb64test, chain)
 | ||
| end
 | ||
| 
 | ||
| local function decode_b64test()
 | ||
|     local d1 = named(mime.decode("base64"), "d1")
 | ||
|     local d2 = named(mime.decode("base64"), "d2")
 | ||
|     local d3 = named(mime.decode("base64"), "d3")
 | ||
|     local d4 = named(mime.decode("base64"), "d4")
 | ||
|     local chain = named(ltn12.filter.chain(d1, d2, d3, d4), "chain")
 | ||
|     transform(eb64test, db64test, chain)
 | ||
| end
 | ||
| 
 | ||
| local function cleanup_b64test()
 | ||
|     os.remove(b64test)
 | ||
|     os.remove(eb64test)
 | ||
|     os.remove(db64test)
 | ||
| end
 | ||
| 
 | ||
| local function compare_b64test()
 | ||
| io.write("testing b64 chained encode: ")
 | ||
|     compare(b64test, db64test)
 | ||
| end
 | ||
| 
 | ||
| local function identity_test()
 | ||
| io.write("testing identity: ")
 | ||
|     local chain = named(ltn12.filter.chain(
 | ||
|         named(mime.encode("quoted-printable"), "1 eq"),
 | ||
|         named(mime.encode("base64"), "2 eb"),
 | ||
|         named(mime.decode("base64"), "3 db"),
 | ||
|         named(mime.decode("quoted-printable"), "4 dq")
 | ||
|     ), "chain")
 | ||
|     transform(b64test, eb64test, chain)
 | ||
|     compare(b64test, eb64test)
 | ||
|     os.remove(eb64test)
 | ||
| end
 | ||
| 
 | ||
| 
 | ||
| local function padcheck(original, encoded)
 | ||
|     local e = (mime.b64(original))
 | ||
|     local d = (mime.unb64(encoded))
 | ||
|     if e ~= encoded then fail("encoding failed") end
 | ||
|     if d ~= original then fail("decoding failed") end
 | ||
| end
 | ||
| 
 | ||
| local function chunkcheck(original, encoded)
 | ||
|     local len = string.len(original)
 | ||
|     for i = 0, len do
 | ||
|         local a = string.sub(original, 1, i)
 | ||
|         local b = string.sub(original, i+1)
 | ||
|         local e, r = mime.b64(a, b)
 | ||
|         local f = (mime.b64(r))
 | ||
|         if (e .. (f or "") ~= encoded) then fail(e .. (f or "")) end
 | ||
|     end
 | ||
| end
 | ||
| 
 | ||
| local function padding_b64test()
 | ||
| io.write("testing b64 padding: ")
 | ||
|     padcheck("a", "YQ==")
 | ||
|     padcheck("ab", "YWI=")
 | ||
|     padcheck("abc", "YWJj")
 | ||
|     padcheck("abcd", "YWJjZA==")
 | ||
|     padcheck("abcde", "YWJjZGU=")
 | ||
|     padcheck("abcdef", "YWJjZGVm")
 | ||
|     padcheck("abcdefg", "YWJjZGVmZw==")
 | ||
|     padcheck("abcdefgh", "YWJjZGVmZ2g=")
 | ||
|     padcheck("abcdefghi", "YWJjZGVmZ2hp")
 | ||
|     padcheck("abcdefghij", "YWJjZGVmZ2hpag==")
 | ||
|     chunkcheck("abcdefgh", "YWJjZGVmZ2g=")
 | ||
|     chunkcheck("abcdefghi", "YWJjZGVmZ2hp")
 | ||
|     chunkcheck("abcdefghij", "YWJjZGVmZ2hpag==")
 | ||
|     print("ok")
 | ||
| end
 | ||
| 
 | ||
| local function test_b64lowlevel()
 | ||
| io.write("testing b64 low-level: ")
 | ||
|     local a, b
 | ||
|     a, b = mime.b64("", "")
 | ||
|     assert(a == "" and b == "")
 | ||
|     a, b = mime.b64(nil, "blablabla")
 | ||
|     assert(a == nil and b == nil)
 | ||
|     a, b = mime.b64("", nil)
 | ||
|     assert(a == nil and b == nil)
 | ||
|     a, b = mime.unb64("", "")
 | ||
|     assert(a == "" and b == "")
 | ||
|     a, b = mime.unb64(nil, "blablabla")
 | ||
|     assert(a == nil and b == nil)
 | ||
|     a, b = mime.unb64("", nil)
 | ||
|     assert(a == nil and b == nil)
 | ||
|     local binary=string.char(0x00,0x44,0x1D,0x14,0x0F,0xF4,0xDA,0x11,0xA9,0x78,0x00,0x14,0x38,0x50,0x60,0xCE)
 | ||
|     local encoded = mime.b64(binary)
 | ||
|     local decoded=mime.unb64(encoded)
 | ||
|     assert(binary == decoded)
 | ||
|     print("ok")
 | ||
| end
 | ||
| 
 | ||
| local t = socket.gettime()
 | ||
| 
 | ||
| create_b64test()
 | ||
| identity_test()
 | ||
| encode_b64test()
 | ||
| decode_b64test()
 | ||
| compare_b64test()
 | ||
| cleanup_b64test()
 | ||
| padding_b64test()
 | ||
| test_b64lowlevel()
 | ||
| 
 | ||
| create_qptest()
 | ||
| encode_qptest()
 | ||
| decode_qptest()
 | ||
| compare_qptest()
 | ||
| encode_qptest("binary")
 | ||
| decode_qptest()
 | ||
| compare_qptest()
 | ||
| cleanup_qptest()
 | ||
| 
 | ||
| 
 | ||
| print(string.format("done in %.2fs", socket.gettime() - t))
 |