Skip to content

Instantly share code, notes, and snippets.

@zedeus
Created September 11, 2018 02:14
Show Gist options
  • Save zedeus/38eae7ceeebbe81aaecd9b96f36ffa63 to your computer and use it in GitHub Desktop.
Save zedeus/38eae7ceeebbe81aaecd9b96f36ffa63 to your computer and use it in GitHub Desktop.
Hack to reduce memory overhead when sending a file via post
proc lightformat(p: var MultipartData): string =
if p == nil or p.content.len == 0:
return
# Create boundary that is not in the data to be formatted
var bound: string
while true:
bound = $random(int.high)
var found = false
for s in p.content:
if bound in s:
found = true
if not found:
break
result = "multipart/form-data; boundary=" & bound
for i in 0 ..< p.content.len:
p.content[i] = "--" & bound & "\c\L" & p.content[i] & "\c\L"
p.content.add("--" & bound & "--\c\L")
proc postFile*(client: HttpClient, url: string, filePath: string, name: string,
multipart: var MultipartData): Response =
var m = newMimetypes()
var contentType: string
let (_, fName, ext) = splitFile(filePath)
if ext.len > 0:
contentType = m.getMimetype(ext[1..ext.high], "")
## similar behaviour to the addFiles proc
var str = "Content-Disposition: form-data; name=\"" & name &
"\";filename=\"" & fName & ext &
"\"\c\LContent-Type: " & contentType & "\c\L\c\L"
multipart.content.add(str)
multipart.content[^1] &= readFile(filePath)
## `str & readFile(..)` allocates the contents twice
let mpContentType = lightformat(multipart)
let xb = multipart.content.join("")
var headers = newHttpHeaders()
if multipart != nil:
headers["Content-Type"] = mpContentType
headers["Content-Length"] = $len(xb)
result = client.requestAux(url, $HttpPOST, xb, headers)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment