aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorV1K1NGbg <victor@ilchev.com>2024-08-22 17:48:56 -0300
committerHisham Muhammad <hisham@gobolinux.org>2024-10-21 13:30:51 -0300
commit1a93f626e6c0783b1a7e8a31650ca560f068c1b3 (patch)
treec10742fd4ef70ee6c8e397ecad9b6f7b505bb381 /src
parent8d1ef20f81f3014b4dd0dc38e246b91a18b51074 (diff)
downloadluarocks-1a93f626e6c0783b1a7e8a31650ca560f068c1b3.tar.gz
luarocks-1a93f626e6c0783b1a7e8a31650ca560f068c1b3.tar.bz2
luarocks-1a93f626e6c0783b1a7e8a31650ca560f068c1b3.zip
Teal: convert luarocks.upload.multipart
Diffstat (limited to 'src')
-rw-r--r--src/luarocks/upload/multipart.tl (renamed from src/luarocks/upload/multipart.lua)65
1 files changed, 37 insertions, 28 deletions
diff --git a/src/luarocks/upload/multipart.lua b/src/luarocks/upload/multipart.tl
index 790e368f..7fcf73b5 100644
--- a/src/luarocks/upload/multipart.lua
+++ b/src/luarocks/upload/multipart.tl
@@ -1,20 +1,31 @@
1 1
2local multipart = {} 2local record multipart
3 -- record Parameters
4 -- {{string, (string | File)}}
5 -- map: {string: (string | File)}
6 -- end
7 type Parameters = {string: (string | File)}
3 8
4local File = {} 9 record File
10 mimetype: string
11 fname: string
12 mime: function(File): string
13 end
14end
5 15
6local unpack = unpack or table.unpack 16local type Parameters = multipart.Parameters
17local type File = multipart.File
7 18
8-- socket.url.escape(s) from LuaSocket 3.0rc1 19-- socket.url.escape(s) from LuaSocket 3.0rc1 --?
9function multipart.url_escape(s) 20function multipart.url_escape(s: string): string
10 return (string.gsub(s, "([^A-Za-z0-9_])", function(c) 21 return (string.gsub(s, "([^A-Za-z0-9_])", function(c: string): string
11 return string.format("%%%02x", string.byte(c)) 22 return string.format("%%%02x", string.byte(c))
12 end)) 23 end))
13end 24end
14 25
15function File:mime() 26function multipart.File:mime(): string
16 if not self.mimetype then 27 if not self.mimetype then
17 local mimetypes_ok, mimetypes = pcall(require, "mimetypes") 28 local mimetypes_ok, mimetypes = pcall(require, "mimetypes")
18 if mimetypes_ok then 29 if mimetypes_ok then
19 self.mimetype = mimetypes.guess(self.fname) 30 self.mimetype = mimetypes.guess(self.fname)
20 end 31 end
@@ -23,7 +34,7 @@ function File:mime()
23 return self.mimetype 34 return self.mimetype
24end 35end
25 36
26function File:content() 37function multipart.File:content(): string, string
27 local fd = io.open(self.fname, "rb") 38 local fd = io.open(self.fname, "rb")
28 if not fd then 39 if not fd then
29 return nil, "Failed to open file: "..self.fname 40 return nil, "Failed to open file: "..self.fname
@@ -33,8 +44,8 @@ function File:content()
33 return data 44 return data
34end 45end
35 46
36local function rand_string(len) 47local function rand_string(len: integer): string
37 local shuffled = {} 48 local shuffled: {integer} = {}
38 for i = 1, len do 49 for i = 1, len do
39 local r = math.random(97, 122) 50 local r = math.random(97, 122)
40 if math.random() >= 0.5 then 51 if math.random() >= 0.5 then
@@ -42,7 +53,7 @@ local function rand_string(len)
42 end 53 end
43 shuffled[i] = r 54 shuffled[i] = r
44 end 55 end
45 return string.char(unpack(shuffled)) 56 return string.char(table.unpack(shuffled))
46end 57end
47 58
48-- multipart encodes params 59-- multipart encodes params
@@ -53,23 +64,20 @@ end
53-- {key2, value2}, 64-- {key2, value2},
54-- key3: value3 65-- key3: value3
55-- } 66-- }
56function multipart.encode(params) 67function multipart.encode(params: Parameters): string, string
57 local tuples = { } 68 local tuples: {{string, string | File}} = {}
58 for i = 1, #params do
59 tuples[i] = params[i]
60 end
61 for k,v in pairs(params) do 69 for k,v in pairs(params) do
62 if type(k) == "string" then 70 if k is string then
63 table.insert(tuples, {k, v}) 71 table.insert(tuples, {k, v})
64 end 72 end
65 end 73 end
66 local chunks = {} 74 local chunks: {string} = {}
67 for _, tuple in ipairs(tuples) do 75 for _, tuple in ipairs(tuples) do
68 local k,v = unpack(tuple) 76 local k,v = table.unpack(tuple)
69 k = multipart.url_escape(k) 77 k = multipart.url_escape(k)
70 local buffer = { 'Content-Disposition: form-data; name="' .. k .. '"' } 78 local buffer: {string} = { 'Content-Disposition: form-data; name="' .. k .. '"' }
71 local content 79 local content: string
72 if type(v) == "table" and v.__class == File then 80 if v is File then
73 buffer[1] = buffer[1] .. ('; filename="' .. v.fname:gsub(".*[/\\]", "") .. '"') 81 buffer[1] = buffer[1] .. ('; filename="' .. v.fname:gsub(".*[/\\]", "") .. '"')
74 table.insert(buffer, "Content-type: " .. v:mime()) 82 table.insert(buffer, "Content-type: " .. v:mime())
75 content = v:content() 83 content = v:content()
@@ -80,7 +88,7 @@ function multipart.encode(params)
80 table.insert(buffer, content) 88 table.insert(buffer, content)
81 table.insert(chunks, table.concat(buffer, "\r\n")) 89 table.insert(chunks, table.concat(buffer, "\r\n"))
82 end 90 end
83 local boundary 91 local boundary: string
84 while not boundary do 92 while not boundary do
85 boundary = "Boundary" .. rand_string(16) 93 boundary = "Boundary" .. rand_string(16)
86 for _, chunk in ipairs(chunks) do 94 for _, chunk in ipairs(chunks) do
@@ -96,12 +104,13 @@ function multipart.encode(params)
96 "\r\n", "--", boundary, "--", "\r\n" }), boundary 104 "\r\n", "--", boundary, "--", "\r\n" }), boundary
97end 105end
98 106
99function multipart.new_file(fname, mime) 107function multipart.new_file(fname: string, mime?: string): File
100 local self = {} 108 local self: File = {}
109
101 setmetatable(self, { __index = File }) 110 setmetatable(self, { __index = File })
102 self.__class = File 111
103 self.fname = fname 112 self.fname = fname
104 self.mimetype = mime 113 self.mimetype = mime
105 return self 114 return self
106end 115end
107 116