Skip to content

Commit

Permalink
fix(form): fix binary multipart-form-data
Browse files Browse the repository at this point in the history
  • Loading branch information
gorillamoe committed Sep 10, 2024
1 parent 37977a4 commit 806d1bd
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 2 deletions.
33 changes: 33 additions & 0 deletions docs/docs/usage/sending-form-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,36 @@ name={{name}}&
age={{age}}
```

## Sending multipart form data

You can send multipart form data in Kulala by using the `multipart/form-data` content type.

```http title="multipart.http"
# @file-to-variable LOGO_FILE_VAR ./../../logo.png
POST https://httpbin.org/post HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{$timestamp}}
------WebKitFormBoundary{{$timestamp}}
Content-Disposition: form-data; name="logo"; filename="logo.png"
Content-Type: image/jpeg
{{LOGO_FILE_VAR}}
------WebKitFormBoundary{{$timestamp}}
Content-Disposition: form-data; name="x"
0
------WebKitFormBoundary{{$timestamp}}
Content-Disposition: form-data; name="y"
1.4333333333333333
------WebKitFormBoundary{{$timestamp}}
Content-Disposition: form-data; name="w"
514.5666666666667
------WebKitFormBoundary{{$timestamp}}
Content-Disposition: form-data; name="h"
514.5666666666667
------WebKitFormBoundary{{$timestamp}}--
```
10 changes: 8 additions & 2 deletions lua/kulala/parser/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ local function extend_document_variables(document_variables, request)
local kv = vim.split(metadata.value, " ")
local variable_name = kv[1]
local file_path = kv[2]
file_path = FS.get_file_path(file_path)
local file_contents = FS.read_file(file_path)
if file_contents then
document_variables[variable_name] = file_contents
Expand Down Expand Up @@ -574,8 +575,13 @@ function M.parse(start_request_linenr)
res.headers["content-type"] = "application/json"
end
elseif res.headers["content-type"]:find("^multipart/form%-data") then
table.insert(res.cmd, "--data-binary")
table.insert(res.cmd, res.body)
local tmp_file = FS.get_binary_temp_file(res.body)
if tmp_file ~= nil then
table.insert(res.cmd, "--data-binary")
table.insert(res.cmd, "@" .. tmp_file)
else
Logger.error("Failed to create a temporary file for the binary request body")
end
else
table.insert(res.cmd, "--data")
table.insert(res.cmd, res.body)
Expand Down
32 changes: 32 additions & 0 deletions lua/kulala/utils/fs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,27 @@ M.join_paths = function(...)
return table.concat({ ... }, M.ps)
end

---Returns true if the path is absolute, false otherwise
M.is_absolute_path = function(path)
if path:match("^/") or path:match("^%a:\\") then
return true
end
return false
end

---Either returns the absolute path if the path is already absolute or
---joins the path with the current buffer directory
M.get_file_path = function(path)
if M.is_absolute_path(path) then
return path
end
local buffer_dir = vim.fn.expand("%:p:h")
if path:sub(1, 2) == "./" or path:sub(1, 2) == ".\\" then
path = path:sub(3)
end
return M.join_paths(buffer_dir, path)
end

-- This is mainly used for determining if the current buffer is a non-http file
-- and therefore maybe we need to parse a fenced code block
M.is_non_http_file = function()
Expand Down Expand Up @@ -232,6 +253,17 @@ M.read_file = function(filename)
return content
end

M.get_binary_temp_file = function(content)
local tmp_file = vim.fn.tempname()
local f = io.open(tmp_file, "wb")
if f == nil then
return nil
end
f:write(content)
f:close()
return tmp_file
end

---Read file lines
---@param filename string
---@return string[]
Expand Down

0 comments on commit 806d1bd

Please sign in to comment.