summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@gmail.com>2020-02-22 11:46:24 +0000
committerDominik Picheta <dominikpicheta@googlemail.com>2020-03-06 11:52:30 +0100
commitec8a17cc861c8282ae33ae36030d1702e41b275a (patch)
treec382e2644c983dd4cb641b8f20d2da743a89b1a5 /lib
parentb80d293a3f8c301a2d9188fb409162028a00edca (diff)
downloadNim-ec8a17cc861c8282ae33ae36030d1702e41b275a.tar.gz
Revert broken asynchttpserver FutureStream additions.
As discussed in #13394, these changes cannot work. Reverted via

```
git revert --no-commit 5bf571f061d53d35aab727f420afd9f415987723
git revert --no-commit abd660c407d00d0c4f2129ff11bfc69badda8ece
git revert --no-commit 955465e5f42b1353f69f3bd884908a7ef91ce13b
git commit
```
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/asynchttpserver.nim176
1 files changed, 31 insertions, 145 deletions
diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim
index 9aed0255b..186f0da41 100644
--- a/lib/pure/asynchttpserver.nim
+++ b/lib/pure/asynchttpserver.nim
@@ -29,129 +29,43 @@
 ##      await req.respond(Http200, "Hello World")
 ##
 ##    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
-##
-##    const stream = true # for test purposes switch from true to false
-##
-##    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 stream:
-##          # Read 8*1024 bytes at a time
-##          # optional chunkSize parameter. The default is 8*1024
-##          for length, data in req.bodyStream(8*1024):
-##            let content = await data
-##            if length == content.len:
-##              bodyLength += content.len
-##            else:
-##              # Handle exception
-##              await req.respond(Http400,
-##                "Bad Request. Data read has a different length than the expected.")
-##              return
-##        else:
-##          bodyLength += req.body.len
-##      await req.respond(Http200, htmlpage(contentLength, bodyLength))
-##
-##    let server = newAsyncHttpServer(maxBody = 10485760, stream = stream) # 10 MB
-##    waitFor server.serve(Port(8080), cb)
 
 import tables, asyncnet, asyncdispatch, parseutils, uri, strutils
 import httpcore
 
 export httpcore except parseHeader
 
+const
+  maxLine = 8*1024
+
 # TODO: If it turns out that the decisions that asynchttpserver makes
 # explicitly, about whether to close the client sockets or upgrade them are
 # wrong, then add a return value which determines what to do for the callback.
 # Also, maybe move `client` out of `Request` object and into the args for
 # the proc.
-
-const
-  maxLine = 8*1024
-
-when (NimMajor, NimMinor) >= (1, 1):
-  type
-    Request* = object
-      client*: AsyncSocket # TODO: Separate this into a Response object?
-      reqMethod*: HttpMethod
-      headers*: HttpHeaders
-      protocol*: tuple[orig: string, major, minor: int]
-      url*: Uri
-      hostname*: string    ## The hostname of the client that made the request.
-      body*: string
-      contentLength*: int
-
-  type
-    AsyncHttpServer* = ref object
-      socket: AsyncSocket
-      reuseAddr: bool
-      reusePort: bool
-      maxBody: int ## The maximum content-length that will be read for the body.
-      stream: bool ## By default (stream = false), the body of the request is read immediately
-else:
-  type
-    Request* = object
-      client*: AsyncSocket # TODO: Separate this into a Response object?
-      reqMethod*: HttpMethod
-      headers*: HttpHeaders
-      protocol*: tuple[orig: string, major, minor: int]
-      url*: Uri
-      hostname*: string    ## The hostname of the client that made the request.
-      body*: string
-
-  type
-    AsyncHttpServer* = ref object
-      socket: AsyncSocket
-      reuseAddr: bool
-      reusePort: bool
-      maxBody: int ## The maximum content-length that will be read for the body.
-
-when (NimMajor, NimMinor) >= (1, 1):
-  proc newAsyncHttpServer*(reuseAddr = true, reusePort = false,
-                         maxBody = 8388608, stream = false): AsyncHttpServer =
-    ## Creates a new ``AsyncHttpServer`` instance.
-    new result
-    result.reuseAddr = reuseAddr
-    result.reusePort = reusePort
-    result.maxBody = maxBody
-    result.stream = stream
-else:
-  proc newAsyncHttpServer*(reuseAddr = true, reusePort = false,
+type
+  Request* = object
+    client*: AsyncSocket # TODO: Separate this into a Response object?
+    reqMethod*: HttpMethod
+    headers*: HttpHeaders
+    protocol*: tuple[orig: string, major, minor: int]
+    url*: Uri
+    hostname*: string    ## The hostname of the client that made the request.
+    body*: string
+
+  AsyncHttpServer* = ref object
+    socket: AsyncSocket
+    reuseAddr: bool
+    reusePort: bool
+    maxBody: int ## The maximum content-length that will be read for the body.
+
+proc newAsyncHttpServer*(reuseAddr = true, reusePort = false,
                          maxBody = 8388608): AsyncHttpServer =
-    ## Creates a new ``AsyncHttpServer`` instance.
-    new result
-    result.reuseAddr = reuseAddr
-    result.reusePort = reusePort
-    result.maxBody = maxBody
+  ## Creates a new ``AsyncHttpServer`` instance.
+  new result
+  result.reuseAddr = reuseAddr
+  result.reusePort = reusePort
+  result.maxBody = maxBody
 
 proc addHeaders(msg: var string, headers: HttpHeaders) =
   for k, v in headers:
@@ -214,30 +128,13 @@ 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")
 
-when (NimMajor, NimMinor) >= (1, 1):
-  iterator bodyStream*(
-    request: Request,
-    chunkSize: int = 8*1024): (int, Future[string]) =
-    ## The chunkSize parameter is optional and default value is 8*1024 bytes.
-    ##
-    ## This iterator return a tuple with the length of the data that was read
-    ## and a future.
-    var remainder = request.contentLength
-    while remainder > 0:
-      let readSize = min(remainder, chunkSize)
-      let data = request.client.recv(readSize)
-      if data.failed:
-        raise newException(ValueError, "Error reading POST data from client.")
-      yield (readSize, data)
-      remainder -= readSize
-
 proc processRequest(
   server: AsyncHttpServer,
   req: FutureVar[Request],
   client: AsyncSocket,
   address: string,
   lineFut: FutureVar[string],
-  callback: proc (request: Request): Future[void] {.closure, gcsafe.}
+  callback: proc (request: Request): Future[void] {.closure, gcsafe.},
 ): Future[bool] {.async.} =
 
   # Alias `request` to `req.mget()` so we don't have to write `mget` everywhere.
@@ -248,12 +145,10 @@ proc processRequest(
   # Header: val
   # \n
   request.headers.clear()
+  request.body = ""
   request.hostname.shallowCopy(address)
   assert client != nil
   request.client = client
-  request.body = ""
-  when (NimMajor, NimMinor) >= (1, 1):
-    request.contentLength = 0
 
   # We should skip at least one empty line before the request
   # https://tools.ietf.org/html/rfc7230#section-3.5
@@ -348,19 +243,10 @@ proc processRequest(
       if contentLength > server.maxBody:
         await request.respondError(Http413)
         return false
-
-      when (NimMajor, NimMinor) >= (1, 1):
-        request.contentLength = contentLength
-        if not server.stream:
-          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
-      else:
-        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.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