Giter VIP home page Giter VIP logo

lua-multipart's Introduction

lua-multipart Build Status

A Lua library to parse and edit multipart/form-data data.

Usage

local Multipart = require("multipart")

-- Initialize with a body
local multipart_data = Multipart(body, content_type_header)

-- Reading parameters
local parameter = multipart_data:get("param-name")

parameter.value -- The value
parameter.headers -- A table with the headers associated with the parameter

-- Reading all values of `files` part
local files = multipart_data:get_as_array("files")

-- Setting a new parameter
multipart_data:set_simple("some-param-name", "some-value")

-- Deleting a parameter
multipart_data:delete("param-name")

-- Setting a file
multipart_data:set_simple("name", "some-value", "filename", "content_type")

-- Get a multipart/form-data representation of the object
local body = multipart_data:tostring()

-- Get all the parameters in a Lua table, in the form of {param_name = param_value}
local t = multipart_data:get_all()

-- Get all the parameters in a Lua table, in the form of {param_name = param_value} where param_value is array
local t = multipart_data:get_all_as_arrays()

-- Get all the parameters in a Lua table, in the form of {param_name = param_value} where param_value is string or array
local t = multipart_data:get_all_with_arrays()

Contribute

This library is a work in progress, pull-requests are welcomed.

lua-multipart's People

Contributors

bungle avatar daurnimator avatar gszr avatar hishamhm avatar javierguerragiraldez avatar jayce avatar nikolaydubina avatar p0pr0ck5 avatar subnetmarco avatar tieske avatar zhucebuliaopx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lua-multipart's Issues

How to read this?

------WebKitFormBoundaryEnMb9LHcspOC97yv
Content-Disposition: form-data; name="address"

Idpetfectone
------WebKitFormBoundaryEnMb9LHcspOC97yv--

When the data is formData, the parsed out shows Instance of'FormData'

2020/06/26 22:52:45 [info] 30346#30346: *4239 [lua] Princopal.lua:17: RW1OO7hAfPHdavccK2XBWYBSEScWpHzsudt3Pwh0oFFu4oOFMHq05dxQmVq9s+/f8nSgQ77mjySe6RwgF3N93t5+2ifJtjCrKG7lFnIhSNN7w8FQ19L+ny/bzIOyHLH0K5PsgW4k17QNP79TH0XCTk4YHeG+45Decw8Zv3iBkEPCMqVy5ByuYmImpz3ln3u/FXNiKXsFogz59p7KRGhvB33RJ41VymWBfSN4K3ls9RjEj2KIj6mZ4+lMXn+R7bKhCpAdL8/axriezTII/2NkBnzuXXPHG2iAO1qtjOUQkS0DEfqS/d6rQxT42dUSsCu/zM3S3q3ENLULkKUWA+O6dA==, client: 121.32.48.11, request: "POST /Princopal HTTP/1.1",
2020/06/26 22:52:45 [info] 30346#30346: *4239 [lua] Princopal.lua:19: Instance of 'FormData', client: 121.32.48.11, request: "POST /Princopal HTTP/1.1",
local cjson = require "cjson.safe" --Json解析模块
local resty_rsa = require "resty.rsa" --对称加密解密模块
local Multipart = require("multipart") --解析fromData表单

local method = ngx.req.get_method() --获取是Get还是Post

local private_file = io.open("/Nginx/lua/flutter_private.pem", "r") --打开私匙文件
local private_Key = private_file:read("*a") --读取私钥内容
local priv = resty_rsa:new({private_key = private_Key, key_type = resty_rsa.KEY_TYPE.PKCS1}) --创建一个 对象

local head = ngx.req.get_headers() --获取请求头

if method == "POST" then --如果是Post的话
ngx.req.read_body() --读取Post_Body

local Encryptionbody = ngx.req.get_body_data() --获取消息体,此时是被加密的消息体
ngx.log(ngx.INFO, Encryptionbody)
local body = priv:decrypt(ngx.decode_base64(Encryptionbody)) --解析出来,此时是真正的消息
ngx.log(ngx.INFO, body)
if body == nil then
    ngx.exit(500)
end

local multipart_data = Multipart(body, head["content-type"])
body = multipart_data:tostring()
ngx.log(ngx.INFO, body)
--判断是Json格式还是其他的格式
-- local str = cjson.encode(priv:decrypt(ngx.decode_base64(body))) --解析消息体,然后转换为Json
if body then
    ngx.say(body)
end
ngx.exit(200)
end

if method == "GET" then
end

Can I set part header manually?

multipart_data:set_simple is useful, but I need a new method to upload file with header like:

--------------------------bd99c856fd831904
Content-Disposition: form-data; name="record"; filename="run_test.sh"
Content-Type: application/octet-stream

../../bin/lua run_test.lua $@

--------------------------bd99c856fd831904--

Any suggestions?

--WebKitFormBoundary how to get post data?

"------WebKitFormBoundaryOK7yAUgUbAlqyGG8
Content-Disposition: form-data; name="file"; filename="test.bin"
Content-Type: application/octet-stream

test!!!
------WebKitFormBoundaryOK7yAUgUbAlqyGG8--
"
How to get "test!!!"
Thanks.

File Format Change from csv to string while adding data in request body

I am adding one parameter in request body if POST request (Content-Type= "multipart-form/data") but after adding when i set edited body in kong request, file format changed from csv to string. Any suggestion?

