thttpclient.nim 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. discard """
  2. cmd: "nim c --threads:on -d:ssl $file"
  3. exitcode: 0
  4. output: "OK"
  5. disabled: true
  6. """
  7. import strutils
  8. from net import TimeoutError
  9. import nativesockets, os, httpclient, asyncdispatch
  10. const manualTests = false
  11. proc makeIPv6HttpServer(hostname: string, port: Port,
  12. message: string): AsyncFD =
  13. let fd = createNativeSocket(AF_INET6)
  14. setSockOptInt(fd, SOL_SOCKET, SO_REUSEADDR, 1)
  15. var aiList = getAddrInfo(hostname, port, AF_INET6)
  16. if bindAddr(fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32:
  17. freeAddrInfo(aiList)
  18. raiseOSError(osLastError())
  19. freeAddrInfo(aiList)
  20. if listen(fd) != 0:
  21. raiseOSError(osLastError())
  22. setBlocking(fd, false)
  23. var serverFd = fd.AsyncFD
  24. register(serverFd)
  25. result = serverFd
  26. proc onAccept(fut: Future[AsyncFD]) {.gcsafe.} =
  27. if not fut.failed:
  28. let clientFd = fut.read()
  29. clientFd.send(message).callback = proc() =
  30. clientFd.closeSocket()
  31. serverFd.accept().callback = onAccept
  32. serverFd.accept().callback = onAccept
  33. proc asyncTest() {.async.} =
  34. var client = newAsyncHttpClient()
  35. var resp = await client.request("http://example.com/")
  36. doAssert(resp.code.is2xx)
  37. var body = await resp.body
  38. body = await resp.body # Test caching
  39. doAssert("<title>Example Domain</title>" in body)
  40. resp = await client.request("http://example.com/404")
  41. doAssert(resp.code.is4xx)
  42. doAssert(resp.code == Http404)
  43. doAssert(resp.status == Http404)
  44. resp = await client.request("https://google.com/")
  45. doAssert(resp.code.is2xx or resp.code.is3xx)
  46. # getContent
  47. try:
  48. discard await client.getContent("https://google.com/404")
  49. doAssert(false, "HttpRequestError should have been raised")
  50. except HttpRequestError:
  51. discard
  52. except:
  53. doAssert(false, "HttpRequestError should have been raised")
  54. when false:
  55. # w3.org now blocks travis, so disabled:
  56. # Multipart test.
  57. var data = newMultipartData()
  58. data["output"] = "soap12"
  59. data["uploaded_file"] = ("test.html", "text/html",
  60. "<html><head></head><body><p>test</p></body></html>")
  61. resp = await client.post("http://validator.w3.org/check", multipart = data)
  62. doAssert(resp.code.is2xx)
  63. # onProgressChanged
  64. when manualTests:
  65. proc onProgressChanged(total, progress, speed: BiggestInt) {.async.} =
  66. echo("Downloaded ", progress, " of ", total)
  67. echo("Current rate: ", speed div 1000, "kb/s")
  68. client.onProgressChanged = onProgressChanged
  69. await client.downloadFile("http://speedtest-ams2.digitalocean.com/100mb.test",
  70. "100mb.test")
  71. # HTTP/1.1 without Content-Length - issue #10726
  72. var serverFd = makeIPv6HttpServer("::1", Port(18473),
  73. "HTTP/1.1 200 \c\L" &
  74. "\c\L" &
  75. "Here comes reply")
  76. resp = await client.request("http://[::1]:18473/")
  77. body = await resp.body
  78. doAssert(body == "Here comes reply")
  79. serverFd.closeSocket()
  80. client.close()
  81. # Proxy test
  82. #when manualTests:
  83. # client = newAsyncHttpClient(proxy = newProxy("http://51.254.106.76:80/"))
  84. # var resp = await client.request("https://github.com")
  85. # echo resp
  86. proc syncTest() =
  87. var client = newHttpClient()
  88. var resp = client.request("http://example.com/")
  89. doAssert(resp.code.is2xx)
  90. doAssert("<title>Example Domain</title>" in resp.body)
  91. resp = client.request("http://example.com/404")
  92. doAssert(resp.code.is4xx)
  93. doAssert(resp.code == Http404)
  94. doAssert(resp.status == Http404)
  95. resp = client.request("https://google.com/")
  96. doAssert(resp.code.is2xx or resp.code.is3xx)
  97. # getContent
  98. try:
  99. discard client.getContent("https://google.com/404")
  100. doAssert(false, "HttpRequestError should have been raised")
  101. except HttpRequestError:
  102. discard
  103. except:
  104. doAssert(false, "HttpRequestError should have been raised")
  105. when false:
  106. # w3.org now blocks travis, so disabled:
  107. # Multipart test.
  108. var data = newMultipartData()
  109. data["output"] = "soap12"
  110. data["uploaded_file"] = ("test.html", "text/html",
  111. "<html><head></head><body><p>test</p></body></html>")
  112. resp = client.post("http://validator.w3.org/check", multipart = data)
  113. doAssert(resp.code.is2xx)
  114. # onProgressChanged
  115. when manualTests:
  116. proc onProgressChanged(total, progress, speed: BiggestInt) =
  117. echo("Downloaded ", progress, " of ", total)
  118. echo("Current rate: ", speed div 1000, "kb/s")
  119. client.onProgressChanged = onProgressChanged
  120. client.downloadFile("http://speedtest-ams2.digitalocean.com/100mb.test",
  121. "100mb.test")
  122. client.close()
  123. when false:
  124. # Disabled for now because it causes troubles with AppVeyor
  125. # Timeout test.
  126. client = newHttpClient(timeout = 1)
  127. try:
  128. resp = client.request("http://example.com/")
  129. doAssert false, "TimeoutError should have been raised."
  130. except TimeoutError:
  131. discard
  132. except:
  133. doAssert false, "TimeoutError should have been raised."
  134. proc ipv6Test() =
  135. var client = newAsyncHttpClient()
  136. let serverFd = makeIPv6HttpServer("::1", Port(18473),
  137. "HTTP/1.1 200 OK\r\LContent-Length: 0\r\LConnection: Closed\r\L\r\L")
  138. var resp = waitFor client.request("http://[::1]:18473/")
  139. doAssert(resp.status == "200 OK")
  140. serverFd.closeSocket()
  141. client.close()
  142. ipv6Test()
  143. syncTest()
  144. waitFor(asyncTest())
  145. echo "OK"