summary refs log tree commit diff stats
path: root/lib/pure/cgi.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/cgi.nim')
-rw-r--r--lib/pure/cgi.nim147
1 files changed, 72 insertions, 75 deletions
diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim
index 8d827f555..034f224ac 100644
--- a/lib/pure/cgi.nim
+++ b/lib/pure/cgi.nim
@@ -9,29 +9,32 @@
 
 ## This module implements helper procs for CGI applications. Example:
 ##
-## .. code-block:: Nim
+##   ```Nim
+##   import std/[strtabs, cgi]
 ##
-##    import strtabs, cgi
-##
-##    # Fill the values when debugging:
-##    when debug:
-##      setTestData("name", "Klaus", "password", "123456")
-##    # read the data into `myData`
-##    var myData = readData()
-##    # check that the data's variable names are "name" or "password"
-##    validateData(myData, "name", "password")
-##    # start generating content:
-##    writeContentType()
-##    # generate content:
-##    write(stdout, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n")
-##    write(stdout, "<html><head><title>Test</title></head><body>\n")
-##    writeLine(stdout, "your name: " & myData["name"])
-##    writeLine(stdout, "your password: " & myData["password"])
-##    writeLine(stdout, "</body></html>")
+##   # Fill the values when debugging:
+##   when debug:
+##     setTestData("name", "Klaus", "password", "123456")
+##   # read the data into `myData`
+##   var myData = readData()
+##   # check that the data's variable names are "name" or "password"
+##   validateData(myData, "name", "password")
+##   # start generating content:
+##   writeContentType()
+##   # generate content:
+##   write(stdout, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n")
+##   write(stdout, "<html><head><title>Test</title></head><body>\n")
+##   writeLine(stdout, "your name: " & myData["name"])
+##   writeLine(stdout, "your password: " & myData["password"])
+##   writeLine(stdout, "</body></html>")
+##   ```
 
 import std/[strutils, os, strtabs, cookies, uri]
 export uri.encodeUrl, uri.decodeUrl
 
+when defined(nimPreviewSlimSystem):
+  import std/syncio
+
 
 proc addXmlChar(dest: var string, c: char) {.inline.} =
   case c
@@ -63,11 +66,11 @@ proc cgiError*(msg: string) {.noreturn.} =
   raise newException(CgiError, msg)
 
 proc getEncodedData(allowedMethods: set[RequestMethod]): string =
-  case getEnv("REQUEST_METHOD").string
+  case getEnv("REQUEST_METHOD")
   of "POST":
     if methodPost notin allowedMethods:
       cgiError("'REQUEST_METHOD' 'POST' is not supported")
-    var L = parseInt(getEnv("CONTENT_LENGTH").string)
+    var L = parseInt(getEnv("CONTENT_LENGTH"))
     if L == 0:
       return ""
     result = newString(L)
@@ -76,31 +79,25 @@ proc getEncodedData(allowedMethods: set[RequestMethod]): string =
   of "GET":
     if methodGet notin allowedMethods:
       cgiError("'REQUEST_METHOD' 'GET' is not supported")
-    result = getEnv("QUERY_STRING").string
+    result = getEnv("QUERY_STRING")
   else:
     if methodNone notin allowedMethods:
       cgiError("'REQUEST_METHOD' must be 'POST' or 'GET'")
 
-iterator decodeData*(data: string): tuple[key, value: TaintedString] =
+iterator decodeData*(data: string): tuple[key, value: string] =
   ## Reads and decodes CGI data and yields the (name, value) pairs the
   ## data consists of.
-  try:
-    for (key, value) in uri.decodeQuery(data):
-      yield (key, value)
-  except UriParseError as e:
-    cgiError(e.msg)
+  for (key, value) in uri.decodeQuery(data):
+    yield (key, value)
 
 iterator decodeData*(allowedMethods: set[RequestMethod] =
-       {methodNone, methodPost, methodGet}): tuple[key, value: TaintedString] =
+       {methodNone, methodPost, methodGet}): tuple[key, value: string] =
   ## Reads and decodes CGI data and yields the (name, value) pairs the
   ## data consists of. If the client does not use a method listed in the
   ## `allowedMethods` set, a `CgiError` exception is raised.
   let data = getEncodedData(allowedMethods)
-  try:
-    for (key, value) in uri.decodeQuery(data):
-      yield (key, value)
-  except UriParseError as e:
-    cgiError(e.msg)
+  for (key, value) in uri.decodeQuery(data):
+    yield (key, value)
 
 proc readData*(allowedMethods: set[RequestMethod] =
                {methodNone, methodPost, methodGet}): StringTableRef =
