Replace double backticks with single backticks - Part 3 out of ~7 (#17207)

This commit is contained in:
Danil Yarantsev 2021-03-01 10:22:05 +03:00 • committed by GitHub
commit aef55a7a88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 159 additions and 159 deletions

View file

@ -37,7 +37,7 @@ proc rightSize*(count: Natural): int {.inline, deprecated: "Deprecated since 1.4
## **Deprecated since Nim v1.4.0**, it is not needed anymore ## **Deprecated since Nim v1.4.0**, it is not needed anymore
## because picking the correct size is done internally. ## because picking the correct size is done internally.
## ##
## Return the value of ``initialSize`` to support ``count`` items. ## Return the value of `initialSize` to support `count` items.
## ##
## If more items are expected to be added, simply add that ## If more items are expected to be added, simply add that
## expected extra amount to the parameter before calling this. ## expected extra amount to the parameter before calling this.

View file

@ -7,7 +7,7 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
## The ``sets`` module implements an efficient `hash set`:idx: and ## The `sets` module implements an efficient `hash set`:idx: and
## ordered hash set. ## ordered hash set.
## ##
## Hash sets are different from the `built in set type ## Hash sets are different from the `built in set type
@ -40,7 +40,7 @@
## ##
## ##
## Note: The data types declared here have *value semantics*: This means ## Note: The data types declared here have *value semantics*: This means
## that ``=`` performs a copy of the set. ## that `=` performs a copy of the set.
## ##
## **See also:** ## **See also:**
## * `intsets module <intsets.html>`_ for efficient int sets ## * `intsets module <intsets.html>`_ for efficient int sets
@ -113,7 +113,7 @@ proc initHashSet*[A](initialSize = defaultInitialSize): HashSet[A] =
## Wrapper around `init proc <#init,HashSet[A]>`_ for initialization of ## Wrapper around `init proc <#init,HashSet[A]>`_ for initialization of
## hash sets. ## hash sets.
## ##
## Returns an empty hash set you can assign directly in ``var`` blocks in a ## Returns an empty hash set you can assign directly in `var` blocks in a
## single line. ## single line.
## ##
## Starting from Nim v0.20, sets are initialized by default and it is ## Starting from Nim v0.20, sets are initialized by default and it is
@ -130,7 +130,7 @@ proc initHashSet*[A](initialSize = defaultInitialSize): HashSet[A] =
proc `[]`*[A](s: var HashSet[A], key: A): var A = proc `[]`*[A](s: var HashSet[A], key: A): var A =
## Returns the element that is actually stored in `s` which has the same ## Returns the element that is actually stored in `s` which has the same
## value as `key` or raises the ``KeyError`` exception. ## value as `key` or raises the `KeyError` exception.
## ##
## This is useful when one overloaded `hash` and `==` but still needs ## This is useful when one overloaded `hash` and `==` but still needs
## reference semantics for sharing. ## reference semantics for sharing.
@ -652,7 +652,7 @@ proc initOrderedSet*[A](initialSize = defaultInitialSize): OrderedSet[A] =
## Wrapper around `init proc <#init,OrderedSet[A]>`_ for initialization of ## Wrapper around `init proc <#init,OrderedSet[A]>`_ for initialization of
## ordered hash sets. ## ordered hash sets.
## ##
## Returns an empty ordered hash set you can assign directly in ``var`` blocks ## Returns an empty ordered hash set you can assign directly in `var` blocks
## in a single line. ## in a single line.
## ##
## Starting from Nim v0.20, sets are initialized by default and it is ## Starting from Nim v0.20, sets are initialized by default and it is

View file

@ -7,8 +7,8 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
## Contains functionality shared between the ``httpclient`` and ## Contains functionality shared between the `httpclient` and
## ``asynchttpserver`` modules. ## `asynchttpserver` modules.
## ##
## Unstable API. ## Unstable API.
import std/private/since import std/private/since
@ -130,7 +130,7 @@ func toCaseInsensitive(headers: HttpHeaders, s: string): string {.inline.} =
return if headers.isTitleCase: toTitleCase(s) else: toLowerAscii(s) return if headers.isTitleCase: toTitleCase(s) else: toLowerAscii(s)
func newHttpHeaders*(titleCase=false): HttpHeaders = func newHttpHeaders*(titleCase=false): HttpHeaders =
## Returns a new ``HttpHeaders`` object. if ``titleCase`` is set to true, ## Returns a new `HttpHeaders` object. if `titleCase` is set to true,
## headers are passed to the server in title case (e.g. "Content-Length") ## headers are passed to the server in title case (e.g. "Content-Length")
new result new result
result.table = newTable[string, seq[string]]() result.table = newTable[string, seq[string]]()
@ -138,7 +138,7 @@ func newHttpHeaders*(titleCase=false): HttpHeaders =
func newHttpHeaders*(keyValuePairs: func newHttpHeaders*(keyValuePairs:
openArray[tuple[key: string, val: string]], titleCase=false): HttpHeaders = openArray[tuple[key: string, val: string]], titleCase=false): HttpHeaders =
## Returns a new ``HttpHeaders`` object from an array. if ``titleCase`` is set to true, ## Returns a new `HttpHeaders` object from an array. if `titleCase` is set to true,
## headers are passed to the server in title case (e.g. "Content-Length") ## headers are passed to the server in title case (e.g. "Content-Length")
new result new result
result.table = newTable[string, seq[string]]() result.table = newTable[string, seq[string]]()
@ -159,13 +159,13 @@ proc clear*(headers: HttpHeaders) {.inline.} =
headers.table.clear() headers.table.clear()
func `[]`*(headers: HttpHeaders, key: string): HttpHeaderValues = func `[]`*(headers: HttpHeaders, key: string): HttpHeaderValues =
## Returns the values associated with the given ``key``. If the returned ## Returns the values associated with the given `key`. If the returned
## values are passed to a procedure expecting a ``string``, the first ## values are passed to a procedure expecting a `string`, the first
## value is automatically picked. If there are ## value is automatically picked. If there are
## no values associated with the key, an exception is raised. ## no values associated with the key, an exception is raised.
## ##
## To access multiple values of a key, use the overloaded ``[]`` below or ## To access multiple values of a key, use the overloaded `[]` below or
## to get all of them access the ``table`` field directly. ## to get all of them access the `table` field directly.
{.cast(noSideEffect).}: {.cast(noSideEffect).}:
return headers.table[headers.toCaseInsensitive(key)].HttpHeaderValues return headers.table[headers.toCaseInsensitive(key)].HttpHeaderValues
@ -173,21 +173,21 @@ converter toString*(values: HttpHeaderValues): string =
return seq[string](values)[0] return seq[string](values)[0]
func `[]`*(headers: HttpHeaders, key: string, i: int): string = func `[]`*(headers: HttpHeaders, key: string, i: int): string =
## Returns the ``i``'th value associated with the given key. If there are ## Returns the `i`'th value associated with the given key. If there are
## no values associated with the key or the ``i``'th value doesn't exist, ## no values associated with the key or the `i`'th value doesn't exist,
## an exception is raised. ## an exception is raised.
{.cast(noSideEffect).}: {.cast(noSideEffect).}:
return headers.table[headers.toCaseInsensitive(key)][i] return headers.table[headers.toCaseInsensitive(key)][i]
proc `[]=`*(headers: HttpHeaders, key, value: string) = proc `[]=`*(headers: HttpHeaders, key, value: string) =
## Sets the header entries associated with ``key`` to the specified value. ## Sets the header entries associated with `key` to the specified value.
## Replaces any existing values. ## Replaces any existing values.
headers.table[headers.toCaseInsensitive(key)] = @[value] headers.table[headers.toCaseInsensitive(key)] = @[value]
proc `[]=`*(headers: HttpHeaders, key: string, value: seq[string]) = proc `[]=`*(headers: HttpHeaders, key: string, value: seq[string]) =
## Sets the header entries associated with ``key`` to the specified list of ## Sets the header entries associated with `key` to the specified list of
## values. Replaces any existing values. If ``value`` is empty, ## values. Replaces any existing values. If `value` is empty,
## deletes the header entries associated with ``key``. ## deletes the header entries associated with `key`.
if value.len > 0: if value.len > 0:
headers.table[headers.toCaseInsensitive(key)] = value headers.table[headers.toCaseInsensitive(key)] = value
else: else:
@ -202,7 +202,7 @@ proc add*(headers: HttpHeaders, key, value: string) =
headers.table[headers.toCaseInsensitive(key)].add(value) headers.table[headers.toCaseInsensitive(key)].add(value)
proc del*(headers: HttpHeaders, key: string) = proc del*(headers: HttpHeaders, key: string) =
## Deletes the header entries associated with ``key`` ## Deletes the header entries associated with `key`
headers.table.del(headers.toCaseInsensitive(key)) headers.table.del(headers.toCaseInsensitive(key))
iterator pairs*(headers: HttpHeaders): tuple[key, value: string] = iterator pairs*(headers: HttpHeaders): tuple[key, value: string] =
@ -212,7 +212,7 @@ iterator pairs*(headers: HttpHeaders): tuple[key, value: string] =
yield (k, value) yield (k, value)
func contains*(values: HttpHeaderValues, value: string): bool = func contains*(values: HttpHeaderValues, value: string): bool =
## Determines if ``value`` is one of the values inside ``values``. Comparison ## Determines if `value` is one of the values inside `values`. Comparison
## is performed without case sensitivity. ## is performed without case sensitivity.
for val in seq[string](values): for val in seq[string](values):
if val.toLowerAscii == value.toLowerAscii: return true if val.toLowerAscii == value.toLowerAscii: return true
@ -222,8 +222,8 @@ func hasKey*(headers: HttpHeaders, key: string): bool =
func getOrDefault*(headers: HttpHeaders, key: string, func getOrDefault*(headers: HttpHeaders, key: string,
default = @[""].HttpHeaderValues): HttpHeaderValues = default = @[""].HttpHeaderValues): HttpHeaderValues =
## Returns the values associated with the given ``key``. If there are no ## Returns the values associated with the given `key`. If there are no
## values associated with the key, then ``default`` is returned. ## values associated with the key, then `default` is returned.
if headers.hasKey(key): if headers.hasKey(key):
return headers[key] return headers[key]
else: else:
@ -245,7 +245,7 @@ func parseList(line: string, list: var seq[string], start: int): int =
func parseHeader*(line: string): tuple[key: string, value: seq[string]] = func parseHeader*(line: string): tuple[key: string, value: seq[string]] =
## Parses a single raw header HTTP line into key value pairs. ## Parses a single raw header HTTP line into key value pairs.
## ##
## Used by ``asynchttpserver`` and ``httpclient`` internally and should not ## Used by `asynchttpserver` and `httpclient` internally and should not
## be used by you. ## be used by you.
result.value = @[] result.value = @[]
var i = 0 var i = 0
@ -277,7 +277,7 @@ func contains*(methods: set[HttpMethod], x: string): bool =
return parseEnum[HttpMethod](x) in methods return parseEnum[HttpMethod](x) in methods
func `$`*(code: HttpCode): string = func `$`*(code: HttpCode): string =
## Converts the specified ``HttpCode`` into a HTTP status. ## Converts the specified `HttpCode` into a HTTP status.
runnableExamples: runnableExamples:
doAssert($Http404 == "404 Not Found") doAssert($Http404 == "404 Not Found")
case code.int case code.int
@ -353,29 +353,29 @@ proc `==`*(rawCode: string, code: HttpCode): bool
## ##
## **Note**: According to HTTP/1.1 specification, the reason phrase is ## **Note**: According to HTTP/1.1 specification, the reason phrase is
## optional and should be ignored by the client, making this ## optional and should be ignored by the client, making this
## proc only suitable for comparing the ``HttpCode`` against the ## proc only suitable for comparing the `HttpCode` against the
## string form of itself. ## string form of itself.
return cmpIgnoreCase(rawCode, $code) == 0 return cmpIgnoreCase(rawCode, $code) == 0
func is1xx*(code: HttpCode): bool {.inline, since: (1, 5).} = func is1xx*(code: HttpCode): bool {.inline, since: (1, 5).} =
## Determines whether ``code`` is a 1xx HTTP status code. ## Determines whether `code` is a 1xx HTTP status code.
runnableExamples: runnableExamples:
doAssert is1xx(HttpCode(103)) doAssert is1xx(HttpCode(103))
code.int in {100 .. 199} code.int in {100 .. 199}
func is2xx*(code: HttpCode): bool {.inline.} = func is2xx*(code: HttpCode): bool {.inline.} =
## Determines whether ``code`` is a 2xx HTTP status code. ## Determines whether `code` is a 2xx HTTP status code.
code.int in {200 .. 299} code.int in {200 .. 299}
func is3xx*(code: HttpCode): bool {.inline.} = func is3xx*(code: HttpCode): bool {.inline.} =
## Determines whether ``code`` is a 3xx HTTP status code. ## Determines whether `code` is a 3xx HTTP status code.
code.int in {300 .. 399} code.int in {300 .. 399}
func is4xx*(code: HttpCode): bool {.inline.} = func is4xx*(code: HttpCode): bool {.inline.} =
## Determines whether ``code`` is a 4xx HTTP status code. ## Determines whether `code` is a 4xx HTTP status code.
code.int in {400 .. 499} code.int in {400 .. 499}
func is5xx*(code: HttpCode): bool {.inline.} = func is5xx*(code: HttpCode): bool {.inline.} =
## Determines whether ``code`` is a 5xx HTTP status code. ## Determines whether `code` is a 5xx HTTP status code.
code.int in {500 .. 599} code.int in {500 .. 599}

View file

@ -8,7 +8,7 @@
# #
## This module implements a low-level cross-platform sockets interface. Look ## This module implements a low-level cross-platform sockets interface. Look
## at the ``net`` module for the higher-level version. ## at the `net` module for the higher-level version.
# TODO: Clean up the exports a bit and everything else in general. # TODO: Clean up the exports a bit and everything else in general.
@ -112,19 +112,19 @@ else:
nativeAfUnix = posix.AF_UNIX nativeAfUnix = posix.AF_UNIX
proc `==`*(a, b: Port): bool {.borrow.} proc `==`*(a, b: Port): bool {.borrow.}
## ``==`` for ports. ## `==` for ports.
proc `$`*(p: Port): string {.borrow.} proc `$`*(p: Port): string {.borrow.}
## Returns the port number as a string ## Returns the port number as a string
proc toInt*(domain: Domain): cint proc toInt*(domain: Domain): cint
## Converts the Domain enum to a platform-dependent ``cint``. ## Converts the Domain enum to a platform-dependent `cint`.
proc toInt*(typ: SockType): cint proc toInt*(typ: SockType): cint
## Converts the SockType enum to a platform-dependent ``cint``. ## Converts the SockType enum to a platform-dependent `cint`.
proc toInt*(p: Protocol): cint proc toInt*(p: Protocol): cint
## Converts the Protocol enum to a platform-dependent ``cint``. ## Converts the Protocol enum to a platform-dependent `cint`.
when not useWinVersion: when not useWinVersion:
proc toInt(domain: Domain): cint = proc toInt(domain: Domain): cint =
@ -135,8 +135,8 @@ when not useWinVersion:
of AF_INET6: result = posix.AF_INET6.cint of AF_INET6: result = posix.AF_INET6.cint
proc toKnownDomain*(family: cint): Option[Domain] = proc toKnownDomain*(family: cint): Option[Domain] =
## Converts the platform-dependent ``cint`` to the Domain or none(), ## Converts the platform-dependent `cint` to the Domain or none(),
## if the ``cint`` is not known. ## if the `cint` is not known.
result = if family == posix.AF_UNSPEC: some(Domain.AF_UNSPEC) result = if family == posix.AF_UNSPEC: some(Domain.AF_UNSPEC)
elif family == posix.AF_UNIX: some(Domain.AF_UNIX) elif family == posix.AF_UNIX: some(Domain.AF_UNIX)
elif family == posix.AF_INET: some(Domain.AF_INET) elif family == posix.AF_INET: some(Domain.AF_INET)
@ -165,8 +165,8 @@ else:
result = toU32(ord(domain)).cint result = toU32(ord(domain)).cint
proc toKnownDomain*(family: cint): Option[Domain] = proc toKnownDomain*(family: cint): Option[Domain] =
## Converts the platform-dependent ``cint`` to the Domain or none(), ## Converts the platform-dependent `cint` to the Domain or none(),
## if the ``cint`` is not known. ## if the `cint` is not known.
result = if family == winlean.AF_UNSPEC: some(Domain.AF_UNSPEC) result = if family == winlean.AF_UNSPEC: some(Domain.AF_UNSPEC)
elif family == winlean.AF_INET: some(Domain.AF_INET) elif family == winlean.AF_INET: some(Domain.AF_INET)
elif family == winlean.AF_INET6: some(Domain.AF_INET6) elif family == winlean.AF_INET6: some(Domain.AF_INET6)
@ -202,7 +202,7 @@ proc toSockType*(protocol: Protocol): SockType =
SOCK_RAW SOCK_RAW
proc getProtoByName*(name: string): int {.since: (1, 3, 5).} = proc getProtoByName*(name: string): int {.since: (1, 3, 5).} =
## Returns a protocol code from the database that matches the protocol ``name``. ## Returns a protocol code from the database that matches the protocol `name`.
when useWinVersion: when useWinVersion:
let protoent = winlean.getprotobyname(name.cstring) let protoent = winlean.getprotobyname(name.cstring)
else: else:
@ -267,8 +267,8 @@ proc bindAddr*(socket: SocketHandle, name: ptr SockAddr,
proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [ proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [
ReadIOEffect].} = ReadIOEffect].} =
## Marks ``socket`` as accepting connections. ## Marks `socket` as accepting connections.
## ``Backlog`` specifies the maximum length of the ## `Backlog` specifies the maximum length of the
## queue of pending connections. ## queue of pending connections.
when useWinVersion: when useWinVersion:
result = winlean.listen(socket, cint(backlog)) result = winlean.listen(socket, cint(backlog))
@ -280,7 +280,7 @@ proc getAddrInfo*(address: string, port: Port, domain: Domain = AF_INET,
protocol: Protocol = IPPROTO_TCP): ptr AddrInfo = protocol: Protocol = IPPROTO_TCP): ptr AddrInfo =
## ##
## ##
## **Warning**: The resulting ``ptr AddrInfo`` must be freed using ``freeAddrInfo``! ## **Warning**: The resulting `ptr AddrInfo` must be freed using `freeAddrInfo`!
var hints: AddrInfo var hints: AddrInfo
result = nil result = nil
hints.ai_family = toInt(domain) hints.ai_family = toInt(domain)
@ -333,10 +333,10 @@ template htons*(x: uint16): untyped =
proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} = proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
## Searches the database from the beginning and finds the first entry for ## Searches the database from the beginning and finds the first entry for
## which the service name specified by ``name`` matches the s_name member ## which the service name specified by `name` matches the s_name member
## and the protocol name specified by ``proto`` matches the s_proto member. ## and the protocol name specified by `proto` matches the s_proto member.
## ##
## On posix this will search through the ``/etc/services`` file. ## On posix this will search through the `/etc/services` file.
when useWinVersion: when useWinVersion:
var s = winlean.getservbyname(name, proto) var s = winlean.getservbyname(name, proto)
else: else:
@ -349,10 +349,10 @@ proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} = proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} =
## Searches the database from the beginning and finds the first entry for ## Searches the database from the beginning and finds the first entry for
## which the port specified by ``port`` matches the s_port member and the ## which the port specified by `port` matches the s_port member and the
## protocol name specified by ``proto`` matches the s_proto member. ## protocol name specified by `proto` matches the s_proto member.
## ##
## On posix this will search through the ``/etc/services`` file. ## On posix this will search through the `/etc/services` file.
when useWinVersion: when useWinVersion:
var s = winlean.getservbyport(ze(int16(port)).cint, proto) var s = winlean.getservbyport(ze(int16(port)).cint, proto)
else: else:
@ -490,11 +490,11 @@ proc getAddrString*(sockAddr: ptr SockAddr): string =
raise newException(IOError, "Unknown socket family in getAddrString") raise newException(IOError, "Unknown socket family in getAddrString")
proc getAddrString*(sockAddr: ptr SockAddr, strAddress: var string) = proc getAddrString*(sockAddr: ptr SockAddr, strAddress: var string) =
## Stores in ``strAddress`` the string representation of the address inside ## Stores in `strAddress` the string representation of the address inside
## ``sockAddr`` ## `sockAddr`
## ##
## **Note** ## **Note**
## * ``strAddress`` must be initialized to 46 in length. ## * `strAddress` must be initialized to 46 in length.
assert(46 == len(strAddress), assert(46 == len(strAddress),
"`strAddress` was not initialized correctly. 46 != `len(strAddress)`") "`strAddress` was not initialized correctly. 46 != `len(strAddress)`")
if sockAddr.sa_family.cint == nativeAfInet: if sockAddr.sa_family.cint == nativeAfInet:
@ -682,12 +682,12 @@ proc pruneSocketSet(s: var seq[SocketHandle], fd: var TFdSet) =
setLen(s, L) setLen(s, L)
proc selectRead*(readfds: var seq[SocketHandle], timeout = 500): int = proc selectRead*(readfds: var seq[SocketHandle], timeout = 500): int =
## When a socket in ``readfds`` is ready to be read from then a non-zero ## When a socket in `readfds` is ready to be read from then a non-zero
## value will be returned specifying the count of the sockets which can be ## value will be returned specifying the count of the sockets which can be
## read from. The sockets which cannot be read from will also be removed ## read from. The sockets which cannot be read from will also be removed
## from ``readfds``. ## from `readfds`.
## ##
## ``timeout`` is specified in milliseconds and ``-1`` can be specified for ## `timeout` is specified in milliseconds and `-1` can be specified for
## an unlimited time. ## an unlimited time.
var tv {.noinit.}: Timeval = timeValFromMilliseconds(timeout) var tv {.noinit.}: Timeval = timeValFromMilliseconds(timeout)
@ -704,12 +704,12 @@ proc selectRead*(readfds: var seq[SocketHandle], timeout = 500): int =
proc selectWrite*(writefds: var seq[SocketHandle], proc selectWrite*(writefds: var seq[SocketHandle],
timeout = 500): int {.tags: [ReadIOEffect].} = timeout = 500): int {.tags: [ReadIOEffect].} =
## When a socket in ``writefds`` is ready to be written to then a non-zero ## When a socket in `writefds` is ready to be written to then a non-zero
## value will be returned specifying the count of the sockets which can be ## value will be returned specifying the count of the sockets which can be
## written to. The sockets which cannot be written to will also be removed ## written to. The sockets which cannot be written to will also be removed
## from ``writefds``. ## from `writefds`.
## ##
## ``timeout`` is specified in milliseconds and ``-1`` can be specified for ## `timeout` is specified in milliseconds and `-1` can be specified for
## an unlimited time. ## an unlimited time.
var tv {.noinit.}: Timeval = timeValFromMilliseconds(timeout) var tv {.noinit.}: Timeval = timeValFromMilliseconds(timeout)

View file

@ -9,18 +9,18 @@
## This module implements a high-level cross-platform sockets interface. ## This module implements a high-level cross-platform sockets interface.
## The procedures implemented in this module are primarily for blocking sockets. ## The procedures implemented in this module are primarily for blocking sockets.
## For asynchronous non-blocking sockets use the ``asyncnet`` module together ## For asynchronous non-blocking sockets use the `asyncnet` module together
## with the ``asyncdispatch`` module. ## with the `asyncdispatch` module.
## ##
## The first thing you will always need to do in order to start using sockets, ## The first thing you will always need to do in order to start using sockets,
## is to create a new instance of the ``Socket`` type using the ``newSocket`` ## is to create a new instance of the `Socket` type using the `newSocket`
## procedure. ## procedure.
## ##
## SSL ## SSL
## ==== ## ====
## ##
## In order to use the SSL procedures defined in this module, you will need to ## In order to use the SSL procedures defined in this module, you will need to
## compile your application with the ``-d:ssl`` flag. See the ## compile your application with the `-d:ssl` flag. See the
## `newContext<net.html#newContext%2Cstring%2Cstring%2Cstring%2Cstring>`_ ## `newContext<net.html#newContext%2Cstring%2Cstring%2Cstring%2Cstring>`_
## procedure for additional details. ## procedure for additional details.
## ##
@ -41,7 +41,7 @@
## Connecting to a server ## Connecting to a server
## ---------------------- ## ----------------------
## ##
## After you create a socket with the ``newSocket`` procedure, you can easily ## After you create a socket with the `newSocket` procedure, you can easily
## connect it to a server running at a known hostname (or IP address) and port. ## connect it to a server running at a known hostname (or IP address) and port.
## To do so over TCP, use the example below. ## To do so over TCP, use the example below.
## ##
@ -49,7 +49,7 @@
## var socket = newSocket() ## var socket = newSocket()
## socket.connect("google.com", Port(80)) ## socket.connect("google.com", Port(80))
## ##
## For SSL, use the following example (and make sure to compile with ``-d:ssl``): ## For SSL, use the following example (and make sure to compile with `-d:ssl`):
## ##
## .. code-block:: Nim ## .. code-block:: Nim
## var socket = newSocket() ## var socket = newSocket()
@ -68,15 +68,15 @@
## Creating a server ## Creating a server
## ----------------- ## -----------------
## ##
## After you create a socket with the ``newSocket`` procedure, you can create a ## After you create a socket with the `newSocket` procedure, you can create a
## TCP server by calling the ``bindAddr`` and ``listen`` procedures. ## TCP server by calling the `bindAddr` and `listen` procedures.
## ##
## .. code-block:: Nim ## .. code-block:: Nim
## var socket = newSocket() ## var socket = newSocket()
## socket.bindAddr(Port(1234)) ## socket.bindAddr(Port(1234))
## socket.listen() ## socket.listen()
## ##
## You can then begin accepting connections using the ``accept`` procedure. ## You can then begin accepting connections using the `accept` procedure.
## ##
## .. code-block:: Nim ## .. code-block:: Nim
## var client: Socket ## var client: Socket
@ -204,8 +204,8 @@ proc socketError*(socket: Socket, err: int = -1, async = false,
proc isDisconnectionError*(flags: set[SocketFlag], proc isDisconnectionError*(flags: set[SocketFlag],
lastError: OSErrorCode): bool = lastError: OSErrorCode): bool =
## Determines whether ``lastError`` is a disconnection error. Only does this ## Determines whether `lastError` is a disconnection error. Only does this
## if flags contains ``SafeDisconn``. ## if flags contains `SafeDisconn`.
when useWinVersion: when useWinVersion:
SocketFlag.SafeDisconn in flags and SocketFlag.SafeDisconn in flags and
(lastError.int32 == WSAECONNRESET or (lastError.int32 == WSAECONNRESET or
@ -567,13 +567,13 @@ when defineSsl:
## Creates an SSL context. ## Creates an SSL context.
## ##
## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1
## are available with the addition of ``protSSLv23`` which allows for ## are available with the addition of `protSSLv23` which allows for
## compatibility with all of them. ## compatibility with all of them.
## ##
## There are three options for verify mode: ## There are three options for verify mode:
## ``CVerifyNone``: certificates are not verified; ## `CVerifyNone`: certificates are not verified;
## ``CVerifyPeer``: certificates are verified; ## `CVerifyPeer`: certificates are verified;
## ``CVerifyPeerUseEnvVars``: certificates are verified and the optional ## `CVerifyPeerUseEnvVars`: certificates are verified and the optional
## environment variables SSL_CERT_FILE and SSL_CERT_DIR are also used to ## environment variables SSL_CERT_FILE and SSL_CERT_DIR are also used to
## locate certificates ## locate certificates
## ##
@ -583,7 +583,7 @@ when defineSsl:
## CA certificates will be loaded, in the following order, from: ## CA certificates will be loaded, in the following order, from:
## ##
## - caFile, caDir, parameters, if set ## - caFile, caDir, parameters, if set
## - if `verifyMode` is set to ``CVerifyPeerUseEnvVars``, ## - if `verifyMode` is set to `CVerifyPeerUseEnvVars`,
## the SSL_CERT_FILE and SSL_CERT_DIR environment variables are used ## the SSL_CERT_FILE and SSL_CERT_DIR environment variables are used
## - a set of files and directories from the `ssl_certs <ssl_certs.html>`_ file. ## - a set of files and directories from the `ssl_certs <ssl_certs.html>`_ file.
## ##
@ -591,10 +591,10 @@ when defineSsl:
## path, a server socket will most likely not work without these. ## path, a server socket will most likely not work without these.
## ##
## Certificates can be generated using the following command: ## Certificates can be generated using the following command:
## - ``openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout mykey.pem -out mycert.pem`` ## - `openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout mykey.pem -out mycert.pem`
## or using ECDSA: ## or using ECDSA:
## - ``openssl ecparam -out mykey.pem -name secp256k1 -genkey`` ## - `openssl ecparam -out mykey.pem -name secp256k1 -genkey`
## - ``openssl req -new -key mykey.pem -x509 -nodes -days 365 -out mycert.pem`` ## - `openssl req -new -key mykey.pem -x509 -nodes -days 365 -out mycert.pem`
var newCTX: SslCtx var newCTX: SslCtx
case protVersion case protVersion
of protSSLv23: of protSSLv23:
@ -737,7 +737,7 @@ when defineSsl:
proc wrapSocket*(ctx: SslContext, socket: Socket) = proc wrapSocket*(ctx: SslContext, socket: Socket) =
## Wraps a socket in an SSL context. This function effectively turns ## Wraps a socket in an SSL context. This function effectively turns
## ``socket`` into an SSL socket. ## `socket` into an SSL socket.
## ##
## This must be called on an unconnected socket; an SSL session will ## This must be called on an unconnected socket; an SSL session will
## be started when the socket is connected. ## be started when the socket is connected.
@ -781,8 +781,8 @@ when defineSsl:
handshake: SslHandshakeType, handshake: SslHandshakeType,
hostname: string = "") = hostname: string = "") =
## Wraps a connected socket in an SSL context. This function effectively ## Wraps a connected socket in an SSL context. This function effectively
## turns ``socket`` into an SSL socket. ## turns `socket` into an SSL socket.
## ``hostname`` should be specified so that the client knows which hostname ## `hostname` should be specified so that the client knows which hostname
## the server certificate should be validated against. ## the server certificate should be validated against.
## ##
## This should be called on a connected socket, and will perform ## This should be called on a connected socket, and will perform
@ -811,7 +811,7 @@ when defineSsl:
proc getPeerCertificates*(sslHandle: SslPtr): seq[Certificate] {.since: (1, 1).} = proc getPeerCertificates*(sslHandle: SslPtr): seq[Certificate] {.since: (1, 1).} =
## Returns the certificate chain received by the peer we are connected to ## Returns the certificate chain received by the peer we are connected to
## through the OpenSSL connection represented by ``sslHandle``. ## through the OpenSSL connection represented by `sslHandle`.
## The handshake must have been completed and the certificate chain must ## The handshake must have been completed and the certificate chain must
## have been verified successfully or else an empty sequence is returned. ## have been verified successfully or else an empty sequence is returned.
## The chain is ordered from leaf certificate to root certificate. ## The chain is ordered from leaf certificate to root certificate.
@ -856,7 +856,7 @@ when defineSsl:
SSL_CTX_set_session_id_context(ctx.context, sidCtx, sidCtx.len) SSL_CTX_set_session_id_context(ctx.context, sidCtx, sidCtx.len)
proc getSocketError*(socket: Socket): OSErrorCode = proc getSocketError*(socket: Socket): OSErrorCode =
## Checks ``osLastError`` for a valid error. If it has been reset it uses ## Checks `osLastError` for a valid error. If it has been reset it uses
## the last error stored in the socket object. ## the last error stored in the socket object.
result = osLastError() result = osLastError()
if result == 0.OSErrorCode: if result == 0.OSErrorCode:
@ -867,15 +867,15 @@ proc getSocketError*(socket: Socket): OSErrorCode =
proc socketError*(socket: Socket, err: int = -1, async = false, proc socketError*(socket: Socket, err: int = -1, async = false,
lastError = (-1).OSErrorCode, lastError = (-1).OSErrorCode,
flags: set[SocketFlag] = {}) = flags: set[SocketFlag] = {}) =
## Raises an OSError based on the error code returned by ``SSL_get_error`` ## Raises an OSError based on the error code returned by `SSL_get_error`
## (for SSL sockets) and ``osLastError`` otherwise. ## (for SSL sockets) and `osLastError` otherwise.
## ##
## If ``async`` is ``true`` no error will be thrown in the case when the ## If `async` is `true` no error will be thrown in the case when the
## error was caused by no data being available to be read. ## error was caused by no data being available to be read.
## ##
## If ``err`` is not lower than 0 no exception will be raised. ## If `err` is not lower than 0 no exception will be raised.
## ##
## If ``flags`` contains ``SafeDisconn``, no exception will be raised ## If `flags` contains `SafeDisconn`, no exception will be raised
## when the error was caused by a peer disconnection. ## when the error was caused by a peer disconnection.
when defineSsl: when defineSsl:
if socket.isSsl: if socket.isSsl:
@ -930,8 +930,8 @@ proc socketError*(socket: Socket, err: int = -1, async = false,
else: raiseOSError(lastE) else: raiseOSError(lastE)
proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
## Marks ``socket`` as accepting connections. ## Marks `socket` as accepting connections.
## ``Backlog`` specifies the maximum length of the ## `Backlog` specifies the maximum length of the
## queue of pending connections. ## queue of pending connections.
## ##
## Raises an OSError error upon failure. ## Raises an OSError error upon failure.
@ -940,9 +940,9 @@ proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
proc bindAddr*(socket: Socket, port = Port(0), address = "") {. proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
tags: [ReadIOEffect].} = tags: [ReadIOEffect].} =
## Binds ``address``:``port`` to the socket. ## Binds `address`:`port` to the socket.
## ##
## If ``address`` is "" then ADDR_ANY will be bound. ## If `address` is "" then ADDR_ANY will be bound.
var realaddr = address var realaddr = address
if realaddr == "": if realaddr == "":
case socket.domain case socket.domain
@ -963,7 +963,7 @@ proc acceptAddr*(server: Socket, client: var owned(Socket), address: var string,
inheritable = defined(nimInheritHandles)) {. inheritable = defined(nimInheritHandles)) {.
tags: [ReadIOEffect], gcsafe, locks: 0.} = tags: [ReadIOEffect], gcsafe, locks: 0.} =
## Blocks until a connection is being made from a client. When a connection ## Blocks until a connection is being made from a client. When a connection
## is made sets ``client`` to the client socket and ``address`` to the address ## is made sets `client` to the client socket and `address` to the address
## of the connecting client. ## of the connecting client.
## This function will raise OSError if an error occurs. ## This function will raise OSError if an error occurs.
## ##
@ -974,8 +974,8 @@ proc acceptAddr*(server: Socket, client: var owned(Socket), address: var string,
## inheritable by child processes by default. This can be changed via ## inheritable by child processes by default. This can be changed via
## the `inheritable` parameter. ## the `inheritable` parameter.
## ##
## The ``accept`` call may result in an error if the connecting socket ## The `accept` call may result in an error if the connecting socket
## disconnects during the duration of the ``accept``. If the ``SafeDisconn`` ## disconnects during the duration of the `accept`. If the `SafeDisconn`
## flag is specified then this error will not be raised and instead ## flag is specified then this error will not be raised and instead
## accept will be called again. ## accept will be called again.
if client.isNil: if client.isNil:
@ -1011,16 +1011,16 @@ when false: #defineSsl:
## This procedure should only be used for non-blocking **SSL** sockets. ## This procedure should only be used for non-blocking **SSL** sockets.
## It will immediately return with one of the following values: ## It will immediately return with one of the following values:
## ##
## ``AcceptSuccess`` will be returned when a client has been successfully ## `AcceptSuccess` will be returned when a client has been successfully
## accepted and the handshake has been successfully performed between ## accepted and the handshake has been successfully performed between
## ``server`` and the newly connected client. ## `server` and the newly connected client.
## ##
## ``AcceptNoHandshake`` will be returned when a client has been accepted ## `AcceptNoHandshake` will be returned when a client has been accepted
## but no handshake could be performed. This can happen when the client ## but no handshake could be performed. This can happen when the client
## connects but does not yet initiate a handshake. In this case ## connects but does not yet initiate a handshake. In this case
## ``acceptAddrSSL`` should be called again with the same parameters. ## `acceptAddrSSL` should be called again with the same parameters.
## ##
## ``AcceptNoClient`` will be returned when no client is currently attempting ## `AcceptNoClient` will be returned when no client is currently attempting
## to connect. ## to connect.
template doHandshake(): untyped = template doHandshake(): untyped =
when defineSsl: when defineSsl:
@ -1061,15 +1061,15 @@ proc accept*(server: Socket, client: var owned(Socket),
flags = {SocketFlag.SafeDisconn}, flags = {SocketFlag.SafeDisconn},
inheritable = defined(nimInheritHandles)) inheritable = defined(nimInheritHandles))
{.tags: [ReadIOEffect].} = {.tags: [ReadIOEffect].} =
## Equivalent to ``acceptAddr`` but doesn't return the address, only the ## Equivalent to `acceptAddr` but doesn't return the address, only the
## socket. ## socket.
## ##
## The SocketHandle associated with the resulting client will not be ## The SocketHandle associated with the resulting client will not be
## inheritable by child processes by default. This can be changed via ## inheritable by child processes by default. This can be changed via
## the `inheritable` parameter. ## the `inheritable` parameter.
## ##
## The ``accept`` call may result in an error if the connecting socket ## The `accept` call may result in an error if the connecting socket
## disconnects during the duration of the ``accept``. If the ``SafeDisconn`` ## disconnects during the duration of the `accept`. If the `SafeDisconn`
## flag is specified then this error will not be raised and instead ## flag is specified then this error will not be raised and instead
## accept will be called again. ## accept will be called again.
var addrDummy = "" var addrDummy = ""
@ -1195,7 +1195,7 @@ else:
from winlean import TCP_NODELAY from winlean import TCP_NODELAY
proc toCInt*(opt: SOBool): cint = proc toCInt*(opt: SOBool): cint =
## Converts a ``SOBool`` into its Socket Option cint representation. ## Converts a `SOBool` into its Socket Option cint representation.
case opt case opt
of OptAcceptConn: SO_ACCEPTCONN of OptAcceptConn: SO_ACCEPTCONN
of OptBroadcast: SO_BROADCAST of OptBroadcast: SO_BROADCAST
@ -1209,7 +1209,7 @@ proc toCInt*(opt: SOBool): cint =
proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {. proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
tags: [ReadIOEffect].} = tags: [ReadIOEffect].} =
## Retrieves option ``opt`` as a boolean value. ## Retrieves option `opt` as a boolean value.
var res = getSockOptInt(socket.fd, cint(level), toCInt(opt)) var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
result = res != 0 result = res != 0
@ -1227,7 +1227,7 @@ proc getPeerAddr*(socket: Socket): (string, Port) =
proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, proc setSockOpt*(socket: Socket, opt: SOBool, value: bool,
level = SOL_SOCKET) {.tags: [WriteIOEffect].} = level = SOL_SOCKET) {.tags: [WriteIOEffect].} =
## Sets option ``opt`` to a boolean value specified by ``value``. ## Sets option `opt` to a boolean value specified by `value`.
## ##
## .. code-block:: Nim ## .. code-block:: Nim
## var socket = newSocket() ## var socket = newSocket()
@ -1258,10 +1258,10 @@ when defined(posix) or defined(nimdoc):
when defined(ssl): when defined(ssl):
proc gotHandshake*(socket: Socket): bool = proc gotHandshake*(socket: Socket): bool =
## Determines whether a handshake has occurred between a client (``socket``) ## Determines whether a handshake has occurred between a client (`socket`)
## and the server that ``socket`` is connected to. ## and the server that `socket` is connected to.
## ##
## Throws SslError if ``socket`` is not an SSL socket. ## Throws SslError if `socket` is not an SSL socket.
if socket.isSsl: if socket.isSsl:
return not socket.sslNoHandshake return not socket.sslNoHandshake
else: else:
@ -1329,7 +1329,7 @@ proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [
## Receives data from a socket. ## Receives data from a socket.
## ##
## **Note**: This is a low-level function, you may be interested in the higher ## **Note**: This is a low-level function, you may be interested in the higher
## level versions of this function which are also named ``recv``. ## level versions of this function which are also named `recv`.
if size == 0: return if size == 0: return
if socket.isBuffered: if socket.isBuffered:
if socket.bufLen == 0: if socket.bufLen == 0:
@ -1372,11 +1372,11 @@ proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [
proc waitFor(socket: Socket, waited: var Duration, timeout, size: int, proc waitFor(socket: Socket, waited: var Duration, timeout, size: int,
funcName: string): int {.tags: [TimeEffect].} = funcName: string): int {.tags: [TimeEffect].} =
## determines the amount of characters that can be read. Result will never ## determines the amount of characters that can be read. Result will never
## be larger than ``size``. For unbuffered sockets this will be ``1``. ## be larger than `size`. For unbuffered sockets this will be `1`.
## For buffered sockets it can be as big as ``BufferSize``. ## For buffered sockets it can be as big as `BufferSize`.
## ##
## If this function does not determine that there is data on the socket ## If this function does not determine that there is data on the socket
## within ``timeout`` ms, a TimeoutError error will be raised. ## within `timeout` ms, a TimeoutError error will be raised.
result = 1 result = 1
if size <= 0: assert false if size <= 0: assert false
if timeout == -1: return size if timeout == -1: return size
@ -1406,7 +1406,7 @@ proc waitFor(socket: Socket, waited: var Duration, timeout, size: int,
proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {.
tags: [ReadIOEffect, TimeEffect].} = tags: [ReadIOEffect, TimeEffect].} =
## overload with a ``timeout`` parameter in milliseconds. ## overload with a `timeout` parameter in milliseconds.
var waited: Duration # duration already waited var waited: Duration # duration already waited
var read = 0 var read = 0
@ -1424,12 +1424,12 @@ proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {.
proc recv*(socket: Socket, data: var string, size: int, timeout = -1, proc recv*(socket: Socket, data: var string, size: int, timeout = -1,
flags = {SocketFlag.SafeDisconn}): int = flags = {SocketFlag.SafeDisconn}): int =
## Higher-level version of ``recv``. ## Higher-level version of `recv`.
## ##
## Reads **up to** ``size`` bytes from ``socket`` into ``buf``. ## Reads **up to** `size` bytes from `socket` into `buf`.
## ##
## For buffered sockets this function will attempt to read all the requested ## For buffered sockets this function will attempt to read all the requested
## data. It will read this data in ``BufferSize`` chunks. ## data. It will read this data in `BufferSize` chunks.
## ##
## For unbuffered sockets this function makes no effort to read ## For unbuffered sockets this function makes no effort to read
## all the data requested. It will return as much data as the operating system ## all the data requested. It will return as much data as the operating system
@ -1443,9 +1443,9 @@ proc recv*(socket: Socket, data: var string, size: int, timeout = -1,
## A timeout may be specified in milliseconds, if enough data is not received ## A timeout may be specified in milliseconds, if enough data is not received
## within the time specified a TimeoutError exception will be raised. ## within the time specified a TimeoutError exception will be raised.
## ##
## **Note**: ``data`` must be initialised. ## **Note**: `data` must be initialised.
## ##
## **Warning**: Only the ``SafeDisconn`` flag is currently supported. ## **Warning**: Only the `SafeDisconn` flag is currently supported.
data.setLen(size) data.setLen(size)
result = result =
if timeout == -1: if timeout == -1:
@ -1461,18 +1461,18 @@ proc recv*(socket: Socket, data: var string, size: int, timeout = -1,
proc recv*(socket: Socket, size: int, timeout = -1, proc recv*(socket: Socket, size: int, timeout = -1,
flags = {SocketFlag.SafeDisconn}): string {.inline.} = flags = {SocketFlag.SafeDisconn}): string {.inline.} =
## Higher-level version of ``recv`` which returns a string. ## Higher-level version of `recv` which returns a string.
## ##
## Reads **up to** ``size`` bytes from ``socket`` into ``buf``. ## Reads **up to** `size` bytes from `socket` into `buf`.
## ##
## For buffered sockets this function will attempt to read all the requested ## For buffered sockets this function will attempt to read all the requested
## data. It will read this data in ``BufferSize`` chunks. ## data. It will read this data in `BufferSize` chunks.
## ##
## For unbuffered sockets this function makes no effort to read ## For unbuffered sockets this function makes no effort to read
## all the data requested. It will return as much data as the operating system ## all the data requested. It will return as much data as the operating system
## gives it. ## gives it.
## ##
## When ``""`` is returned the socket's connection has been closed. ## When `""` is returned the socket's connection has been closed.
## ##
## This function will throw an OSError exception when an error occurs. ## This function will throw an OSError exception when an error occurs.
## ##
@ -1480,7 +1480,7 @@ proc recv*(socket: Socket, size: int, timeout = -1,
## within the time specified a TimeoutError exception will be raised. ## within the time specified a TimeoutError exception will be raised.
## ##
## ##
## **Warning**: Only the ``SafeDisconn`` flag is currently supported. ## **Warning**: Only the `SafeDisconn` flag is currently supported.
result = newString(size) result = newString(size)
discard recv(socket, result, size, timeout, flags) discard recv(socket, result, size, timeout, flags)
@ -1507,23 +1507,23 @@ proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} =
proc readLine*(socket: Socket, line: var string, timeout = -1, proc readLine*(socket: Socket, line: var string, timeout = -1,
flags = {SocketFlag.SafeDisconn}, maxLength = MaxLineLength) {. flags = {SocketFlag.SafeDisconn}, maxLength = MaxLineLength) {.
tags: [ReadIOEffect, TimeEffect].} = tags: [ReadIOEffect, TimeEffect].} =
## Reads a line of data from ``socket``. ## Reads a line of data from `socket`.
## ##
## If a full line is read ``\r\L`` is not ## If a full line is read `\r\L` is not
## added to ``line``, however if solely ``\r\L`` is read then ``line`` ## added to `line`, however if solely `\r\L` is read then `line`
## will be set to it. ## will be set to it.
## ##
## If the socket is disconnected, ``line`` will be set to ``""``. ## If the socket is disconnected, `line` will be set to `""`.
## ##
## An OSError exception will be raised in the case of a socket error. ## An OSError exception will be raised in the case of a socket error.
## ##
## A timeout can be specified in milliseconds, if data is not received within ## A timeout can be specified in milliseconds, if data is not received within
## the specified time a TimeoutError exception will be raised. ## the specified time a TimeoutError exception will be raised.
## ##
## The ``maxLength`` parameter determines the maximum amount of characters ## The `maxLength` parameter determines the maximum amount of characters
## that can be read. The result is truncated after that. ## that can be read. The result is truncated after that.
## ##
## **Warning**: Only the ``SafeDisconn`` flag is currently supported. ## **Warning**: Only the `SafeDisconn` flag is currently supported.
template addNLIfEmpty() = template addNLIfEmpty() =
if line.len == 0: if line.len == 0:
@ -1563,38 +1563,38 @@ proc readLine*(socket: Socket, line: var string, timeout = -1,
proc recvLine*(socket: Socket, timeout = -1, proc recvLine*(socket: Socket, timeout = -1,
flags = {SocketFlag.SafeDisconn}, flags = {SocketFlag.SafeDisconn},
maxLength = MaxLineLength): string = maxLength = MaxLineLength): string =
## Reads a line of data from ``socket``. ## Reads a line of data from `socket`.
## ##
## If a full line is read ``\r\L`` is not ## If a full line is read `\r\L` is not
## added to the result, however if solely ``\r\L`` is read then the result ## added to the result, however if solely `\r\L` is read then the result
## will be set to it. ## will be set to it.
## ##
## If the socket is disconnected, the result will be set to ``""``. ## If the socket is disconnected, the result will be set to `""`.
## ##
## An OSError exception will be raised in the case of a socket error. ## An OSError exception will be raised in the case of a socket error.
## ##
## A timeout can be specified in milliseconds, if data is not received within ## A timeout can be specified in milliseconds, if data is not received within
## the specified time a TimeoutError exception will be raised. ## the specified time a TimeoutError exception will be raised.
## ##
## The ``maxLength`` parameter determines the maximum amount of characters ## The `maxLength` parameter determines the maximum amount of characters
## that can be read. The result is truncated after that. ## that can be read. The result is truncated after that.
## ##
## **Warning**: Only the ``SafeDisconn`` flag is currently supported. ## **Warning**: Only the `SafeDisconn` flag is currently supported.
result = "" result = ""
readLine(socket, result, timeout, flags, maxLength) readLine(socket, result, timeout, flags, maxLength)
proc recvFrom*(socket: Socket, data: var string, length: int, proc recvFrom*(socket: Socket, data: var string, length: int,
address: var string, port: var Port, flags = 0'i32): int {. address: var string, port: var Port, flags = 0'i32): int {.
tags: [ReadIOEffect].} = tags: [ReadIOEffect].} =
## Receives data from ``socket``. This function should normally be used with ## Receives data from `socket`. This function should normally be used with
## connection-less sockets (UDP sockets). ## connection-less sockets (UDP sockets).
## ##
## If an error occurs an OSError exception will be raised. Otherwise the return ## If an error occurs an OSError exception will be raised. Otherwise the return
## value will be the length of data received. ## value will be the length of data received.
## ##
## **Warning:** This function does not yet have a buffered implementation, ## **Warning:** This function does not yet have a buffered implementation,
## so when ``socket`` is buffered the non-buffered implementation will be ## so when `socket` is buffered the non-buffered implementation will be
## used. Therefore if ``socket`` contains something in its buffer this ## used. Therefore if `socket` contains something in its buffer this
## function will make no effort to return it. ## function will make no effort to return it.
template adaptRecvFromToDomain(domain: Domain) = template adaptRecvFromToDomain(domain: Domain) =
var addrLen = sizeof(sockAddress).SockLen var addrLen = sizeof(sockAddress).SockLen
@ -1625,7 +1625,7 @@ proc recvFrom*(socket: Socket, data: var string, length: int,
raise newException(ValueError, "Unknown socket address family") raise newException(ValueError, "Unknown socket address family")
proc skip*(socket: Socket, size: int, timeout = -1) = proc skip*(socket: Socket, size: int, timeout = -1) =
## Skips ``size`` amount of bytes. ## Skips `size` amount of bytes.
## ##
## An optional timeout can be specified in milliseconds, if skipping the ## An optional timeout can be specified in milliseconds, if skipping the
## bytes takes longer than specified a TimeoutError exception will be raised. ## bytes takes longer than specified a TimeoutError exception will be raised.
@ -1643,7 +1643,7 @@ proc send*(socket: Socket, data: pointer, size: int): int {.
tags: [WriteIOEffect].} = tags: [WriteIOEffect].} =
## Sends data to a socket. ## Sends data to a socket.
## ##
## **Note**: This is a low-level version of ``send``. You likely should use ## **Note**: This is a low-level version of `send`. You likely should use
## the version below. ## the version below.
assert(not socket.isClosed, "Cannot `send` on a closed socket") assert(not socket.isClosed, "Cannot `send` on a closed socket")
when defineSsl: when defineSsl:
@ -1674,14 +1674,14 @@ template `&=`*(socket: Socket; data: typed) =
send(socket, data) send(socket, data)
proc trySend*(socket: Socket, data: string): bool {.tags: [WriteIOEffect].} = proc trySend*(socket: Socket, data: string): bool {.tags: [WriteIOEffect].} =
## Safe alternative to ``send``. Does not raise an OSError when an error occurs, ## Safe alternative to `send`. Does not raise an OSError when an error occurs,
## and instead returns ``false`` on failure. ## and instead returns `false` on failure.
result = send(socket, cstring(data), data.len) == data.len result = send(socket, cstring(data), data.len) == data.len
proc sendTo*(socket: Socket, address: string, port: Port, data: pointer, proc sendTo*(socket: Socket, address: string, port: Port, data: pointer,
size: int, af: Domain = AF_INET, flags = 0'i32) {. size: int, af: Domain = AF_INET, flags = 0'i32) {.
tags: [WriteIOEffect].} = tags: [WriteIOEffect].} =
## This proc sends ``data`` to the specified ``address``, ## This proc sends `data` to the specified `address`,
## which may be an IP address or a hostname, if a hostname is specified ## which may be an IP address or a hostname, if a hostname is specified
## this function will try each IP of that hostname. ## this function will try each IP of that hostname.
## ##
@ -1714,18 +1714,18 @@ proc sendTo*(socket: Socket, address: string, port: Port, data: pointer,
proc sendTo*(socket: Socket, address: string, port: Port, proc sendTo*(socket: Socket, address: string, port: Port,
data: string) {.tags: [WriteIOEffect].} = data: string) {.tags: [WriteIOEffect].} =
## This proc sends ``data`` to the specified ``address``, ## This proc sends `data` to the specified `address`,
## which may be an IP address or a hostname, if a hostname is specified ## which may be an IP address or a hostname, if a hostname is specified
## this function will try each IP of that hostname. ## this function will try each IP of that hostname.
## ##
## If an error occurs an OSError exception will be raised. ## If an error occurs an OSError exception will be raised.
## ##
## This is the high-level version of the above ``sendTo`` function. ## This is the high-level version of the above `sendTo` function.
socket.sendTo(address, port, cstring(data), data.len, socket.domain) socket.sendTo(address, port, cstring(data), data.len, socket.domain)
proc isSsl*(socket: Socket): bool = proc isSsl*(socket: Socket): bool =
## Determines whether ``socket`` is a SSL socket. ## Determines whether `socket` is a SSL socket.
when defineSsl: when defineSsl:
result = socket.isSsl result = socket.isSsl
else: else:
@ -1850,9 +1850,9 @@ proc `$`*(address: IpAddress): string =
proc dial*(address: string, port: Port, proc dial*(address: string, port: Port,
protocol = IPPROTO_TCP, buffered = true): owned(Socket) protocol = IPPROTO_TCP, buffered = true): owned(Socket)
{.tags: [ReadIOEffect, WriteIOEffect].} = {.tags: [ReadIOEffect, WriteIOEffect].} =
## Establishes connection to the specified ``address``:``port`` pair via the ## Establishes connection to the specified `address`:`port` pair via the
## specified protocol. The procedure iterates through possible ## specified protocol. The procedure iterates through possible
## resolutions of the ``address`` until it succeeds, meaning that it ## resolutions of the `address` until it succeeds, meaning that it
## seamlessly works with both IPv4 and IPv6. ## seamlessly works with both IPv4 and IPv6.
## Returns Socket ready to send or receive data. ## Returns Socket ready to send or receive data.
let sockType = protocol.toSockType() let sockType = protocol.toSockType()
@ -1907,12 +1907,12 @@ proc dial*(address: string, port: Port,
proc connect*(socket: Socket, address: string, proc connect*(socket: Socket, address: string,
port = Port(0)) {.tags: [ReadIOEffect].} = port = Port(0)) {.tags: [ReadIOEffect].} =
## Connects socket to ``address``:``port``. ``Address`` can be an IP address or a ## Connects socket to `address`:`port`. `Address` can be an IP address or a
## host name. If ``address`` is a host name, this function will try each IP ## host name. If `address` is a host name, this function will try each IP
## of that host name. ``htons`` is already performed on ``port`` so you must ## of that host name. `htons` is already performed on `port` so you must
## not do it. ## not do it.
## ##
## If ``socket`` is an SSL socket a handshake will be automatically performed. ## If `socket` is an SSL socket a handshake will be automatically performed.
var aiList = getAddrInfo(address, port, socket.domain) var aiList = getAddrInfo(address, port, socket.domain)
# try all possibilities: # try all possibilities:
var success = false var success = false
@ -1945,13 +1945,13 @@ proc connect*(socket: Socket, address: string,
proc connectAsync(socket: Socket, name: string, port = Port(0), proc connectAsync(socket: Socket, name: string, port = Port(0),
af: Domain = AF_INET) {.tags: [ReadIOEffect].} = af: Domain = AF_INET) {.tags: [ReadIOEffect].} =
## A variant of ``connect`` for non-blocking sockets. ## A variant of `connect` for non-blocking sockets.
## ##
## This procedure will immediately return, it will not block until a connection ## This procedure will immediately return, it will not block until a connection
## is made. It is up to the caller to make sure the connection has been established ## is made. It is up to the caller to make sure the connection has been established
## by checking (using ``select``) whether the socket is writeable. ## by checking (using `select`) whether the socket is writeable.
## ##
## **Note**: For SSL sockets, the ``handshake`` procedure must be called ## **Note**: For SSL sockets, the `handshake` procedure must be called
## whenever the socket successfully connects to a server. ## whenever the socket successfully connects to a server.
var aiList = getAddrInfo(name, port, af) var aiList = getAddrInfo(name, port, af)
# try all possibilities: # try all possibilities:
@ -1982,9 +1982,9 @@ proc connectAsync(socket: Socket, name: string, port = Port(0),
proc connect*(socket: Socket, address: string, port = Port(0), proc connect*(socket: Socket, address: string, port = Port(0),
timeout: int) {.tags: [ReadIOEffect, WriteIOEffect].} = timeout: int) {.tags: [ReadIOEffect, WriteIOEffect].} =
## Connects to server as specified by ``address`` on port specified by ``port``. ## Connects to server as specified by `address` on port specified by `port`.
## ##
## The ``timeout`` parameter specifies the time in milliseconds to allow for ## The `timeout` parameter specifies the time in milliseconds to allow for
## the connection to the server to be made. ## the connection to the server to be made.
socket.fd.setBlocking(false) socket.fd.setBlocking(false)