Skip to content

Commit abd660c

Browse files
authored
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!
1 parent bf3f1c3 commit abd660c

File tree

1 file changed

+55
-3
lines changed

1 file changed

+55
-3
lines changed

lib/pure/asynchttpserver.nim

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,54 @@
2929
## await req.respond(Http200, "Hello World")
3030
##
3131
## waitFor server.serve(Port(8080), cb)
32+
##
33+
## Basic Post request handle
34+
## =========================
35+
##
36+
## This example will create an HTTP server on port 8080. The server will
37+
## respond with a page with the actual and expected body length after
38+
## submitting a file.
39+
##
40+
## .. code-block::nim
41+
## import asynchttpserver, asyncdispatch
42+
## import strutils, strformat
43+
##
44+
## proc htmlpage(contentLength, bodyLength: int): string =
45+
## return &"""
46+
## <!Doctype html>
47+
## <html lang="en">
48+
## <head>
49+
## <meta charset="utf-8"/>
50+
## </head>
51+
## <body>
52+
## <form action="/" method="post" enctype="multipart/form-data">
53+
## File: <input type="file" name="testfile" accept="text/*"><br />
54+
## <input style="margin:10px 0;" type="submit">
55+
## </form><br />
56+
## Expected Body Length: {contentLength} bytes<br />
57+
## Actual Body Length: {bodyLength} bytes
58+
## </body>
59+
## </html>
60+
## """
61+
##
62+
## proc cb(req: Request) {.async.} =
63+
## var
64+
## contentLength = 0
65+
## bodyLength = 0
66+
## if req.reqMethod == HttpPost:
67+
## contentLength = req.headers["Content-length"].parseInt
68+
## if contentLength < 8*1024: # the default chunkSize
69+
## # read the request body at once
70+
## let body = await req.bodyStream.readAll();
71+
## bodyLength = body.len
72+
## else:
73+
## # read 8*1024 bytes at a time
74+
## while (let data = await req.bodyStream.read(); data[0]):
75+
## bodyLength += data[1].len
76+
## await req.respond(Http200, htmlpage(contentLength, bodyLength))
77+
##
78+
## let server = newAsyncHttpServer(maxBody = 10485760) # 10 MB
79+
## waitFor server.serve(Port(8080), cb)
3280

3381
import tables, asyncnet, asyncdispatch, parseutils, uri, strutils
3482
import httpcore
@@ -46,7 +94,7 @@ const
4694

4795
when (NimMajor, NimMinor) >= (1, 1):
4896
const
49-
chunkSize = 8*1048 ## This seems perfectly reasonable for default chunkSize.
97+
chunkSize = 8*1024 ## This seems perfectly reasonable for default chunkSize.
5098

5199
type
52100
Request* = object
@@ -56,7 +104,7 @@ when (NimMajor, NimMinor) >= (1, 1):
56104
protocol*: tuple[orig: string, major, minor: int]
57105
url*: Uri
58106
hostname*: string ## The hostname of the client that made the request.
59-
body*: string
107+
body*: string # For future removal
60108
bodyStream*: FutureStream[string]
61109
else:
62110
type
@@ -162,12 +210,16 @@ proc processRequest(
162210
# Header: val
163211
# \n
164212
request.headers.clear()
165-
request.body = ""
166213
request.hostname.shallowCopy(address)
167214
assert client != nil
168215
request.client = client
169216
when (NimMajor, NimMinor) >= (1, 1):
170217
request.bodyStream = newFutureStream[string]()
218+
# To uncomment in the future after compatibility issues
219+
# with third parties are solved
220+
# else:
221+
# request.body = ""
222+
request.body = "" # Temporary fix for future removal
171223

172224
# We should skip at least one empty line before the request
173225
# https://tools.ietf.org/html/rfc7230#section-3.5

0 commit comments

Comments
 (0)