I was having problems using an API to upload a file with network.request. I studied the forum posts in this area and went deeper into http.request from the socket library. I am using class_MultipartFormData.lua which shows up in several forum posts. I’ll describe a test case here to demonstrate the isue, with full code further below. Maybe it will ring a bell with someone. If I can get some understanding around this, then I can return to the Corona version of network.request.
I have a curl command to upload “Icon.png” that I run against https://postman-echo.com/post.
curl -F "file=@Icon.png" https://postman-echo.com/post
To get an equivalent Lua request, I can set up class_MultipartFormData and run
-- full example below local data = mp:getBody() local headers = mp:getHeaders() print(data)
to get the same base64 string that I see in the curl response from the echo server. However, when I run the http.request I get a different base64 string from the echo server. When I decode that string, then I get the string that was submitted by curl. So, it appears that the body is encoded by class_MultipartFormData, then it is encoded again at some point later.
To verify this, if I change class_MultipartFormData to comment out
ltn12.filter.chain(mime.encode(el.encoding), mime.wrap())
in the definition of fileSource (at about line 108), then I can get the same response from the echo server (getting exactly the same response takes a little bit more editing of class_MultipartFormData, but for the example here, this is the primary edit).
Again, this shows that my body string is being base64 encoded somewhere after the print statement, which as far as I can tell must be in either http.request or in ltn12.source.string. If that is true, I don’t see it documented anywhere and I haven’t yet found it in the source. So, that is the question: Do I need to change class_MultipartFormData to allow for “raw” data, or is there a way to tell http.request to leave the body alone and not to further encode it?
I realize that this isn’t directly related to the Corona network library, but I have seen several variations of this issue on the forums with “corrupted” files after upload that I think might be tied to this issue. The primary test that I haven’t done yet to to run this on a lua system outside the Corona Simulator.
Here is the code to run the case. The boundary comes from looking at the output of the curl command to the echo server.
local http = require("socket.http") local ltn12 = require("ltn12") local MultipartFormData = require("class\_MultipartFormData") local mp = MultipartFormData.new() mp:setBoundry("------------------------d413857e969e2679") mp:addFile("file", system.pathForFile( "Icon.png", system.ResourcesDirectory ), "image/png", "Icon.png") local data = mp:getBody() local headers = mp:getHeaders() print(data) -- this is the same as the curl version of the body local url = "https://postman-echo.com/post" local resp = {} local res, err = http.request({ url = url, method = 'POST', headers = headers, sink = ltn12.sink.table(resp), source = ltn12.source.string(data) }) if res then print(table.concat(resp)) else print(err) end -- the base64 encoding of Icon.png that is sent to the server is different -- than that printed by the previous print statement. In fact, if you decode the -- base64 string in this result, you will get the same that that was printed by -- the previous print statement