Added a basic example how to handle a Post request. (#13339)
* Added a basic example how to handle a Post request. They were also made minor cosmetic changes. * Minor fixes suggested by Yardanico * Fixed a wrong value in chunkSize constant. * Re-added the request.body for compatibility!
This commit is contained in:
parent
bf3f1c3762
commit
abd660c407
1 changed files with 55 additions and 3 deletions
|
|
@ -29,6 +29,54 @@
|
||||||
## await req.respond(Http200, "Hello World")
|
## await req.respond(Http200, "Hello World")
|
||||||
##
|
##
|
||||||
## waitFor server.serve(Port(8080), cb)
|
## waitFor server.serve(Port(8080), cb)
|
||||||
|
##
|
||||||
|
## Basic Post request handle
|
||||||
|
## =========================
|
||||||
|
##
|
||||||
|
## This example will create an HTTP server on port 8080. The server will
|
||||||
|
## respond with a page with the actual and expected body length after
|
||||||
|
## submitting a file.
|
||||||
|
##
|
||||||
|
## .. code-block::nim
|
||||||
|
## import asynchttpserver, asyncdispatch
|
||||||
|
## import strutils, strformat
|
||||||
|
##
|
||||||
|
## proc htmlpage(contentLength, bodyLength: int): string =
|
||||||
|
## return &"""
|
||||||
|
## <!Doctype html>
|
||||||
|
## <html lang="en">
|
||||||
|
## <head>
|
||||||
|
## <meta charset="utf-8"/>
|
||||||
|
## </head>
|
||||||
|
## <body>
|
||||||
|
## <form action="/" method="post" enctype="multipart/form-data">
|
||||||
|
## File: <input type="file" name="testfile" accept="text/*"><br />
|
||||||
|
## <input style="margin:10px 0;" type="submit">
|
||||||
|
## </form><br />
|
||||||
|
## Expected Body Length: {contentLength} bytes<br />
|
||||||
|
## Actual Body Length: {bodyLength} bytes
|
||||||
|
## </body>
|
||||||
|
## </html>
|
||||||
|
## """
|
||||||
|
##
|
||||||
|
## proc cb(req: Request) {.async.} =
|
||||||
|
## var
|
||||||
|
## contentLength = 0
|
||||||
|
## bodyLength = 0
|
||||||
|
## if req.reqMethod == HttpPost:
|
||||||
|
## contentLength = req.headers["Content-length"].parseInt
|
||||||
|
## if contentLength < 8*1024: # the default chunkSize
|
||||||
|
## # read the request body at once
|
||||||
|
## let body = await req.bodyStream.readAll();
|
||||||
|
## bodyLength = body.len
|
||||||
|
## else:
|
||||||
|
## # read 8*1024 bytes at a time
|
||||||
|
## while (let data = await req.bodyStream.read(); data[0]):
|
||||||
|
## bodyLength += data[1].len
|
||||||
|
## await req.respond(Http200, htmlpage(contentLength, bodyLength))
|
||||||
|
##
|
||||||
|
## let server = newAsyncHttpServer(maxBody = 10485760) # 10 MB
|
||||||
|
## waitFor server.serve(Port(8080), cb)
|
||||||
|
|
||||||
import tables, asyncnet, asyncdispatch, parseutils, uri, strutils
|
import tables, asyncnet, asyncdispatch, parseutils, uri, strutils
|
||||||
import httpcore
|
import httpcore
|
||||||
|
|
@ -46,7 +94,7 @@ const
|
||||||
|
|
||||||
when (NimMajor, NimMinor) >= (1, 1):
|
when (NimMajor, NimMinor) >= (1, 1):
|
||||||
const
|
const
|
||||||
chunkSize = 8*1048 ## This seems perfectly reasonable for default chunkSize.
|
chunkSize = 8*1024 ## This seems perfectly reasonable for default chunkSize.
|
||||||
|
|
||||||
type
|
type
|
||||||
Request* = object
|
Request* = object
|
||||||
|
|
@ -56,7 +104,7 @@ when (NimMajor, NimMinor) >= (1, 1):
|
||||||
protocol*: tuple[orig: string, major, minor: int]
|
protocol*: tuple[orig: string, major, minor: int]
|
||||||
url*: Uri
|
url*: Uri
|
||||||
hostname*: string ## The hostname of the client that made the request.
|
hostname*: string ## The hostname of the client that made the request.
|
||||||
body*: string
|
body*: string # For future removal
|
||||||
bodyStream*: FutureStream[string]
|
bodyStream*: FutureStream[string]
|
||||||
else:
|
else:
|
||||||
type
|
type
|
||||||
|
|
@ -162,12 +210,16 @@ proc processRequest(
|
||||||
# Header: val
|
# Header: val
|
||||||
# \n
|
# \n
|
||||||
request.headers.clear()
|
request.headers.clear()
|
||||||
request.body = ""
|
|
||||||
request.hostname.shallowCopy(address)
|
request.hostname.shallowCopy(address)
|
||||||
assert client != nil
|
assert client != nil
|
||||||
request.client = client
|
request.client = client
|
||||||
when (NimMajor, NimMinor) >= (1, 1):
|
when (NimMajor, NimMinor) >= (1, 1):
|
||||||
request.bodyStream = newFutureStream[string]()
|
request.bodyStream = newFutureStream[string]()
|
||||||
|
# To uncomment in the future after compatibility issues
|
||||||
|
# with third parties are solved
|
||||||
|
# else:
|
||||||
|
# request.body = ""
|
||||||
|
request.body = "" # Temporary fix for future removal
|
||||||
|
|
||||||
# We should skip at least one empty line before the request
|
# We should skip at least one empty line before the request
|
||||||
# https://tools.ietf.org/html/rfc7230#section-3.5
|
# https://tools.ietf.org/html/rfc7230#section-3.5
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue