summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2014-11-07 14:48:11 +0000
committerDominik Picheta <dominikpicheta@googlemail.com>2014-11-07 14:48:11 +0000
commit13e3c0d5bb5e9d594da3554c358dd9cdce387a7d (patch)
treecc4640d4d484f35d36faaff5bdd00f885de2f02a /lib
parent96d1543c0d4b00505ff78d481326e124d49aa2f1 (diff)
downloadNim-13e3c0d5bb5e9d594da3554c358dd9cdce387a7d.tar.gz
Implement SO_REUSEADDR for asyncnet and asynchttpserver.
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/asynchttpserver.nim6
-rw-r--r--lib/pure/asyncnet.nim13
-rw-r--r--lib/pure/net.nim3
3 files changed, 20 insertions, 2 deletions
diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim
index 257fbaeb5..f40090c64 100644
--- a/lib/pure/asynchttpserver.nim
+++ b/lib/pure/asynchttpserver.nim
@@ -37,6 +37,7 @@ type
 
   AsyncHttpServer* = ref object
     socket: PAsyncSocket
+    reuseAddr: bool
 
   HttpCode* = enum
     Http200 = "200 OK",
@@ -64,9 +65,10 @@ proc `==`*(protocol: tuple[orig: string, major, minor: int],
     of HttpVer10: 0
   result = protocol.major == major and protocol.minor == minor
 
-proc newAsyncHttpServer*(): PAsyncHttpServer =
+proc newAsyncHttpServer*(reuseAddr = true): PAsyncHttpServer =
   ## Creates a new ``AsyncHttpServer`` instance.
   new result
+  result.reuseAddr = reuseAddr
 
 proc addHeaders(msg: var string, headers: PStringTable) =
   for k, v in headers:
@@ -210,6 +212,8 @@ proc serve*(server: PAsyncHttpServer, port: Port,
   ##
   ## When a request is made by a client the specified callback will be called.
   server.socket = newAsyncSocket()
+  if server.reuseAddr:
+    server.socket.setSockOpt(OptReuseAddr, true)
   server.socket.bindAddr(port, address)
   server.socket.listen()
   
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index 72fe51a7e..7028a358d 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -60,6 +60,8 @@ import rawsockets
 import net
 import os
 
+export SOBool
+
 when defined(ssl):
   import openssl
 
@@ -425,6 +427,17 @@ when defined(ssl):
     socket.bioOut = bioNew(bio_s_mem())
     sslSetBio(socket.sslHandle, socket.bioIn, socket.bioOut)
 
+proc getSockOpt*(socket: AsyncSocket, opt: SOBool, level = SOL_SOCKET): bool {.
+  tags: [ReadIOEffect].} =
+  ## Retrieves option ``opt`` as a boolean value.
+  var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
+  result = res != 0
+
+proc setSockOpt*(socket: AsyncSocket, opt: SOBool, value: bool,
+    level = SOL_SOCKET) {.tags: [WriteIOEffect].} =
+  ## Sets option ``opt`` to a boolean value specified by ``value``.
+  var valuei = cint(if value: 1 else: 0)
+  setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei)
 
 when isMainModule:
   type
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index f63f5fff8..2b2c8cfda 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -428,7 +428,8 @@ proc close*(socket: Socket) =
       elif res != 1:
         socketError(socket)
 
-proc toCInt(opt: SOBool): cint =
+proc toCInt*(opt: SOBool): cint =
+  ## Converts a ``SOBool`` into its Socket Option cint representation.
   case opt
   of OptAcceptConn: SO_ACCEPTCONN
   of OptBroadcast: SO_BROADCAST