summary refs log tree commit diff stats
path: root/lib/pure/scgi.nim
diff options
context:
space:
mode:
authordom96 <dominikpicheta@googlemail.com>2012-01-22 16:21:05 +0000
committerdom96 <dominikpicheta@googlemail.com>2012-01-22 16:21:05 +0000
commitb298b07567e683de0b82b20f67fd661773edde30 (patch)
tree1eba4ebbf705591868fa768e35214dd0a5716dc2 /lib/pure/scgi.nim
parente92693ec8df1c6b2e4a833e72e18037cd9880b8c (diff)
downloadNim-b298b07567e683de0b82b20f67fd661773edde30.tar.gz
Added asyncio module; irc, scgi and the ftpclient modules work with it. Added (de)allocCStringArray. Many async sockets fixes.
Diffstat (limited to 'lib/pure/scgi.nim')
-rwxr-xr-xlib/pure/scgi.nim54
1 files changed, 51 insertions, 3 deletions
diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim
index 546afb2c0..f8a957d87 100755
--- a/lib/pure/scgi.nim
+++ b/lib/pure/scgi.nim
@@ -7,7 +7,7 @@
 #    distribution, for details about the copyright.
 #
 
-## This module implements helper procs for SCGI applictions. Example:
+## This module implements helper procs for SCGI applications. Example:
 ## 
 ## .. code-block:: Nimrod
 ##
@@ -24,7 +24,7 @@
 ##    run(handleRequest)
 ##
 
-import sockets, strutils, os, strtabs
+import sockets, strutils, os, strtabs, asyncio
 
 type
   EScgi* = object of EIO ## the exception that is raised, if a SCGI error occurs
@@ -58,12 +58,18 @@ proc recvChar(s: TSocket): char =
     result = c
   
 type
-  TScgiState* {.final.} = object ## SCGI state object
+  TScgiState* = object of TObject ## SCGI state object
     server: TSocket
     bufLen: int
     client*: TSocket ## the client socket to send data to
     headers*: PStringTable ## the parsed headers
     input*: string  ## the input buffer
+  
+  TAsyncScgiState* = object of TScgiState
+    handleRequest: proc (server: var TAsyncScgiState, client: TSocket, 
+                         input: string, headers: PStringTable,userArg: PObject)
+    userArg: PObject
+  PAsyncScgiState* = ref TAsyncScgiState
     
 proc recvBuffer(s: var TScgiState, L: int) =
   if L > s.bufLen: 
@@ -131,6 +137,48 @@ proc run*(handleRequest: proc (client: TSocket, input: string,
       s.client.close()
   s.close()
 
+proc open*(handleRequest: proc (server: var TAsyncScgiState, client: TSocket, 
+                                input: string, headers: PStringTable,
+                                userArg: PObject),
+           port = TPort(4000), address = "127.0.0.1",
+           userArg: PObject = nil): PAsyncScgiState =
+  ## Alternative of ``open`` for asyncio compatible SCGI.
+  new(result)
+  open(result[], port, address)
+  result.handleRequest = handleRequest
+  result.userArg = userArg
+
+proc getSocket(h: PObject): tuple[info: TInfo, sock: TSocket] =
+  var s = PAsyncScgiState(h)
+  return (SockListening, s.server)
+
+proc handleAccept(h: PObject) =
+  var s = PAsyncScgiState(h)
+  
+  s.client = accept(s.server)
+  var L = 0
+  while true:
+    var d = s.client.recvChar()
+    if d notin strutils.digits: 
+      if d != ':': scgiError("':' after length expected")
+      break
+    L = L * 10 + ord(d) - ord('0')  
+  recvBuffer(s[], L+1)
+  s.headers = parseHeaders(s.input, L)
+  if s.headers["SCGI"] != "1": scgiError("SCGI Version 1 expected")
+  L = parseInt(s.headers["CONTENT_LENGTH"])
+  recvBuffer(s[], L)
+
+  s.handleRequest(s[], s.client, s.input, s.headers, s.userArg)
+
+proc register*(d: PDispatcher, s: PAsyncScgiState) =
+  ## Registers ``s`` with dispatcher ``d``.
+  var dele = newDelegate()
+  dele.deleVal = s
+  dele.getSocket = getSocket
+  dele.handleAccept = handleAccept
+  d.register(dele)
+
 when false:
   var counter = 0
   proc handleRequest(client: TSocket, input: string,