From 4fdbf8f7f71bdadf9e938869b7d8b83e1767d415 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 14 Jan 2020 12:38:09 +0000 Subject: [PATCH] llow the request body to be processed outside the asynchttpserver library. Allow the request body to be processed outside the asynchttpserver library to break big files into chunks of data. This change does not break anything. Example: import asyncnet, asynchttpserver, asyncdispatch proc test_page(): string = return """
Test:
""" const chunkSize = 1024 var server = newAsyncHttpServer(maxBody=102400, handleBody=false) proc cb(req: Request) {.async.} = if req.reqMethod == HttpPost: var body = "" var remainder = req.content_length while remainder > 0: let data = await req.client.recv(if remainder < chunkSize: remainder else: chunkSize) if data.len == 0: break body.add(data) remainder -= data.len if body.len != req.contentLength: await req.respond(Http400, "Bad Request. Content-Length does not match actual.") else: await req.respond(Http200, body) # req.client.close() else: await req.respond(Http200, test_page()) waitFor server.serve(Port(8080), cb) --- lib/pure/asynchttpserver.nim | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 186f0da41465..93a3aaa55ac1 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -52,20 +52,23 @@ type url*: Uri hostname*: string ## The hostname of the client that made the request. body*: string + contentLength*: int AsyncHttpServer* = ref object socket: AsyncSocket reuseAddr: bool reusePort: bool maxBody: int ## The maximum content-length that will be read for the body. + handleBody: bool ## if false leave the body for the developer to do whatever he wants with it. proc newAsyncHttpServer*(reuseAddr = true, reusePort = false, - maxBody = 8388608): AsyncHttpServer = + maxBody = 8388608, handleBody = true): AsyncHttpServer = ## Creates a new ``AsyncHttpServer`` instance. new result result.reuseAddr = reuseAddr result.reusePort = reusePort result.maxBody = maxBody + result.handleBody = handleBody proc addHeaders(msg: var string, headers: HttpHeaders) = for k, v in headers: @@ -146,6 +149,7 @@ proc processRequest( # \n request.headers.clear() request.body = "" + request.contentLength = 0 request.hostname.shallowCopy(address) assert client != nil request.client = client @@ -243,10 +247,14 @@ proc processRequest( if contentLength > server.maxBody: await request.respondError(Http413) return false - request.body = await client.recv(contentLength) - if request.body.len != contentLength: - await request.respond(Http400, "Bad Request. Content-Length does not match actual.") - return true + + request.contentLength = contentLength + if server.handleBody == true: # if false leave the body for the developer to do whatever he wants with it. + request.body = await client.recv(contentLength) + if request.body.len != contentLength: + await request.respond(Http400, "Bad Request. Content-Length does not match actual.") + return true + elif request.reqMethod == HttpPost: await request.respond(Http411, "Content-Length required.") return true