diff options
-rw-r--r-- | compiler/lists.nim | 28 | ||||
-rw-r--r-- | doc/lib.rst | 14 | ||||
-rw-r--r-- | lib/deprecated/core/unsigned.nim | 18 | ||||
-rw-r--r-- | lib/deprecated/pure/actors.nim | 239 | ||||
-rw-r--r-- | lib/deprecated/pure/actors.nim.cfg | 3 | ||||
-rw-r--r-- | lib/deprecated/pure/parseurl.nim | 112 | ||||
-rw-r--r-- | lib/deprecated/pure/rawsockets.nim | 14 | ||||
-rw-r--r-- | lib/deprecated/pure/securehash.nim (renamed from lib/pure/securehash.nim) | 0 | ||||
-rw-r--r-- | lib/impure/ssl.nim | 99 | ||||
-rw-r--r-- | lib/pure/httpserver.nim | 535 | ||||
-rw-r--r-- | lib/pure/matchers.nim | 68 | ||||
-rw-r--r-- | tests/manyloc/keineschweine/enet_server/enet_server.nim | 2 | ||||
-rw-r--r-- | tests/manyloc/keineschweine/server/old_dirserver.nim | 2 | ||||
-rw-r--r-- | tests/manyloc/keineschweine/server/old_sg_server.nim | 2 | ||||
-rw-r--r-- | tests/threads/tactors.nim | 13 | ||||
-rw-r--r-- | tests/threads/tactors2.nim | 25 | ||||
-rw-r--r-- | tests/threads/trecursive_actor.nim | 20 | ||||
-rw-r--r-- | tests/tuples/tuple_with_nil.nim | 1 | ||||
-rw-r--r-- | tools/kochdocs.nim | 4 |
19 files changed, 5 insertions, 1194 deletions
diff --git a/compiler/lists.nim b/compiler/lists.nim deleted file mode 100644 index bfd052204..000000000 --- a/compiler/lists.nim +++ /dev/null @@ -1,28 +0,0 @@ -# -# -# The Nim Compiler -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -# This module is deprecated, don't use it. -# TODO Remove this - -import os - -static: - echo "WARNING: imported deprecated module compiler/lists.nim, use seq ore lists from the standard library" - -proc appendStr*(list: var seq[string]; data: string) {.deprecated.} = - # just use system.add - list.add(data) - -proc includeStr(list: var seq[string]; data: string): bool {.deprecated.} = - if list.contains(data): - result = true - else: - result = false - list.add data - diff --git a/doc/lib.rst b/doc/lib.rst index 89e3cca40..a16bf2677 100644 --- a/doc/lib.rst +++ b/doc/lib.rst @@ -141,9 +141,6 @@ String handling Ropes can represent very long strings efficiently; especially concatenation is done in O(1) instead of O(n). -* `matchers <matchers.html>`_ - This module contains various string matchers for email addresses, etc. - * `subexes <subexes.html>`_ This module implements advanced string substitution operations. @@ -275,8 +272,8 @@ Internet Protocols and Support module. * `net <net.html>`_ - This module implements a high-level sockets API. It will replace the - ``sockets`` module in the future. + This module implements a high-level sockets API. It replaces the + ``sockets`` module. * `nativesockets <nativesockets.html>`_ This module implements a low-level sockets API. @@ -456,13 +453,6 @@ Database support for other databases too. -Other ------ - -* `ssl <ssl.html>`_ - This module provides an easy to use sockets-style - Nim interface to the OpenSSL library. - Wrappers ======== diff --git a/lib/deprecated/core/unsigned.nim b/lib/deprecated/core/unsigned.nim deleted file mode 100644 index 93a29e1c9..000000000 --- a/lib/deprecated/core/unsigned.nim +++ /dev/null @@ -1,18 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## **Warning:** Since version 0.11.4 this module is deprecated. -## -## This module implemented basic arithmetic operators for unsigned integers. -## These operators are now available in the ``system`` module directly. - -{.deprecated.} - -export `shr`, `shl`, `and`, `or`, `xor`, `==`, `+`, `-`, `*`, `div`, `mod`, - `<=`, `<` diff --git a/lib/deprecated/pure/actors.nim b/lib/deprecated/pure/actors.nim deleted file mode 100644 index 77c67a3e4..000000000 --- a/lib/deprecated/pure/actors.nim +++ /dev/null @@ -1,239 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## `Actor`:idx: support for Nim. An actor is implemented as a thread with -## a channel as its inbox. This module requires the ``--threads:on`` -## command line switch. -## -## Example: -## -## .. code-block:: nim -## -## var -## a: ActorPool[int, void] -## createActorPool(a) -## for i in 0 ..< 300: -## a.spawn(i, proc (x: int) {.thread.} = echo x) -## a.join() -## -## **Note**: This whole module is deprecated. Use `threadpool` and ``spawn`` -## instead. - -{.deprecated.} - -from os import sleep - -type - Task*[In, Out] = object{.pure, final.} ## a task - when Out isnot void: - receiver*: ptr Channel[Out] ## the receiver channel of the response - action*: proc (x: In): Out {.thread.} ## action to execute; - ## sometimes useful - shutDown*: bool ## set to tell an actor to shut-down - data*: In ## the data to process - - Actor[In, Out] = object{.pure, final.} - i: Channel[Task[In, Out]] - t: Thread[ptr Actor[In, Out]] - - PActor*[In, Out] = ptr Actor[In, Out] ## an actor - -proc spawn*[In, Out](action: proc( - self: PActor[In, Out]){.thread.}): PActor[In, Out] = - ## creates an actor; that is a thread with an inbox. The caller MUST call - ## ``join`` because that also frees the actor's associated resources. - result = cast[PActor[In, Out]](allocShared0(sizeof(result[]))) - open(result.i) - createThread(result.t, action, result) - -proc inbox*[In, Out](self: PActor[In, Out]): ptr Channel[In] = - ## gets a pointer to the associated inbox of the actor `self`. - result = addr(self.i) - -proc running*[In, Out](a: PActor[In, Out]): bool = - ## returns true if the actor `a` is running. - result = running(a.t) - -proc ready*[In, Out](a: PActor[In, Out]): bool = - ## returns true if the actor `a` is ready to process new messages. - result = ready(a.i) - -proc join*[In, Out](a: PActor[In, Out]) = - ## joins an actor. - joinThread(a.t) - close(a.i) - deallocShared(a) - -proc recv*[In, Out](a: PActor[In, Out]): Task[In, Out] = - ## receives a task from `a`'s inbox. - result = recv(a.i) - -proc send*[In, Out, X, Y](receiver: PActor[In, Out], msg: In, - sender: PActor[X, Y]) = - ## sends a message to `a`'s inbox. - var t: Task[In, Out] - t.receiver = addr(sender.i) - shallowCopy(t.data, msg) - send(receiver.i, t) - -proc send*[In, Out](receiver: PActor[In, Out], msg: In, - sender: ptr Channel[Out] = nil) = - ## sends a message to `receiver`'s inbox. - var t: Task[In, Out] - t.receiver = sender - shallowCopy(t.data, msg) - send(receiver.i, t) - -proc sendShutdown*[In, Out](receiver: PActor[In, Out]) = - ## send a shutdown message to `receiver`. - var t: Task[In, Out] - t.shutdown = true - send(receiver.i, t) - -proc reply*[In, Out](t: Task[In, Out], m: Out) = - ## sends a message to io's output message box. - when Out is void: - {.error: "you cannot reply to a void outbox".} - assert t.receiver != nil - send(t.receiver[], m) - - -# ----------------- actor pools ---------------------------------------------- - -type - ActorPool*[In, Out] = object{.pure, final.} ## an actor pool - actors: seq[PActor[In, Out]] - when Out isnot void: - outputs: Channel[Out] - -proc `^`*[T](f: ptr Channel[T]): T = - ## alias for 'recv'. - result = recv(f[]) - -proc poolWorker[In, Out](self: PActor[In, Out]) {.thread.} = - while true: - var m = self.recv - if m.shutDown: break - when Out is void: - m.action(m.data) - else: - send(m.receiver[], m.action(m.data)) - #self.reply() - -proc createActorPool*[In, Out](a: var ActorPool[In, Out], poolSize = 4) = - ## creates an actor pool. - newSeq(a.actors, poolSize) - when Out isnot void: - open(a.outputs) - for i in 0 ..< a.actors.len: - a.actors[i] = spawn(poolWorker[In, Out]) - -proc sync*[In, Out](a: var ActorPool[In, Out], polling=50) = - ## waits for every actor of `a` to finish with its work. Currently this is - ## implemented as polling every `polling` ms and has a slight chance - ## of failing since we check for every actor to be in `ready` state and not - ## for messages still in ether. This will change in a later - ## version, however. - var allReadyCount = 0 - while true: - var wait = false - for i in 0..high(a.actors): - if not a.actors[i].i.ready: - wait = true - allReadyCount = 0 - break - if not wait: - # it's possible that some actor sent a message to some other actor but - # both appeared to be non-working as the message takes some time to - # arrive. We assume that this won't take longer than `polling` and - # simply attempt a second time and declare victory then. ;-) - inc allReadyCount - if allReadyCount > 1: break - sleep(polling) - -proc terminate*[In, Out](a: var ActorPool[In, Out]) = - ## terminates each actor in the actor pool `a` and frees the - ## resources attached to `a`. - var t: Task[In, Out] - t.shutdown = true - for i in 0..<a.actors.len: send(a.actors[i].i, t) - for i in 0..<a.actors.len: join(a.actors[i]) - when Out isnot void: - close(a.outputs) - a.actors = @[] - -proc join*[In, Out](a: var ActorPool[In, Out]) = - ## short-cut for `sync` and then `terminate`. - sync(a) - terminate(a) - -template setupTask = - t.action = action - shallowCopy(t.data, input) - -template schedule = - # extremely simple scheduler: We always try the first thread first, so that - # it remains 'hot' ;-). Round-robin hurts for keeping threads hot. - for i in 0..high(p.actors): - if p.actors[i].i.ready: - p.actors[i].i.send(t) - return - # no thread ready :-( --> send message to the thread which has the least - # messages pending: - var minIdx = -1 - var minVal = high(int) - for i in 0..high(p.actors): - var curr = p.actors[i].i.peek - if curr == 0: - # ok, is ready now: - p.actors[i].i.send(t) - return - if curr < minVal and curr >= 0: - minVal = curr - minIdx = i - if minIdx >= 0: - p.actors[minIdx].i.send(t) - else: - raise newException(DeadThreadError, "cannot send message; thread died") - -proc spawn*[In, Out](p: var ActorPool[In, Out], input: In, - action: proc (input: In): Out {.thread.} - ): ptr Channel[Out] = - ## uses the actor pool to run ``action(input)`` concurrently. - ## `spawn` is guaranteed to not block. - var t: Task[In, Out] - setupTask() - result = addr(p.outputs) - t.receiver = result - schedule() - -proc spawn*[In](p: var ActorPool[In, void], input: In, - action: proc (input: In) {.thread.}) = - ## uses the actor pool to run ``action(input)`` concurrently. - ## `spawn` is guaranteed to not block. - var t: Task[In, void] - setupTask() - schedule() - -when not defined(testing) and isMainModule: - var - a: ActorPool[int, void] - createActorPool(a) - for i in 0 ..< 300: - a.spawn(i, proc (x: int) {.thread.} = echo x) - - when false: - proc treeDepth(n: PNode): int {.thread.} = - var x = a.spawn(treeDepth, n.le) - var y = a.spawn(treeDepth, n.ri) - result = max(^x, ^y) + 1 - - a.join() - - diff --git a/lib/deprecated/pure/actors.nim.cfg b/lib/deprecated/pure/actors.nim.cfg deleted file mode 100644 index c6bb9c545..000000000 --- a/lib/deprecated/pure/actors.nim.cfg +++ /dev/null @@ -1,3 +0,0 @@ -# to shut up the tester: ---threads:on - diff --git a/lib/deprecated/pure/parseurl.nim b/lib/deprecated/pure/parseurl.nim deleted file mode 100644 index b19f6dc85..000000000 --- a/lib/deprecated/pure/parseurl.nim +++ /dev/null @@ -1,112 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2015 Dominik Picheta -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## **Warnings:** This module is deprecated since version 0.10.2. -## Use the `uri <uri.html>`_ module instead. -## -## Parses & constructs URLs. - -{.deprecated.} - -import strutils - -type - Url* = tuple[ ## represents a *Uniform Resource Locator* (URL) - ## any optional component is "" if it does not exist - scheme, username, password, - hostname, port, path, query, anchor: string] - -proc parseUrl*(url: string): Url {.deprecated.} = - var i = 0 - - var scheme, username, password: string = "" - var hostname, port, path, query, anchor: string = "" - - var temp = "" - - if url[i] != '/': # url isn't a relative path - while true: - # Scheme - if url[i] == ':': - if url[i+1] == '/' and url[i+2] == '/': - scheme = temp - temp.setLen(0) - inc(i, 3) # Skip the // - # Authority(username, password) - if url[i] == '@': - username = temp - let colon = username.find(':') - if colon >= 0: - password = username.substr(colon+1) - username = username.substr(0, colon-1) - temp.setLen(0) - inc(i) #Skip the @ - # hostname(subdomain, domain, port) - if url[i] == '/' or url[i] == '\0': - hostname = temp - let colon = hostname.find(':') - if colon >= 0: - port = hostname.substr(colon+1) - hostname = hostname.substr(0, colon-1) - - temp.setLen(0) - break - - temp.add(url[i]) - inc(i) - - if url[i] == '/': inc(i) # Skip the '/' - # Path - while true: - if url[i] == '?': - path = temp - temp.setLen(0) - if url[i] == '#': - if temp[0] == '?': - query = temp - else: - path = temp - temp.setLen(0) - - if url[i] == '\0': - if temp[0] == '?': - query = temp - elif temp[0] == '#': - anchor = temp - else: - path = temp - break - - temp.add(url[i]) - inc(i) - - return (scheme, username, password, hostname, port, path, query, anchor) - -proc `$`*(u: Url): string {.deprecated.} = - ## turns the URL `u` into its string representation. - result = "" - if u.scheme.len > 0: - result.add(u.scheme) - result.add("://") - if u.username.len > 0: - result.add(u.username) - if u.password.len > 0: - result.add(":") - result.add(u.password) - result.add("@") - result.add(u.hostname) - if u.port.len > 0: - result.add(":") - result.add(u.port) - if u.path.len > 0: - result.add("/") - result.add(u.path) - result.add(u.query) - result.add(u.anchor) - diff --git a/lib/deprecated/pure/rawsockets.nim b/lib/deprecated/pure/rawsockets.nim deleted file mode 100644 index 876334f9e..000000000 --- a/lib/deprecated/pure/rawsockets.nim +++ /dev/null @@ -1,14 +0,0 @@ -import nativesockets -export nativesockets - -{.warning: "rawsockets module is deprecated, use nativesockets instead".} - -template newRawSocket*(domain, sockType, protocol: cint): untyped = - {.warning: "newRawSocket is deprecated, use newNativeSocket instead".} - newNativeSocket(domain, sockType, protocol) - -template newRawSocket*(domain: Domain = AF_INET, - sockType: SockType = SOCK_STREAM, - protocol: Protocol = IPPROTO_TCP): untyped = - {.warning: "newRawSocket is deprecated, use newNativeSocket instead".} - newNativeSocket(domain, sockType, protocol) diff --git a/lib/pure/securehash.nim b/lib/deprecated/pure/securehash.nim index c6cde599a..c6cde599a 100644 --- a/lib/pure/securehash.nim +++ b/lib/deprecated/pure/securehash.nim diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim deleted file mode 100644 index 0bcb3f217..000000000 --- a/lib/impure/ssl.nim +++ /dev/null @@ -1,99 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2012 Dominik Picheta -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module provides an easy to use sockets-style -## nim interface to the OpenSSL library. -## -## **Warning:** This module is deprecated, use the SSL procedures defined in -## the ``net`` module instead. - -{.deprecated.} - -import openssl, strutils, os - -type - SecureSocket* = object - ssl: SslPtr - bio: BIO - -proc connect*(sock: var SecureSocket, address: string, - port: int): int = - ## Connects to the specified `address` on the specified `port`. - ## Returns the result of the certificate validation. - SslLoadErrorStrings() - ERR_load_BIO_strings() - - if SSL_library_init() != 1: - raiseOSError(osLastError()) - - var ctx = SSL_CTX_new(SSLv23_client_method()) - if ctx == nil: - ERR_print_errors_fp(stderr) - raiseOSError(osLastError()) - - #if SSL_CTX_load_verify_locations(ctx, - # "/tmp/openssl-0.9.8e/certs/vsign1.pem", NIL) == 0: - # echo("Failed load verify locations") - # ERR_print_errors_fp(stderr) - - sock.bio = BIO_new_ssl_connect(ctx) - if BIO_get_ssl(sock.bio, addr(sock.ssl)) == 0: - raiseOSError(osLastError()) - - if BIO_set_conn_hostname(sock.bio, address & ":" & $port) != 1: - raiseOSError(osLastError()) - - if BIO_do_connect(sock.bio) <= 0: - ERR_print_errors_fp(stderr) - raiseOSError(osLastError()) - - result = SSL_get_verify_result(sock.ssl) - -proc recvLine*(sock: SecureSocket, line: var TaintedString): bool = - ## Acts in a similar fashion to the `recvLine` in the sockets module. - ## Returns false when no data is available to be read. - ## `Line` must be initialized and not nil! - setLen(line.string, 0) - while true: - var c: array[0..0, char] - var n = BIO_read(sock.bio, addr c, c.len.cint) - if n <= 0: return false - if c[0] == '\r': - n = BIO_read(sock.bio, addr c, c.len.cint) - if n > 0 and c[0] == '\L': - return true - elif n <= 0: - return false - elif c[0] == '\L': return true - add(line.string, c[0]) - - -proc send*(sock: SecureSocket, data: string) = - ## Writes `data` to the socket. - if BIO_write(sock.bio, data, data.len.cint) <= 0: - raiseOSError(osLastError()) - -proc close*(sock: SecureSocket) = - ## Closes the socket - if BIO_free(sock.bio) <= 0: - ERR_print_errors_fp(stderr) - raiseOSError(osLastError()) - -when not defined(testing) and isMainModule: - var s: SecureSocket - echo connect(s, "smtp.gmail.com", 465) - - #var buffer: array[0..255, char] - #echo BIO_read(bio, buffer, buffer.len) - var buffer: string = "" - - echo s.recvLine(buffer) - echo buffer - echo buffer.len - diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim deleted file mode 100644 index a81e8c0a8..000000000 --- a/lib/pure/httpserver.nim +++ /dev/null @@ -1,535 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2012 Andreas Rumpf, Dominik Picheta -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module implements a simple HTTP-Server. -## -## **Warning**: This module will soon be deprecated in favour of -## the ``asyncdispatch`` module, you should use it instead. -## -## Example: -## -## .. code-block:: nim -## import strutils, sockets, httpserver -## -## var counter = 0 -## proc handleRequest(client: Socket, path, query: string): bool {.procvar.} = -## inc(counter) -## client.send("Hello for the $#th time." % $counter & wwwNL) -## return false # do not stop processing -## -## run(handleRequest, Port(80)) -## - -import parseutils, strutils, os, osproc, strtabs, streams, sockets, asyncio - -const - wwwNL* = "\r\L" - ServerSig = "Server: httpserver.nim/1.0.0" & wwwNL - -# --------------- output messages -------------------------------------------- - -proc sendTextContentType(client: Socket) = - send(client, "Content-type: text/html" & wwwNL) - send(client, wwwNL) - -proc sendStatus(client: Socket, status: string) = - send(client, "HTTP/1.1 " & status & wwwNL) - -proc badRequest(client: Socket) = - # Inform the client that a request it has made has a problem. - send(client, "HTTP/1.1 400 Bad Request" & wwwNL) - sendTextContentType(client) - send(client, "<p>Your browser sent a bad request, " & - "such as a POST without a Content-Length.</p>" & wwwNL) - -when false: - proc cannotExec(client: Socket) = - send(client, "HTTP/1.1 500 Internal Server Error" & wwwNL) - sendTextContentType(client) - send(client, "<P>Error prohibited CGI execution." & wwwNL) - -proc headers(client: Socket, filename: string) = - # XXX could use filename to determine file type - send(client, "HTTP/1.1 200 OK" & wwwNL) - send(client, ServerSig) - sendTextContentType(client) - -proc notFound(client: Socket) = - send(client, "HTTP/1.1 404 NOT FOUND" & wwwNL) - send(client, ServerSig) - sendTextContentType(client) - send(client, "<html><title>Not Found</title>" & wwwNL) - send(client, "<body><p>The server could not fulfill" & wwwNL) - send(client, "your request because the resource specified" & wwwNL) - send(client, "is unavailable or nonexistent.</p>" & wwwNL) - send(client, "</body></html>" & wwwNL) - -proc unimplemented(client: Socket) = - send(client, "HTTP/1.1 501 Method Not Implemented" & wwwNL) - send(client, ServerSig) - sendTextContentType(client) - send(client, "<html><head><title>Method Not Implemented" & - "</title></head>" & - "<body><p>HTTP request method not supported.</p>" & - "</body></HTML>" & wwwNL) - -# ----------------- file serving --------------------------------------------- - -when false: - proc discardHeaders(client: Socket) = skip(client) - -proc serveFile*(client: Socket, filename: string) = - ## serves a file to the client. - var f: File - if open(f, filename): - headers(client, filename) - const bufSize = 8000 # != 8K might be good for memory manager - var buf = alloc(bufsize) - while true: - var bytesread = readBuffer(f, buf, bufsize) - if bytesread > 0: - var byteswritten = send(client, buf, bytesread) - if bytesread != bytesWritten: - dealloc(buf) - close(f) - raiseOSError(osLastError()) - if bytesread != bufSize: break - dealloc(buf) - close(f) - else: - notFound(client) - -# ------------------ CGI execution ------------------------------------------- -when false: - # TODO: Fix this, or get rid of it. - type - RequestMethod = enum reqGet, reqPost - - proc executeCgi(client: Socket, path, query: string, meth: RequestMethod) = - var env = newStringTable(modeCaseInsensitive) - var contentLength = -1 - case meth - of reqGet: - discardHeaders(client) - - env["REQUEST_METHOD"] = "GET" - env["QUERY_STRING"] = query - of reqPost: - var buf = TaintedString"" - var dataAvail = false - while dataAvail: - dataAvail = recvLine(client, buf) # TODO: This is incorrect. - var L = toLowerAscii(buf.string) - if L.startsWith("content-length:"): - var i = len("content-length:") - while L[i] in Whitespace: inc(i) - contentLength = parseInt(substr(L, i)) - - if contentLength < 0: - badRequest(client) - return - - env["REQUEST_METHOD"] = "POST" - env["CONTENT_LENGTH"] = $contentLength - - send(client, "HTTP/1.0 200 OK" & wwwNL) - - var process = startProcess(command=path, env=env) - if meth == reqPost: - # get from client and post to CGI program: - var buf = alloc(contentLength) - if recv(client, buf, contentLength) != contentLength: - dealloc(buf) - raiseOSError() - var inp = process.inputStream - inp.writeData(buf, contentLength) - dealloc(buf) - - var outp = process.outputStream - var line = newStringOfCap(120).TaintedString - while true: - if outp.readLine(line): - send(client, line.string) - send(client, wwwNL) - elif not running(process): break - - # --------------- Server Setup ----------------------------------------------- - - proc acceptRequest(client: Socket) = - var cgi = false - var query = "" - var buf = TaintedString"" - discard recvLine(client, buf) - var path = "" - var data = buf.string.split() - var meth = reqGet - - var q = find(data[1], '?') - - # extract path - if q >= 0: - # strip "?..." from path, this may be found in both POST and GET - path = "." & data[1].substr(0, q-1) - else: - path = "." & data[1] - # path starts with "/", by adding "." in front of it we serve files from cwd - - if cmpIgnoreCase(data[0], "GET") == 0: - if q >= 0: - cgi = true - query = data[1].substr(q+1) - elif cmpIgnoreCase(data[0], "POST") == 0: - cgi = true - meth = reqPost - else: - unimplemented(client) - - if path[path.len-1] == '/' or existsDir(path): - path = path / "index.html" - - if not existsFile(path): - discardHeaders(client) - notFound(client) - else: - when defined(Windows): - var ext = splitFile(path).ext.toLowerAscii - if ext == ".exe" or ext == ".cgi": - # XXX: extract interpreter information here? - cgi = true - else: - if {fpUserExec, fpGroupExec, fpOthersExec} * path.getFilePermissions != {}: - cgi = true - if not cgi: - serveFile(client, path) - else: - executeCgi(client, path, query, meth) - -type - Server* = object of RootObj ## contains the current server state - socket: Socket - port: Port - client*: Socket ## the socket to write the file data to - reqMethod*: string ## Request method. GET or POST. - path*, query*: string ## path and query the client requested - headers*: StringTableRef ## headers with which the client made the request - body*: string ## only set with POST requests - ip*: string ## ip address of the requesting client - - PAsyncHTTPServer* = ref AsyncHTTPServer - AsyncHTTPServer = object of Server - asyncSocket: AsyncSocket - -proc open*(s: var Server, port = Port(80), reuseAddr = false) = - ## creates a new server at port `port`. If ``port == 0`` a free port is - ## acquired that can be accessed later by the ``port`` proc. - s.socket = socket(AF_INET) - if s.socket == invalidSocket: raiseOSError(osLastError()) - if reuseAddr: - s.socket.setSockOpt(OptReuseAddr, true) - bindAddr(s.socket, port) - listen(s.socket) - - if port == Port(0): - s.port = getSockName(s.socket) - else: - s.port = port - s.client = invalidSocket - s.reqMethod = "" - s.body = "" - s.path = "" - s.query = "" - s.headers = {:}.newStringTable() - -proc port*(s: var Server): Port = - ## get the port number the server has acquired. - result = s.port - -proc next*(s: var Server) = - ## proceed to the first/next request. - var client: Socket - new(client) - var ip: string - acceptAddr(s.socket, client, ip) - s.client = client - s.ip = ip - s.headers = newStringTable(modeCaseInsensitive) - #headers(s.client, "") - var data = "" - s.client.readLine(data) - if data == "": - # Socket disconnected - s.client.close() - next(s) - return - var header = "" - while true: - s.client.readLine(header) - if header == "\c\L": break - if header != "": - var i = 0 - var key = "" - var value = "" - i = header.parseUntil(key, ':') - inc(i) # skip : - i += header.skipWhiteSpace(i) - i += header.parseUntil(value, {'\c', '\L'}, i) - s.headers[key] = value - else: - s.client.close() - next(s) - return - - var i = skipWhitespace(data) - if skipIgnoreCase(data, "GET") > 0: - s.reqMethod = "GET" - inc(i, 3) - elif skipIgnoreCase(data, "POST") > 0: - s.reqMethod = "POST" - inc(i, 4) - else: - unimplemented(s.client) - s.client.close() - next(s) - return - - if s.reqMethod == "POST": - # Check for Expect header - if s.headers.hasKey("Expect"): - if s.headers["Expect"].toLowerAscii == "100-continue": - s.client.sendStatus("100 Continue") - else: - s.client.sendStatus("417 Expectation Failed") - - # Read the body - # - Check for Content-length header - if s.headers.hasKey("Content-Length"): - var contentLength = 0 - if parseInt(s.headers["Content-Length"], contentLength) == 0: - badRequest(s.client) - s.client.close() - next(s) - return - else: - var totalRead = 0 - var totalBody = "" - while totalRead < contentLength: - var chunkSize = 8000 - if (contentLength - totalRead) < 8000: - chunkSize = (contentLength - totalRead) - var bodyData = newString(chunkSize) - var octetsRead = s.client.recv(cstring(bodyData), chunkSize) - if octetsRead <= 0: - s.client.close() - next(s) - return - totalRead += octetsRead - totalBody.add(bodyData) - if totalBody.len != contentLength: - s.client.close() - next(s) - return - - s.body = totalBody - else: - badRequest(s.client) - s.client.close() - next(s) - return - - var L = skipWhitespace(data, i) - inc(i, L) - # XXX we ignore "HTTP/1.1" etc. for now here - var query = 0 - var last = i - while last < data.len and data[last] notin Whitespace: - if data[last] == '?' and query == 0: query = last - inc(last) - if query > 0: - s.query = data.substr(query+1, last-1) - s.path = data.substr(i, query-1) - else: - s.query = "" - s.path = data.substr(i, last-1) - -proc close*(s: Server) = - ## closes the server (and the socket the server uses). - close(s.socket) - -proc run*(handleRequest: proc (client: Socket, - path, query: string): bool {.closure.}, - port = Port(80)) = - ## encapsulates the server object and main loop - var s: Server - open(s, port, reuseAddr = true) - #echo("httpserver running on port ", s.port) - while true: - next(s) - if handleRequest(s.client, s.path, s.query): break - close(s.client) - close(s) - -# -- AsyncIO begin - -proc nextAsync(s: PAsyncHTTPServer) = - ## proceed to the first/next request. - var client: Socket - new(client) - var ip: string - acceptAddr(getSocket(s.asyncSocket), client, ip) - s.client = client - s.ip = ip - s.headers = newStringTable(modeCaseInsensitive) - #headers(s.client, "") - var data = "" - s.client.readLine(data) - if data == "": - # Socket disconnected - s.client.close() - return - var header = "" - while true: - s.client.readLine(header) # TODO: Very inefficient here. Prone to DOS. - if header == "\c\L": break - if header != "": - var i = 0 - var key = "" - var value = "" - i = header.parseUntil(key, ':') - inc(i) # skip : - if i < header.len: - i += header.skipWhiteSpace(i) - i += header.parseUntil(value, {'\c', '\L'}, i) - s.headers[key] = value - else: - s.client.close() - return - - var i = skipWhitespace(data) - if skipIgnoreCase(data, "GET") > 0: - s.reqMethod = "GET" - inc(i, 3) - elif skipIgnoreCase(data, "POST") > 0: - s.reqMethod = "POST" - inc(i, 4) - else: - unimplemented(s.client) - s.client.close() - return - - if s.reqMethod == "POST": - # Check for Expect header - if s.headers.hasKey("Expect"): - if s.headers["Expect"].toLowerAscii == "100-continue": - s.client.sendStatus("100 Continue") - else: - s.client.sendStatus("417 Expectation Failed") - - # Read the body - # - Check for Content-length header - if s.headers.hasKey("Content-Length"): - var contentLength = 0 - if parseInt(s.headers["Content-Length"], contentLength) == 0: - badRequest(s.client) - s.client.close() - return - else: - var totalRead = 0 - var totalBody = "" - while totalRead < contentLength: - var chunkSize = 8000 - if (contentLength - totalRead) < 8000: - chunkSize = (contentLength - totalRead) - var bodyData = newString(chunkSize) - var octetsRead = s.client.recv(cstring(bodyData), chunkSize) - if octetsRead <= 0: - s.client.close() - return - totalRead += octetsRead - totalBody.add(bodyData) - if totalBody.len != contentLength: - s.client.close() - return - - s.body = totalBody - else: - badRequest(s.client) - s.client.close() - return - - var L = skipWhitespace(data, i) - inc(i, L) - # XXX we ignore "HTTP/1.1" etc. for now here - var query = 0 - var last = i - while last < data.len and data[last] notin Whitespace: - if data[last] == '?' and query == 0: query = last - inc(last) - if query > 0: - s.query = data.substr(query+1, last-1) - s.path = data.substr(i, query-1) - else: - s.query = "" - s.path = data.substr(i, last-1) - -proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: Socket, - path, query: string): bool {.closure, gcsafe.}, - port = Port(80), address = "", - reuseAddr = false): PAsyncHTTPServer = - ## Creates an Asynchronous HTTP server at ``port``. - var capturedRet: PAsyncHTTPServer - new(capturedRet) - capturedRet.asyncSocket = asyncSocket() - capturedRet.asyncSocket.handleAccept = - proc (s: AsyncSocket) = - nextAsync(capturedRet) - let quit = handleRequest(capturedRet, capturedRet.client, capturedRet.path, - capturedRet.query) - if quit: capturedRet.asyncSocket.close() - if reuseAddr: - capturedRet.asyncSocket.setSockOpt(OptReuseAddr, true) - - capturedRet.asyncSocket.bindAddr(port, address) - capturedRet.asyncSocket.listen() - if port == Port(0): - capturedRet.port = getSockName(capturedRet.asyncSocket) - else: - capturedRet.port = port - - capturedRet.client = invalidSocket - capturedRet.reqMethod = "" - capturedRet.body = "" - capturedRet.path = "" - capturedRet.query = "" - capturedRet.headers = {:}.newStringTable() - result = capturedRet - -proc register*(d: Dispatcher, s: PAsyncHTTPServer) = - ## Registers a ``PAsyncHTTPServer`` with a ``Dispatcher``. - d.register(s.asyncSocket) - -proc close*(h: PAsyncHTTPServer) = - ## Closes the ``PAsyncHTTPServer``. - h.asyncSocket.close() - -when not defined(testing) and isMainModule: - var counter = 0 - - var s: Server - open(s, Port(0)) - echo("httpserver running on port ", s.port) - while true: - next(s) - - inc(counter) - s.client.send("Hello, Andreas, for the $#th time. $# ? $#" % [ - $counter, s.path, s.query] & wwwNL) - - close(s.client) - close(s) - diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim deleted file mode 100644 index 97223ed01..000000000 --- a/lib/pure/matchers.nim +++ /dev/null @@ -1,68 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2015 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module contains various string matchers for email addresses, etc. -## -## **Warning:** This module is deprecated since version 0.14.0. -{.deprecated.} - -{.deadCodeElim: on.} # dce option deprecated - -{.push debugger:off .} # the user does not want to trace a part - # of the standard library! - -include "system/inclrtl" - -import parseutils, strutils - -proc validEmailAddress*(s: string): bool {.noSideEffect, - rtl, extern: "nsuValidEmailAddress".} = - ## returns true if `s` seems to be a valid e-mail address. - ## The checking also uses a domain list. - const - chars = Letters + Digits + {'!','#','$','%','&', - '\'','*','+','/','=','?','^','_','`','{','}','|','~','-','.'} - var i = 0 - if i >= s.len or s[i] notin chars or s[i] == '.': return false - while i < s.len and s[i] in chars: - if i+1 < s.len and s[i] == '.' and s[i+1] == '.': return false - inc(i) - if i >= s.len or s[i] != '@': return false - var j = len(s)-1 - if j >= 0 and s[j] notin Letters: return false - while j >= i and s[j] in Letters: dec(j) - inc(i) # skip '@' - while i < s.len and s[i] in {'0'..'9', 'a'..'z', '-', '.'}: inc(i) - if i != s.len: return false - - var x = substr(s, j+1) - if len(x) == 2 and x[0] in Letters and x[1] in Letters: return true - case toLowerAscii(x) - of "com", "org", "net", "gov", "mil", "biz", "info", "mobi", "name", - "aero", "jobs", "museum": return true - else: return false - -proc parseInt*(s: string, value: var int, validRange: HSlice[int, int]) {. - noSideEffect, rtl, extern: "nmatchParseInt".} = - ## parses `s` into an integer in the range `validRange`. If successful, - ## `value` is modified to contain the result. Otherwise no exception is - ## raised and `value` is not touched; this way a reasonable default value - ## won't be overwritten. - var x = value - try: - discard parseutils.parseInt(s, x, 0) - except OverflowError: - discard - if x in validRange: value = x - -when isMainModule: - doAssert "wuseldusel@codehome.com".validEmailAddress - -{.pop.} - diff --git a/tests/manyloc/keineschweine/enet_server/enet_server.nim b/tests/manyloc/keineschweine/enet_server/enet_server.nim index 3bb259386..336e57755 100644 --- a/tests/manyloc/keineschweine/enet_server/enet_server.nim +++ b/tests/manyloc/keineschweine/enet_server/enet_server.nim @@ -103,7 +103,7 @@ handlers[HZoneJoinReq] = proc(client: PClient; buffer: PBuffer) = when true: - import parseopt, matchers, os, json + import parseopt, os, json if enetInit() != 0: diff --git a/tests/manyloc/keineschweine/server/old_dirserver.nim b/tests/manyloc/keineschweine/server/old_dirserver.nim index cfb0b0377..390b738aa 100644 --- a/tests/manyloc/keineschweine/server/old_dirserver.nim +++ b/tests/manyloc/keineschweine/server/old_dirserver.nim @@ -157,7 +157,7 @@ proc poll*(timeout: int = 250) = c.outputBuf.flush() when true: - import parseopt, matchers, strutils + import parseopt, strutils var cfgFile = "dirserver_settings.json" for kind, key, val in getOpt(): case kind diff --git a/tests/manyloc/keineschweine/server/old_sg_server.nim b/tests/manyloc/keineschweine/server/old_sg_server.nim index d046df9dd..473880e2b 100644 --- a/tests/manyloc/keineschweine/server/old_sg_server.nim +++ b/tests/manyloc/keineschweine/server/old_sg_server.nim @@ -142,7 +142,7 @@ proc poll*(timeout: int = 250) = c.outputBuf.flush() when true: - import parseopt, matchers, strutils + import parseopt, strutils var zoneCfgFile = "./server_settings.json" for kind, key, val in getOpt(): case kind diff --git a/tests/threads/tactors.nim b/tests/threads/tactors.nim deleted file mode 100644 index ea052b9bd..000000000 --- a/tests/threads/tactors.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - outputsub: "150" -""" - -import actors - -var - pool: ActorPool[int, void] -createActorPool(pool) -for i in 0 ..< 300: - pool.spawn(i, proc (x: int) {.thread.} = echo x) -pool.join() - diff --git a/tests/threads/tactors2.nim b/tests/threads/tactors2.nim deleted file mode 100644 index e8afe203c..000000000 --- a/tests/threads/tactors2.nim +++ /dev/null @@ -1,25 +0,0 @@ -discard """ - output: "1" -""" - -import actors - -type - some_type {.pure, final.} = object - bla: int - -proc thread_proc(input: some_type): some_type {.thread.} = - result.bla = 1 - -proc main() = - var actorPool: ActorPool[some_type, some_type] - createActorPool(actorPool, 1) - - var some_data: some_type - - var inchannel = spawn(actorPool, some_data, thread_proc) - var recv_data = ^inchannel - close(inchannel[]) - echo recv_data.bla - -main() diff --git a/tests/threads/trecursive_actor.nim b/tests/threads/trecursive_actor.nim deleted file mode 100644 index d7072aa53..000000000 --- a/tests/threads/trecursive_actor.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - disabled: yes - outputsub: "0" -""" - -import actors - -var - a: TActorPool[int, void] -createActorPool(a) - -proc task(i: int) {.thread.} = - echo i - if i != 0: a.spawn (i-1, task) - -# count from 9 till 0 and check 0 is somewhere in the output -a.spawn(9, task) -a.join() - - diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim index e09c53407..1b210b2bf 100644 --- a/tests/tuples/tuple_with_nil.nim +++ b/tests/tuples/tuple_with_nil.nim @@ -4,7 +4,6 @@ import parseutils import unicode import math import fenv -#import unsigned import pegs import streams diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 658b9ead7..6741fcf5d 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -126,7 +126,6 @@ lib/js/asyncjs.nim lib/pure/os.nim lib/pure/strutils.nim lib/pure/math.nim -lib/pure/matchers.nim lib/std/editdistance.nim lib/std/wordwrap.nim lib/experimental/diff.nim @@ -161,10 +160,8 @@ lib/impure/db_mysql.nim lib/impure/db_sqlite.nim lib/impure/db_odbc.nim lib/pure/db_common.nim -lib/pure/httpserver.nim lib/pure/httpclient.nim lib/pure/smtp.nim -lib/impure/ssl.nim lib/pure/ropes.nim lib/pure/unidecode/unidecode.nim lib/pure/xmlparser.nim @@ -218,7 +215,6 @@ lib/pure/selectors.nim lib/pure/sugar.nim lib/pure/collections/chains.nim lib/pure/asyncfile.nim -lib/deprecated/pure/ftpclient.nim lib/pure/asyncftpclient.nim lib/pure/lenientops.nim lib/pure/md5.nim |