@@ -108,13 +105,13 @@ proc readData*(allowedMethods: set[RequestMethod] =
   ## `allowedMethods` set, a `CgiError` exception is raised.
   result = newStringTable()
   for name, value in decodeData(allowedMethods):
-    result[name.string] = value.string
+    result[name] = value
 
 proc readData*(data: string): StringTableRef =
   ## Reads CGI data from a string.
   result = newStringTable()
   for name, value in decodeData(data):
-    result[name.string] = value.string
+    result[name] = value
 
 proc validateData*(data: StringTableRef, validKeys: varargs[string]) =
   ## Validates data; raises `CgiError` if this fails. This checks that each variable
@@ -125,139 +122,139 @@ proc validateData*(data: StringTableRef, validKeys: varargs[string]) =
 
 proc getContentLength*(): string =
   ## Returns contents of the `CONTENT_LENGTH` environment variable.
-  return getEnv("CONTENT_LENGTH").string
+  return getEnv("CONTENT_LENGTH")
 
 proc getContentType*(): string =
   ## Returns contents of the `CONTENT_TYPE` environment variable.
-  return getEnv("CONTENT_Type").string
+  return getEnv("CONTENT_Type")
 
 proc getDocumentRoot*(): string =
   ## Returns contents of the `DOCUMENT_ROOT` environment variable.
-  return getEnv("DOCUMENT_ROOT").string
+  return getEnv("DOCUMENT_ROOT")
 
 proc getGatewayInterface*(): string =
   ## Returns contents of the `GATEWAY_INTERFACE` environment variable.
-  return getEnv("GATEWAY_INTERFACE").string
+  return getEnv("GATEWAY_INTERFACE")
 
 proc getHttpAccept*(): string =
   ## Returns contents of the `HTTP_ACCEPT` environment variable.
-  return getEnv("HTTP_ACCEPT").string
+  return getEnv("HTTP_ACCEPT")
 
 proc getHttpAcceptCharset*(): string =
   ## Returns contents of the `HTTP_ACCEPT_CHARSET` environment variable.
-  return getEnv("HTTP_ACCEPT_CHARSET").string
+  return getEnv("HTTP_ACCEPT_CHARSET")
 
 proc getHttpAcceptEncoding*(): string =
   ## Returns contents of the `HTTP_ACCEPT_ENCODING` environment variable.
-  return getEnv("HTTP_ACCEPT_ENCODING").string
+  return getEnv("HTTP_ACCEPT_ENCODING")
 
 proc getHttpAcceptLanguage*(): string =
   ## Returns contents of the `HTTP_ACCEPT_LANGUAGE` environment variable.
-  return getEnv("HTTP_ACCEPT_LANGUAGE").string
+  return getEnv("HTTP_ACCEPT_LANGUAGE")
 
 proc getHttpConnection*(): string =
   ## Returns contents of the `HTTP_CONNECTION` environment variable.
-  return getEnv("HTTP_CONNECTION").string
+  return getEnv("HTTP_CONNECTION")
 
 proc getHttpCookie*(): string =
   ## Returns contents of the `HTTP_COOKIE` environment variable.
-  return getEnv("HTTP_COOKIE").string
+  return getEnv("HTTP_COOKIE")
 
 proc getHttpHost*(): string =
   ## Returns contents of the `HTTP_HOST` environment variable.
-  return getEnv("HTTP_HOST").string
+  return getEnv("HTTP_HOST")
 
 proc getHttpReferer*(): string =
   ## Returns contents of the `HTTP_REFERER` environment variable.
-  return getEnv("HTTP_REFERER").string
+  return getEnv("HTTP_REFERER")
 
 proc getHttpUserAgent*(): string =
   ## Returns contents of the `HTTP_USER_AGENT` environment variable.
-  return getEnv("HTTP_USER_AGENT").string
+  return getEnv("HTTP_USER_AGENT")
 
 proc getPathInfo*(): string =
   ## Returns contents of the `PATH_INFO` environment variable.
-  return getEnv("PATH_INFO").string
+  return getEnv("PATH_INFO")
 
 proc getPathTranslated*(): string =
   ## Returns contents of the `PATH_TRANSLATED` environment variable.
-  return getEnv("PATH_TRANSLATED").string
+  return getEnv("PATH_TRANSLATED")
 
 proc getQueryString*(): string =
   ## Returns contents of the `QUERY_STRING` environment variable.
-  return getEnv("QUERY_STRING").string
+  return getEnv("QUERY_STRING")
 
 proc getRemoteAddr*(): string =
   ## Returns contents of the `REMOTE_ADDR` environment variable.
-  return getEnv("REMOTE_ADDR").string
+  return getEnv("REMOTE_ADDR")
 
 proc getRemoteHost*(): string =
   ## Returns contents of the `REMOTE_HOST` environment variable.
-  return getEnv("REMOTE_HOST").string
+  return getEnv("REMOTE_HOST")
 
 proc getRemoteIdent*(): string =
   ## Returns contents of the `REMOTE_IDENT` environment variable.
-  return getEnv("REMOTE_IDENT").string
+  return getEnv("REMOTE_IDENT")
 
 proc getRemotePort*(): string =
   ## Returns contents of the `REMOTE_PORT` environment variable.
-  return getEnv("REMOTE_PORT").string
+  return getEnv("REMOTE_PORT")
 
 proc getRemoteUser*(): string =
   ## Returns contents of the `REMOTE_USER` environment variable.
-  return getEnv("REMOTE_USER").string
+  return getEnv("REMOTE_USER")
 
 proc getRequestMethod*(): string =
   ## Returns contents of the `REQUEST_METHOD` environment variable.
-  return getEnv("REQUEST_METHOD").string
+  return getEnv("REQUEST_METHOD")
 
 proc getRequestURI*(): string =
   ## Returns contents of the `REQUEST_URI` environment variable.
-  return getEnv("REQUEST_URI").string
+  return getEnv("REQUEST_URI")
 
 proc getScriptFilename*(): string =
   ## Returns contents of the `SCRIPT_FILENAME` environment variable.
-  return getEnv("SCRIPT_FILENAME").string
+  return getEnv("SCRIPT_FILENAME")
 
 proc getScriptName*(): string =
   ## Returns contents of the `SCRIPT_NAME` environment variable.
-  return getEnv("SCRIPT_NAME").string
+  return getEnv("SCRIPT_NAME")
 
 proc getServerAddr*(): string =
   ## Returns contents of the `SERVER_ADDR` environment variable.
-  return getEnv("SERVER_ADDR").string
+  return getEnv("SERVER_ADDR")
 
 proc getServerAdmin*(): string =
   ## Returns contents of the `SERVER_ADMIN` environment variable.
-  return getEnv("SERVER_ADMIN").string
+  return getEnv("SERVER_ADMIN")
 
 proc getServerName*(): string =
   ## Returns contents of the `SERVER_NAME` environment variable.
-  return getEnv("SERVER_NAME").string
+  return getEnv("SERVER_NAME")
 
 proc getServerPort*(): string =
   ## Returns contents of the `SERVER_PORT` environment variable.
-  return getEnv("SERVER_PORT").string
+  return getEnv("SERVER_PORT")
 
 proc getServerProtocol*(): string =
   ## Returns contents of the `SERVER_PROTOCOL` environment variable.
-  return getEnv("SERVER_PROTOCOL").string
+  return getEnv("SERVER_PROTOCOL")
 
 proc getServerSignature*(): string =
   ## Returns contents of the `SERVER_SIGNATURE` environment variable.
-  return getEnv("SERVER_SIGNATURE").string
+  return getEnv("SERVER_SIGNATURE")
 
 proc getServerSoftware*(): string =
   ## Returns contents of the `SERVER_SOFTWARE` environment variable.
-  return getEnv("SERVER_SOFTWARE").string
+  return getEnv("SERVER_SOFTWARE")
 
 proc setTestData*(keysvalues: varargs[string]) =
   ## Fills the appropriate environment variables to test your CGI application.
   ## This can only simulate the 'GET' request method. `keysvalues` should
   ## provide embedded (name, value)-pairs. Example:
-  ##
-  ## .. code-block:: Nim
-  ##    setTestData("name", "Hanz", "password", "12345")
+  ##   ```Nim
+  ##   setTestData("name", "Hanz", "password", "12345")
+  ##   ```
   putEnv("REQUEST_METHOD", "GET")
   var i = 0
   var query = ""
@@ -272,9 +269,9 @@ proc setTestData*(keysvalues: varargs[string]) =
 proc writeContentType*() =
   ## Calls this before starting to send your HTML data to `stdout`. This
   ## implements this part of the CGI protocol:
-  ##
-  ## .. code-block:: Nim
-  ##     write(stdout, "Content-type: text/html\n\n")
+  ##   ```Nim
+  ##   write(stdout, "Content-type: text/html\n\n")
+  ##   ```
   write(stdout, "Content-type: text/html\n\n")
 
 proc resetForStacktrace() =
@@ -307,10 +304,10 @@ proc setCookie*(name, value: string) =
 var
   gcookies {.threadvar.}: StringTableRef
 
-proc getCookie*(name: string): TaintedString =
+proc getCookie*(name: string): string =
   ## Gets a cookie. If no cookie of `name` exists, "" is returned.
   if gcookies == nil: gcookies = parseCookies(getHttpCookie())
-  result = TaintedString(gcookies.getOrDefault(name))
+  result = gcookies.getOrDefault(name)
 
 proc existsCookie*(name: string): bool =
   ## Checks if a cookie of `name` exists.