diff options
author | Araq <rumpf_a@web.de> | 2015-07-02 16:18:35 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-07-02 16:18:35 +0200 |
commit | 9b01f1bedb464e860f8c0f1ffa2df8c17bc26fb7 (patch) | |
tree | 890677483d7e6cb9714a1d5629414df7cbcded12 | |
parent | cabbcd411d93ab1787414715b68b5239a9cee2ae (diff) | |
parent | cf63f90d0ff8586dfba218d2dd80bdb84bf69627 (diff) | |
download | Nim-9b01f1bedb464e860f8c0f1ffa2df8c17bc26fb7.tar.gz |
Merge branch 'devel' of https://github.com/Araq/Nim into devel
-rw-r--r-- | lib/pure/asyncftpclient.nim | 18 | ||||
-rw-r--r-- | lib/pure/ftpclient.nim | 24 | ||||
-rw-r--r-- | lib/pure/httpclient.nim | 18 | ||||
-rw-r--r-- | readme.md | 2 |
4 files changed, 58 insertions, 4 deletions
diff --git a/lib/pure/asyncftpclient.nim b/lib/pure/asyncftpclient.nim index daf69d59f..fe4577ed9 100644 --- a/lib/pure/asyncftpclient.nim +++ b/lib/pure/asyncftpclient.nim @@ -37,12 +37,24 @@ type proc (total, progress: BiggestInt, speed: float): Future[void] {.closure, gcsafe.} -proc expectReply(ftp: AsyncFtpClient): Future[TaintedString] = - result = ftp.csock.recvLine() +const multiLineLimit = 10000 + +proc expectReply(ftp: AsyncFtpClient): Future[TaintedString] {.async.} = + result = await ftp.csock.recvLine() + var count = 0 + while result[3] == '-': + ## Multi-line reply. + let line = await ftp.csock.recvLine() + result.add("\n" & line) + count.inc() + if count >= multiLineLimit: + raise newException(ReplyError, "Reached maximum multi-line reply count.") proc send*(ftp: AsyncFtpClient, m: string): Future[TaintedString] {.async.} = ## Send a message to the server, and wait for a primary reply. ## ``\c\L`` is added for you. + ## + ## **Note:** The server may return multiple lines of coded replies. await ftp.csock.send(m & "\c\L") return await ftp.expectReply() @@ -79,6 +91,8 @@ proc connect*(ftp: AsyncFtpClient) {.async.} = # 120 Service ready in nnn minutes. # We wait until we receive 220. reply = await ftp.expectReply() + + # Handle 220 messages from the server assertReply(reply, "220") if ftp.user != "": diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim index dd141eb01..778ba6857 100644 --- a/lib/pure/ftpclient.nim +++ b/lib/pure/ftpclient.nim @@ -107,6 +107,8 @@ type EInvalidReply: ReplyError, EFTP: FTPError ].} +const multiLineLimit = 10000 + proc ftpClient*(address: string, port = Port(21), user, pass = ""): FtpClient = ## Create a ``FtpClient`` object. @@ -135,10 +137,24 @@ proc expectReply[T](ftp: FtpBase[T]): TaintedString = ftp.csock.readLine(result) else: discard ftp.csock.readLine(result) + var count = 0 + while result[3] == '-': + ## Multi-line reply. + var line = TaintedString"" + when T is Socket: + ftp.csock.readLine(line) + else: + discard ftp.csock.readLine(line) + result.add("\n" & line) + count.inc() + if count >= multiLineLimit: + raise newException(ReplyError, "Reached maximum multi-line reply count.") proc send*[T](ftp: FtpBase[T], m: string): TaintedString = ## Send a message to the server, and wait for a primary reply. ## ``\c\L`` is added for you. + ## + ## **Note:** The server may return multiple lines of coded replies. blockingOperation(ftp.csock): ftp.csock.send(m & "\c\L") return ftp.expectReply() @@ -263,7 +279,13 @@ proc connect*[T](ftp: FtpBase[T]) = else: {.fatal: "Incorrect socket instantiation".} - # TODO: Handle 120? or let user handle it. + var reply = ftp.expectReply() + if reply.startsWith("120"): + # 120 Service ready in nnn minutes. + # We wait until we receive 220. + reply = ftp.expectReply() + + # Handle 220 messages from the server assertReply ftp.expectReply(), "220" if ftp.user != "": diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 6a2913713..2ca2098b3 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -821,6 +821,24 @@ proc get*(client: AsyncHttpClient, url: string): Future[Response] {.async.} = result = await client.request(redirectTo, httpGET) lastUrl = redirectTo +proc post*(client: AsyncHttpClient, url: string, body = "", multipart: MultipartData = nil): Future[Response] {.async.} = + ## Connects to the hostname specified by the URL and performs a POST request. + ## + ## This procedure will follow redirects up to a maximum number of redirects + ## specified in ``newAsyncHttpClient``. + let (mpHeader, mpBody) = format(multipart) + + template withNewLine(x): expr = + if x.len > 0 and not x.endsWith("\c\L"): + x & "\c\L" + else: + x + var xb = mpBody.withNewLine() & body + client.headers["Content-Type"] = mpHeader.split(": ")[1] + client.headers["Content-Length"] = $len(xb) + + result = await client.request(url, httpPOST, xb) + when not defined(testing) and isMainModule: when true: # Async diff --git a/readme.md b/readme.md index 740296f4f..277ceb8f3 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ To build from source you will need: If you are on a fairly modern *nix system, the following steps should work: ``` -$ git clone git://github.com/Araq/Nim.git +$ git clone git://github.com/nim-lang/Nim.git $ cd Nim $ git clone --depth 1 git://github.com/nim-lang/csources $ cd csources && sh build.sh |