mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-13 06:43:52 +00:00
Add support for Transfer-Encoding: chunked (#16636)
* Add support for Transfer-Encoding: chunked * Minor whitespace fixes * Use recv instead of recvLineInto * Undo changes to httpcore, inline changes
This commit is contained in:
@@ -142,6 +142,17 @@ proc parseProtocol(protocol: string): tuple[orig: string, major, minor: int] =
|
||||
proc sendStatus(client: AsyncSocket, status: string): Future[void] =
|
||||
client.send("HTTP/1.1 " & status & "\c\L\c\L")
|
||||
|
||||
func hasChunkedEncoding(request: Request): bool =
|
||||
## Searches for a chunked transfer encoding
|
||||
const transferEncoding = "Transfer-Encoding"
|
||||
|
||||
if request.headers.hasKey(transferEncoding):
|
||||
for encoding in seq[string](request.headers[transferEncoding]):
|
||||
if "chunked" == encoding.strip:
|
||||
# Returns true if it is both an HttpPost and has chunked encoding
|
||||
return request.reqMethod == HttpPost
|
||||
return false
|
||||
|
||||
proc processRequest(
|
||||
server: AsyncHttpServer,
|
||||
req: FutureVar[Request],
|
||||
@@ -261,6 +272,39 @@ proc processRequest(
|
||||
if request.body.len != contentLength:
|
||||
await request.respond(Http400, "Bad Request. Content-Length does not match actual.")
|
||||
return true
|
||||
elif hasChunkedEncoding(request):
|
||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding
|
||||
var sizeOrData = 0
|
||||
var bytesToRead = 0
|
||||
request.body = ""
|
||||
|
||||
while true:
|
||||
lineFut.mget.setLen(0)
|
||||
lineFut.clean()
|
||||
|
||||
# The encoding format alternates between specifying a number of bytes to read
|
||||
# and the data to be read, of the previously specified size
|
||||
if sizeOrData mod 2 == 0:
|
||||
# Expect a number of chars to read
|
||||
await client.recvLineInto(lineFut, maxLength = maxLine)
|
||||
try:
|
||||
bytesToRead = lineFut.mget.parseHexInt
|
||||
except ValueError:
|
||||
# Malformed request
|
||||
await request.respond(Http411, ("Invalid chunked transfer encoding - " &
|
||||
"chunk data size must be hex encoded"))
|
||||
return true
|
||||
else:
|
||||
if bytesToRead == 0:
|
||||
# Done reading chunked data
|
||||
break
|
||||
|
||||
# Read bytesToRead and add to body
|
||||
# Note we add +2 because the line must be terminated by \r\n
|
||||
let chunk = await client.recv(bytesToRead + 2)
|
||||
request.body = request.body & chunk
|
||||
|
||||
inc sizeOrData
|
||||
elif request.reqMethod == HttpPost:
|
||||
await request.respond(Http411, "Content-Length required.")
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user