Skip to content

Instantly share code, notes, and snippets.

@zedeus
Last active September 16, 2018 00:21
Show Gist options
  • Save zedeus/22b187cab89e762cfd9ad3f90691cbb1 to your computer and use it in GitHub Desktop.
Save zedeus/22b187cab89e762cfd9ad3f90691cbb1 to your computer and use it in GitHub Desktop.
Hack to reduce memory overhead on httpclient post when sending files
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)
let
file = open(filePath)
fileSize = getFileSize(file)
clen = multipart.content[^1].len
multipart.content[^1].setLen(clen + fileSize)
var res = 1
while res > 0:
res = readBuffer(file, addr multipart.content[^1][clen], 0x100000)
file.close()
let
mpContentType = lightformat(multipart)
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