Code:
local Multipart = require("multipart")
local multipart_data = Multipart(kong.request.get_raw_body(), kong.request.get_header("Content-Type"))
multipart_data["vendor"]="{ "vendorId" : "vicky", "vendorName" : "vicky" }"
kong.service.request.set_body(multipart_data)

Request Body:
Screenshot 2021-11-14 at 4 16 59 PM

get-value

Suggestion: A method to return the value directly instead of :get(xxx).value

I'd be willing to submit a PR if this is liked.

boundary not found in Content-Type: multipart/formdata

in function MultipartData.new(data, content_type), the boundary is searched by using the expression ";%s+boundary=(%S+)".

This works correctly for e.g. this Content-Type header:

Content-Type: multipart/form-data; boundary=AAAH...

But the whitespace after the semicolon is optional (and the pattern expects a whitespace). If the whitespace is not there, the field boundary is nil and parsing of the request will fail.

E.g. in when using Kong 0.8.3 with Oauth2 and a multipart upload, this fails as following:

share/lua/5.1/multipart.lua: in function 'decode'
share/lua/5.1/multipart.lua:112: in function 'Multipart'
share/lua/5.1/kong/plugins/oauth2/access.lua:93: in function 'retrieve_parameters'
share/lua/5.1/kong/plugins/oauth2/access.lua:359: in function 'parse_access_token'
share/lua/5.1/kong/plugins/oauth2/access.lua:412: in function 'execute'
share/lua/5.1/kong/plugins/oauth2/handler.lua:12: in function 'access'
share/lua/5.1/kong.lua:188: in function 'access'```

Solution: in multipart.lua:109 the value of boundary should also be found, if no whitespace is sent after the ; by the client in the value of the header Content-Type

multipart parsing could be hang

some specific request may cause is_header() hang on regex match for a very long time under 100% cpu usage.
This could be easily reproduced
s = (' '):rep(100000)..('a'):rep(100000);string.match(s, "(%S+):%s*(%S+)")

Are there any known bugs?

Hi!
Could you tell about your tests result, please?
Do your recommend your code for production usage?

Streaming API

Nick Message
daurn @thibaultcha: I don't see why we couldn't have a multipart library with a streaming api that doesn't depend on any openresty specific apis.
daurn @thibaultcha: did you read the irc transcript with furq?
daurn (oh: and it should have both multipart encode and decode)
thibaultcha @Daurn: I haven't read it, but I do agree that this should be totally feasable in an unopinonated streaming fashion
daurn thinking about decoding api: multipart/formdata can be nested
daurn I think there would be SAX-style 'pull' with events like "start of part" "part body chunk" "part body chunk" "end of part"
thibaultcha only I wonder, such an API would not be able to append or remove fields on the fly... Or would it?
thibaultcha Actually, it could, if the API handles it pre- encoding/decoding...
daurn @thibaultcha: there should be a streaming decoder and a streaming encoder. if you wanted to append/edit/remove then you'd have something in the middle there as a filter
thibaultcha yeah
thibaultcha that'd be nice
daurn @thibaultcha: how would you feel about doing this under the 'lua-multipart' project? as a new major version
daurn only thing is that I'd like to have the lua-http 'headers' object available
thibaultcha Any reason you see for wanting to stick under the lua-multipart project though? Just curious
thibaultcha Otherwise it'd be fine as a major version yeah
daurn @thibaultcha: well it's a nice succinct name ;)
thibaultcha Indeed

Boundary extraction does not strip quotes

Per https://tools.ietf.org/html/rfc2046#section-5.1.1 it is permissible and often necessary to enclose boundary strings in quotes, i.e. both the following are valid

Content-Type: multipart/form-data; boundary=6VDnJMUegpEalEvpihpZUgF0JbjBVVgDXb0aZQcw
Content-Type: multipart/form-data; boundary="6VDnJMUegpEalEvpihpZUgF0JbjBVVgDXb0aZQcw"

and should result in the boundary string 6VDnJMUegpEalEvpihpZUgF0JbjBVVgDXb0aZQcw.

Currently, lua-multipart extracts the boundary string using this:

instance._boundary = match(content_type, ";%s*boundary=(%S+)")

which will attempt to use quotes as part of the boundary. An HTTP request like this will not parse successfully, as there are no quotes present in boundary in the body:

POST /test HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary="6VDnJMUegpEalEvpihpZUgF0JbjBVVgDXb0aZQcw"

foo

--6VDnJMUegpEalEvpihpZUgF0JbjBVVgDXb0aZQcw
Content-Type: text/plain; charset="utf-8"
Content-disposition: form-data; name="api_key"

c63211ec-2157-4c35-8c38-2d9584bbee15
--6VDnJMUegpEalEvpihpZUgF0JbjBVVgDXb0aZQcw
Content-Type: text/plain; charset="utf-8"
Content-disposition: form-data; name="username"

popuko

file decode failed

I tried to decode the multipart encoded file and form data on my server
for the text format file , the lines with only \r\n are lost
for the binary format file , the file is damaged

Is this parser can only be used for multipart/form-data encoded form data ? what about file ?

Empty string was printed after tostring() call

example.txt
Hi!
My file example.txt is attached.

local Multipart = require("multipart")
local io = require("io")
local open = io.open
local function read_file(path)
    local file = open(path, "r")
    if not file then return nil end
    local content = file:read "*a"
    file:close()
    return content
end
local body = read_file("example.txt");
local multipart_data = Multipart(body, "text/html")
local t = multipart_data:tostring()
print (t)

This code prints empty line. What's wrong? Please, explain it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.