lib: Trim .nim files trailing whitespace
via OSX: find . -name '*.nim' -exec sed -i '' -E 's/[[:space:]]+$//' {} +
This commit is contained in:
parent
d681812465
commit
43bddf62dd
67 changed files with 2435 additions and 2435 deletions
|
|
@ -51,17 +51,17 @@ else:
|
|||
|
||||
# Note: The enumerations are mapped to Window's constants.
|
||||
|
||||
when defined(ssl):
|
||||
when defined(ssl):
|
||||
|
||||
type
|
||||
SSLError* = object of Exception
|
||||
|
||||
SSLCVerifyMode* = enum
|
||||
CVerifyNone, CVerifyPeer
|
||||
|
||||
|
||||
SSLProtVersion* = enum
|
||||
protSSLv2, protSSLv3, protTLSv1, protSSLv23
|
||||
|
||||
|
||||
SSLContext* = distinct SSLCTX
|
||||
|
||||
SSLAcceptResult* = enum
|
||||
|
|
@ -93,11 +93,11 @@ type
|
|||
sslPeekChar: char
|
||||
of false: nil
|
||||
nonblocking: bool
|
||||
|
||||
|
||||
Socket* = ref SocketImpl
|
||||
|
||||
|
||||
Port* = distinct uint16 ## port type
|
||||
|
||||
|
||||
Domain* = enum ## domain, which specifies the protocol family of the
|
||||
## created socket. Other domains than those that are listed
|
||||
## here are unsupported.
|
||||
|
|
@ -112,7 +112,7 @@ type
|
|||
SOCK_SEQPACKET = 5 ## reliable sequenced packet service
|
||||
|
||||
Protocol* = enum ## third argument to `socket` proc
|
||||
IPPROTO_TCP = 6, ## Transmission control protocol.
|
||||
IPPROTO_TCP = 6, ## Transmission control protocol.
|
||||
IPPROTO_UDP = 17, ## User datagram protocol.
|
||||
IPPROTO_IP, ## Internet protocol. Unsupported on Windows.
|
||||
IPPROTO_IPV6, ## Internet Protocol Version 6. Unsupported on Windows.
|
||||
|
|
@ -178,7 +178,7 @@ proc `==`*(a, b: Port): bool {.borrow.}
|
|||
proc `$`*(p: Port): string {.borrow.}
|
||||
## returns the port number as a string
|
||||
|
||||
proc ntohl*(x: int32): int32 =
|
||||
proc ntohl*(x: int32): int32 =
|
||||
## Converts 32-bit integers from network to host byte order.
|
||||
## On machines where the host byte order is the same as network byte order,
|
||||
## this is a no-op; otherwise, it performs a 4-byte swap operation.
|
||||
|
|
@ -206,7 +206,7 @@ proc htons*(x: int16): int16 =
|
|||
## On machines where the host byte order is the same as network byte
|
||||
## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
|
||||
result = sockets.ntohs(x)
|
||||
|
||||
|
||||
when defined(Posix):
|
||||
proc toInt(domain: Domain): cint =
|
||||
case domain
|
||||
|
|
@ -234,19 +234,19 @@ when defined(Posix):
|
|||
else: discard
|
||||
|
||||
else:
|
||||
proc toInt(domain: Domain): cint =
|
||||
proc toInt(domain: Domain): cint =
|
||||
result = toU16(ord(domain))
|
||||
|
||||
proc toInt(typ: SockType): cint =
|
||||
result = cint(ord(typ))
|
||||
|
||||
|
||||
proc toInt(p: Protocol): cint =
|
||||
result = cint(ord(p))
|
||||
|
||||
proc socket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM,
|
||||
protocol: Protocol = IPPROTO_TCP, buffered = true): Socket =
|
||||
## Creates a new socket; returns `InvalidSocket` if an error occurs.
|
||||
|
||||
|
||||
# TODO: Perhaps this should just raise EOS when an error occurs.
|
||||
when defined(Windows):
|
||||
result = newTSocket(winlean.socket(ord(domain), ord(typ), ord(protocol)), buffered)
|
||||
|
|
@ -277,27 +277,27 @@ when defined(ssl):
|
|||
raise newException(system.IOError, "Certificate file could not be found: " & certFile)
|
||||
if keyFile != "" and not existsFile(keyFile):
|
||||
raise newException(system.IOError, "Key file could not be found: " & keyFile)
|
||||
|
||||
|
||||
if certFile != "":
|
||||
var ret = SSLCTXUseCertificateChainFile(ctx, certFile)
|
||||
if ret != 1:
|
||||
raiseSslError()
|
||||
|
||||
|
||||
# TODO: Password? www.rtfm.com/openssl-examples/part1.pdf
|
||||
if keyFile != "":
|
||||
if SSL_CTX_use_PrivateKey_file(ctx, keyFile,
|
||||
SSL_FILETYPE_PEM) != 1:
|
||||
raiseSslError()
|
||||
|
||||
|
||||
if SSL_CTX_check_private_key(ctx) != 1:
|
||||
raiseSslError("Verification of private key file failed.")
|
||||
|
||||
proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer,
|
||||
certFile = "", keyFile = ""): SSLContext =
|
||||
## Creates an SSL context.
|
||||
##
|
||||
## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are
|
||||
## are available with the addition of ``ProtSSLv23`` which allows for
|
||||
##
|
||||
## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are
|
||||
## are available with the addition of ``ProtSSLv23`` which allows for
|
||||
## compatibility with all of them.
|
||||
##
|
||||
## There are currently only two options for verify mode;
|
||||
|
|
@ -322,7 +322,7 @@ when defined(ssl):
|
|||
newCTX = SSL_CTX_new(SSLv3_method())
|
||||
of protTLSv1:
|
||||
newCTX = SSL_CTX_new(TLSv1_method())
|
||||
|
||||
|
||||
if newCTX.SSLCTXSetCipherList("ALL") != 1:
|
||||
raiseSslError()
|
||||
case verifyMode
|
||||
|
|
@ -343,7 +343,7 @@ when defined(ssl):
|
|||
##
|
||||
## **Disclaimer**: This code is not well tested, may be very unsafe and
|
||||
## prone to security vulnerabilities.
|
||||
|
||||
|
||||
socket.isSSL = true
|
||||
socket.sslContext = ctx
|
||||
socket.sslHandle = SSLNew(SSLCTX(socket.sslContext))
|
||||
|
|
@ -351,7 +351,7 @@ when defined(ssl):
|
|||
socket.sslHasPeekChar = false
|
||||
if socket.sslHandle == nil:
|
||||
raiseSslError()
|
||||
|
||||
|
||||
if SSLSetFd(socket.sslHandle, socket.fd) != 1:
|
||||
raiseSslError()
|
||||
|
||||
|
|
@ -382,7 +382,7 @@ proc raiseSocketError*(socket: Socket, err: int = -1, async = false) =
|
|||
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
||||
raiseSslError()
|
||||
else: raiseSslError("Unknown Error")
|
||||
|
||||
|
||||
if err == -1 and not (when defined(ssl): socket.isSSL else: false):
|
||||
let lastError = osLastError()
|
||||
if async:
|
||||
|
|
@ -397,15 +397,15 @@ proc raiseSocketError*(socket: Socket, err: int = -1, async = false) =
|
|||
else: raiseOSError(lastError)
|
||||
|
||||
proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
|
||||
## Marks ``socket`` as accepting connections.
|
||||
## ``Backlog`` specifies the maximum length of the
|
||||
## Marks ``socket`` as accepting connections.
|
||||
## ``Backlog`` specifies the maximum length of the
|
||||
## queue of pending connections.
|
||||
if listen(socket.fd, cint(backlog)) < 0'i32: raiseOSError(osLastError())
|
||||
|
||||
proc invalidIp4(s: string) {.noreturn, noinline.} =
|
||||
raise newException(ValueError, "invalid ip4 address: " & s)
|
||||
|
||||
proc parseIp4*(s: string): BiggestInt =
|
||||
proc parseIp4*(s: string): BiggestInt =
|
||||
## parses an IP version 4 in dotted decimal form like "a.b.c.d".
|
||||
##
|
||||
## This is equivalent to `inet_ntoa`:idx:.
|
||||
|
|
@ -469,8 +469,8 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
|
|||
gaiNim(address, port, hints, aiList)
|
||||
if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
proc getSockName*(socket: Socket): Port =
|
||||
|
||||
proc getSockName*(socket: Socket): Port =
|
||||
## returns the socket's associated port number.
|
||||
var name: Sockaddr_in
|
||||
when defined(Windows):
|
||||
|
|
@ -485,14 +485,14 @@ proc getSockName*(socket: Socket): Port =
|
|||
raiseOSError(osLastError())
|
||||
result = Port(sockets.ntohs(name.sin_port))
|
||||
|
||||
template acceptAddrPlain(noClientRet, successRet: expr,
|
||||
template acceptAddrPlain(noClientRet, successRet: expr,
|
||||
sslImplementation: stmt): stmt {.immediate.} =
|
||||
assert(client != nil)
|
||||
var sockAddress: Sockaddr_in
|
||||
var addrLen = sizeof(sockAddress).SockLen
|
||||
var sock = accept(server.fd, cast[ptr SockAddr](addr(sockAddress)),
|
||||
addr(addrLen))
|
||||
|
||||
|
||||
if sock == osInvalidSocket:
|
||||
let err = osLastError()
|
||||
when defined(windows):
|
||||
|
|
@ -537,7 +537,7 @@ proc acceptAddr*(server: Socket, client: var Socket, address: var string) {.
|
|||
## The resulting client will inherit any properties of the server socket. For
|
||||
## example: whether the socket is buffered or not.
|
||||
##
|
||||
## **Note**: ``client`` must be initialised (with ``new``), this function
|
||||
## **Note**: ``client`` must be initialised (with ``new``), this function
|
||||
## makes no effort to initialise the ``client`` variable.
|
||||
##
|
||||
## **Warning:** When using SSL with non-blocking sockets, it is best to use
|
||||
|
|
@ -546,7 +546,7 @@ proc acceptAddr*(server: Socket, client: var Socket, address: var string) {.
|
|||
when defined(ssl):
|
||||
if server.isSSL:
|
||||
# We must wrap the client sock in a ssl context.
|
||||
|
||||
|
||||
server.sslContext.wrapSocket(client)
|
||||
let ret = SSLAccept(client.sslHandle)
|
||||
while ret <= 0:
|
||||
|
|
@ -572,9 +572,9 @@ when defined(ssl):
|
|||
proc acceptAddrSSL*(server: Socket, client: var Socket,
|
||||
address: var string): SSLAcceptResult {.
|
||||
tags: [ReadIOEffect].} =
|
||||
## 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:
|
||||
##
|
||||
##
|
||||
## ``AcceptSuccess`` will be returned when a client has been successfully
|
||||
## accepted and the handshake has been successfully performed between
|
||||
## ``server`` and the newly connected client.
|
||||
|
|
@ -591,7 +591,7 @@ when defined(ssl):
|
|||
if server.isSSL:
|
||||
client.setBlocking(false)
|
||||
# We must wrap the client sock in a ssl context.
|
||||
|
||||
|
||||
if not client.isSSL or client.sslHandle == nil:
|
||||
server.sslContext.wrapSocket(client)
|
||||
let ret = SSLAccept(client.sslHandle)
|
||||
|
|
@ -623,10 +623,10 @@ when defined(ssl):
|
|||
proc accept*(server: Socket, client: var Socket) {.tags: [ReadIOEffect].} =
|
||||
## Equivalent to ``acceptAddr`` but doesn't return the address, only the
|
||||
## socket.
|
||||
##
|
||||
##
|
||||
## **Note**: ``client`` must be initialised (with ``new``), this function
|
||||
## makes no effort to initialise the ``client`` variable.
|
||||
|
||||
|
||||
var addrDummy = ""
|
||||
acceptAddr(server, client, addrDummy)
|
||||
|
||||
|
|
@ -662,7 +662,7 @@ proc close*(socket: Socket) =
|
|||
socket.sslHandle = nil
|
||||
|
||||
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
|
||||
## and the protocol name specified by ``proto`` matches the s_proto member.
|
||||
##
|
||||
|
|
@ -676,10 +676,10 @@ proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
|
|||
result.aliases = cstringArrayToSeq(s.s_aliases)
|
||||
result.port = Port(s.s_port)
|
||||
result.proto = $s.s_proto
|
||||
|
||||
proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} =
|
||||
## 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
|
||||
|
||||
proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} =
|
||||
## 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
|
||||
## protocol name specified by ``proto`` matches the s_proto member.
|
||||
##
|
||||
## On posix this will search through the ``/etc/services`` file.
|
||||
|
|
@ -697,20 +697,20 @@ proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} =
|
|||
## This function will lookup the hostname of an IP Address.
|
||||
var myaddr: InAddr
|
||||
myaddr.s_addr = inet_addr(ip)
|
||||
|
||||
|
||||
when defined(windows):
|
||||
var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint,
|
||||
cint(sockets.AF_INET))
|
||||
if s == nil: raiseOSError(osLastError())
|
||||
else:
|
||||
var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen,
|
||||
var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen,
|
||||
cint(posix.AF_INET))
|
||||
if s == nil:
|
||||
raiseOSError(osLastError(), $hstrerror(h_errno))
|
||||
|
||||
|
||||
result.name = $s.h_name
|
||||
result.aliases = cstringArrayToSeq(s.h_aliases)
|
||||
when defined(windows):
|
||||
when defined(windows):
|
||||
result.addrtype = Domain(s.h_addrtype)
|
||||
else:
|
||||
if s.h_addrtype == posix.AF_INET:
|
||||
|
|
@ -722,7 +722,7 @@ proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} =
|
|||
result.addrList = cstringArrayToSeq(s.h_addr_list)
|
||||
result.length = int(s.h_length)
|
||||
|
||||
proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} =
|
||||
proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} =
|
||||
## This function will lookup the IP address of a hostname.
|
||||
when defined(Windows):
|
||||
var s = winlean.gethostbyname(name)
|
||||
|
|
@ -731,7 +731,7 @@ proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} =
|
|||
if s == nil: raiseOSError(osLastError())
|
||||
result.name = $s.h_name
|
||||
result.aliases = cstringArrayToSeq(s.h_aliases)
|
||||
when defined(windows):
|
||||
when defined(windows):
|
||||
result.addrtype = Domain(s.h_addrtype)
|
||||
else:
|
||||
if s.h_addrtype == posix.AF_INET:
|
||||
|
|
@ -744,11 +744,11 @@ proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} =
|
|||
result.length = int(s.h_length)
|
||||
|
||||
proc getSockOptInt*(socket: Socket, level, optname: int): int {.
|
||||
tags: [ReadIOEffect].} =
|
||||
tags: [ReadIOEffect].} =
|
||||
## getsockopt for integer options.
|
||||
var res: cint
|
||||
var size = sizeof(res).SockLen
|
||||
if getsockopt(socket.fd, cint(level), cint(optname),
|
||||
if getsockopt(socket.fd, cint(level), cint(optname),
|
||||
addr(res), addr(size)) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
result = int(res)
|
||||
|
|
@ -757,7 +757,7 @@ proc setSockOptInt*(socket: Socket, level, optname, optval: int) {.
|
|||
tags: [WriteIOEffect].} =
|
||||
## setsockopt for integer options.
|
||||
var value = cint(optval)
|
||||
if setsockopt(socket.fd, cint(level), cint(optname), addr(value),
|
||||
if setsockopt(socket.fd, cint(level), cint(optname), addr(value),
|
||||
sizeof(value).SockLen) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
|
|
@ -776,7 +776,7 @@ proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
|
|||
## Retrieves option ``opt`` as a boolean value.
|
||||
var res: cint
|
||||
var size = sizeof(res).SockLen
|
||||
if getsockopt(socket.fd, cint(level), toCInt(opt),
|
||||
if getsockopt(socket.fd, cint(level), toCInt(opt),
|
||||
addr(res), addr(size)) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
result = res != 0
|
||||
|
|
@ -785,11 +785,11 @@ proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {
|
|||
tags: [WriteIOEffect].} =
|
||||
## Sets option ``opt`` to a boolean value specified by ``value``.
|
||||
var valuei = cint(if value: 1 else: 0)
|
||||
if setsockopt(socket.fd, cint(level), toCInt(opt), addr(valuei),
|
||||
if setsockopt(socket.fd, cint(level), toCInt(opt), addr(valuei),
|
||||
sizeof(valuei).SockLen) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
proc connect*(socket: Socket, address: string, port = Port(0),
|
||||
proc connect*(socket: Socket, address: string, port = Port(0),
|
||||
af: Domain = AF_INET) {.tags: [ReadIOEffect].} =
|
||||
## 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
|
||||
|
|
@ -816,7 +816,7 @@ proc connect*(socket: Socket, address: string, port = Port(0),
|
|||
|
||||
freeaddrinfo(aiList)
|
||||
if not success: raiseOSError(lastError)
|
||||
|
||||
|
||||
when defined(ssl):
|
||||
if socket.isSSL:
|
||||
let ret = SSLConnect(socket.sslHandle)
|
||||
|
|
@ -825,7 +825,7 @@ proc connect*(socket: Socket, address: string, port = Port(0),
|
|||
case err
|
||||
of SSL_ERROR_ZERO_RETURN:
|
||||
raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.")
|
||||
of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT,
|
||||
of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT,
|
||||
SSL_ERROR_WANT_ACCEPT:
|
||||
raiseSslError("The operation did not complete. Perhaps you should use connectAsync?")
|
||||
of SSL_ERROR_WANT_X509_LOOKUP:
|
||||
|
|
@ -834,7 +834,7 @@ proc connect*(socket: Socket, address: string, port = Port(0),
|
|||
raiseSslError()
|
||||
else:
|
||||
raiseSslError("Unknown error")
|
||||
|
||||
|
||||
when false:
|
||||
var s: TSockAddrIn
|
||||
s.sin_addr.s_addr = inet_addr(address)
|
||||
|
|
@ -842,7 +842,7 @@ proc connect*(socket: Socket, address: string, port = Port(0),
|
|||
when defined(windows):
|
||||
s.sin_family = toU16(ord(af))
|
||||
else:
|
||||
case af
|
||||
case af
|
||||
of AF_UNIX: s.sin_family = posix.AF_UNIX
|
||||
of AF_INET: s.sin_family = posix.AF_INET
|
||||
of AF_INET6: s.sin_family = posix.AF_INET6
|
||||
|
|
@ -886,7 +886,7 @@ proc connectAsync*(socket: Socket, name: string, port = Port(0),
|
|||
if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS:
|
||||
success = true
|
||||
break
|
||||
|
||||
|
||||
it = it.ai_next
|
||||
|
||||
freeaddrinfo(aiList)
|
||||
|
|
@ -942,12 +942,12 @@ proc timeValFromMilliseconds(timeout = 500): Timeval =
|
|||
result.tv_sec = seconds.int32
|
||||
result.tv_usec = ((timeout - seconds * 1000) * 1000).int32
|
||||
|
||||
proc createFdSet(fd: var TFdSet, s: seq[Socket], m: var int) =
|
||||
proc createFdSet(fd: var TFdSet, s: seq[Socket], m: var int) =
|
||||
FD_ZERO(fd)
|
||||
for i in items(s):
|
||||
for i in items(s):
|
||||
m = max(m, int(i.fd))
|
||||
FD_SET(i.fd, fd)
|
||||
|
||||
|
||||
proc pruneSocketSet(s: var seq[Socket], fd: var TFdSet) =
|
||||
var i = 0
|
||||
var L = s.len
|
||||
|
|
@ -982,13 +982,13 @@ proc checkBuffer(readfds: var seq[Socket]): int =
|
|||
if result > 0:
|
||||
readfds = res
|
||||
|
||||
proc select*(readfds, writefds, exceptfds: var seq[Socket],
|
||||
timeout = 500): int {.tags: [ReadIOEffect].} =
|
||||
proc select*(readfds, writefds, exceptfds: var seq[Socket],
|
||||
timeout = 500): int {.tags: [ReadIOEffect].} =
|
||||
## Traditional select function. This function will return the number of
|
||||
## sockets that are ready to be read from, written to, or which have errors.
|
||||
## If there are none; 0 is returned.
|
||||
## If there are none; 0 is returned.
|
||||
## ``Timeout`` is in milliseconds and -1 can be specified for no timeout.
|
||||
##
|
||||
##
|
||||
## Sockets which are **not** ready for reading, writing or which don't have
|
||||
## errors waiting on them are removed from the ``readfds``, ``writefds``,
|
||||
## ``exceptfds`` sequences respectively.
|
||||
|
|
@ -997,44 +997,44 @@ proc select*(readfds, writefds, exceptfds: var seq[Socket],
|
|||
return buffersFilled
|
||||
|
||||
var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout)
|
||||
|
||||
|
||||
var rd, wr, ex: TFdSet
|
||||
var m = 0
|
||||
createFdSet((rd), readfds, m)
|
||||
createFdSet((wr), writefds, m)
|
||||
createFdSet((ex), exceptfds, m)
|
||||
|
||||
|
||||
if timeout != -1:
|
||||
result = int(select(cint(m+1), addr(rd), addr(wr), addr(ex), addr(tv)))
|
||||
else:
|
||||
result = int(select(cint(m+1), addr(rd), addr(wr), addr(ex), nil))
|
||||
|
||||
|
||||
pruneSocketSet(readfds, (rd))
|
||||
pruneSocketSet(writefds, (wr))
|
||||
pruneSocketSet(exceptfds, (ex))
|
||||
|
||||
proc select*(readfds, writefds: var seq[Socket],
|
||||
proc select*(readfds, writefds: var seq[Socket],
|
||||
timeout = 500): int {.tags: [ReadIOEffect].} =
|
||||
## Variant of select with only a read and write list.
|
||||
let buffersFilled = checkBuffer(readfds)
|
||||
if buffersFilled > 0:
|
||||
return buffersFilled
|
||||
var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout)
|
||||
|
||||
|
||||
var rd, wr: TFdSet
|
||||
var m = 0
|
||||
createFdSet((rd), readfds, m)
|
||||
createFdSet((wr), writefds, m)
|
||||
|
||||
|
||||
if timeout != -1:
|
||||
result = int(select(cint(m+1), addr(rd), addr(wr), nil, addr(tv)))
|
||||
else:
|
||||
result = int(select(cint(m+1), addr(rd), addr(wr), nil, nil))
|
||||
|
||||
|
||||
pruneSocketSet(readfds, (rd))
|
||||
pruneSocketSet(writefds, (wr))
|
||||
|
||||
proc selectWrite*(writefds: var seq[Socket],
|
||||
proc selectWrite*(writefds: var seq[Socket],
|
||||
timeout = 500): int {.tags: [ReadIOEffect].} =
|
||||
## 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
|
||||
|
|
@ -1044,16 +1044,16 @@ proc selectWrite*(writefds: var seq[Socket],
|
|||
## ``timeout`` is specified in milliseconds and ``-1`` can be specified for
|
||||
## an unlimited time.
|
||||
var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout)
|
||||
|
||||
|
||||
var wr: TFdSet
|
||||
var m = 0
|
||||
createFdSet((wr), writefds, m)
|
||||
|
||||
|
||||
if timeout != -1:
|
||||
result = int(select(cint(m+1), nil, addr(wr), nil, addr(tv)))
|
||||
else:
|
||||
result = int(select(cint(m+1), nil, addr(wr), nil, nil))
|
||||
|
||||
|
||||
pruneSocketSet(writefds, (wr))
|
||||
|
||||
proc select*(readfds: var seq[Socket], timeout = 500): int =
|
||||
|
|
@ -1062,16 +1062,16 @@ proc select*(readfds: var seq[Socket], timeout = 500): int =
|
|||
if buffersFilled > 0:
|
||||
return buffersFilled
|
||||
var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout)
|
||||
|
||||
|
||||
var rd: TFdSet
|
||||
var m = 0
|
||||
createFdSet((rd), readfds, m)
|
||||
|
||||
|
||||
if timeout != -1:
|
||||
result = int(select(cint(m+1), addr(rd), nil, nil, addr(tv)))
|
||||
else:
|
||||
result = int(select(cint(m+1), addr(rd), nil, nil, nil))
|
||||
|
||||
|
||||
pruneSocketSet(readfds, (rd))
|
||||
|
||||
proc readIntoBuf(socket: Socket, flags: int32): int =
|
||||
|
|
@ -1107,12 +1107,12 @@ proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [ReadIOEffect]
|
|||
if socket.isBuffered:
|
||||
if socket.bufLen == 0:
|
||||
retRead(0'i32, 0)
|
||||
|
||||
|
||||
var read = 0
|
||||
while read < size:
|
||||
if socket.currPos >= socket.bufLen:
|
||||
retRead(0'i32, read)
|
||||
|
||||
|
||||
let chunk = min(socket.bufLen-socket.currPos, size-read)
|
||||
var d = cast[cstring](data)
|
||||
copyMem(addr(d[read]), addr(socket.buffer[socket.currPos]), chunk)
|
||||
|
|
@ -1155,7 +1155,7 @@ proc waitFor(socket: Socket, waited: var float, timeout, size: int,
|
|||
else:
|
||||
if timeout - int(waited * 1000.0) < 1:
|
||||
raise newException(TimeoutError, "Call to '" & funcName & "' timed out.")
|
||||
|
||||
|
||||
when defined(ssl):
|
||||
if socket.isSSL:
|
||||
if socket.hasDataBuffered:
|
||||
|
|
@ -1164,7 +1164,7 @@ proc waitFor(socket: Socket, waited: var float, timeout, size: int,
|
|||
let sslPending = SSLPending(socket.sslHandle)
|
||||
if sslPending != 0:
|
||||
return sslPending
|
||||
|
||||
|
||||
var s = @[socket]
|
||||
var startTime = epochTime()
|
||||
let selRet = select(s, timeout - int(waited * 1000.0))
|
||||
|
|
@ -1176,8 +1176,8 @@ proc waitFor(socket: Socket, waited: var float, timeout, size: int,
|
|||
proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {.
|
||||
tags: [ReadIOEffect, TimeEffect].} =
|
||||
## overload with a ``timeout`` parameter in milliseconds.
|
||||
var waited = 0.0 # number of seconds already waited
|
||||
|
||||
var waited = 0.0 # number of seconds already waited
|
||||
|
||||
var read = 0
|
||||
while read < size:
|
||||
let avail = waitFor(socket, waited, timeout, size-read, "recv")
|
||||
|
|
@ -1187,7 +1187,7 @@ proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {.
|
|||
if result < 0:
|
||||
return result
|
||||
inc(read, result)
|
||||
|
||||
|
||||
result = read
|
||||
|
||||
proc recv*(socket: Socket, data: var string, size: int, timeout = -1): int =
|
||||
|
|
@ -1231,7 +1231,7 @@ proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} =
|
|||
var res = socket.readIntoBuf(0'i32)
|
||||
if res <= 0:
|
||||
result = res
|
||||
|
||||
|
||||
c = socket.buffer[socket.currPos]
|
||||
else:
|
||||
when defined(ssl):
|
||||
|
|
@ -1239,7 +1239,7 @@ proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} =
|
|||
if not socket.sslHasPeekChar:
|
||||
result = SSLRead(socket.sslHandle, addr(socket.sslPeekChar), 1)
|
||||
socket.sslHasPeekChar = true
|
||||
|
||||
|
||||
c = socket.sslPeekChar
|
||||
return
|
||||
result = recv(socket.fd, addr(c), 1, MSG_PEEK)
|
||||
|
|
@ -1251,11 +1251,11 @@ proc recvLine*(socket: Socket, line: var TaintedString, timeout = -1): bool {.
|
|||
## If a full line is received ``\r\L`` is not
|
||||
## added to ``line``, however if solely ``\r\L`` is received then ``line``
|
||||
## will be set to it.
|
||||
##
|
||||
##
|
||||
## ``True`` is returned if data is available. ``False`` suggests an
|
||||
## error, EOS exceptions are not raised and ``False`` is simply returned
|
||||
## instead.
|
||||
##
|
||||
##
|
||||
## If the socket is disconnected, ``line`` will be set to ``""`` and ``True``
|
||||
## will be returned.
|
||||
##
|
||||
|
|
@ -1264,7 +1264,7 @@ proc recvLine*(socket: Socket, line: var TaintedString, timeout = -1): bool {.
|
|||
##
|
||||
## **Deprecated since version 0.9.2**: This function has been deprecated in
|
||||
## favour of readLine.
|
||||
|
||||
|
||||
template addNLIfEmpty(): stmt =
|
||||
if line.len == 0:
|
||||
line.add("\c\L")
|
||||
|
|
@ -1286,7 +1286,7 @@ proc recvLine*(socket: Socket, line: var TaintedString, timeout = -1): bool {.
|
|||
elif n <= 0: return false
|
||||
addNLIfEmpty()
|
||||
return true
|
||||
elif c == '\L':
|
||||
elif c == '\L':
|
||||
addNLIfEmpty()
|
||||
return true
|
||||
add(line.string, c)
|
||||
|
|
@ -1298,14 +1298,14 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1) {.
|
|||
## If a full line is read ``\r\L`` is not
|
||||
## added to ``line``, however if solely ``\r\L`` is read then ``line``
|
||||
## will be set to it.
|
||||
##
|
||||
##
|
||||
## If the socket is disconnected, ``line`` will be set to ``""``.
|
||||
##
|
||||
## An EOS exception will be raised in the case of a socket error.
|
||||
##
|
||||
## A timeout can be specified in milliseconds, if data is not received within
|
||||
## the specified time an ETimeout exception will be raised.
|
||||
|
||||
|
||||
template addNLIfEmpty(): stmt =
|
||||
if line.len == 0:
|
||||
line.add("\c\L")
|
||||
|
|
@ -1327,12 +1327,12 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1) {.
|
|||
elif n <= 0: socket.raiseSocketError()
|
||||
addNLIfEmpty()
|
||||
return
|
||||
elif c == '\L':
|
||||
elif c == '\L':
|
||||
addNLIfEmpty()
|
||||
return
|
||||
add(line.string, c)
|
||||
|
||||
proc recvLineAsync*(socket: Socket,
|
||||
proc recvLineAsync*(socket: Socket,
|
||||
line: var TaintedString): RecvLineResult {.tags: [ReadIOEffect], deprecated.} =
|
||||
## Similar to ``recvLine`` but designed for non-blocking sockets.
|
||||
##
|
||||
|
|
@ -1350,21 +1350,21 @@ proc recvLineAsync*(socket: Socket,
|
|||
while true:
|
||||
var c: char
|
||||
var n = recv(socket, addr(c), 1)
|
||||
if n < 0:
|
||||
if n < 0:
|
||||
return (if line.len == 0: RecvFail else: RecvPartialLine)
|
||||
elif n == 0:
|
||||
elif n == 0:
|
||||
return (if line.len == 0: RecvDisconnected else: RecvPartialLine)
|
||||
if c == '\r':
|
||||
n = peekChar(socket, c)
|
||||
if n > 0 and c == '\L':
|
||||
discard recv(socket, addr(c), 1)
|
||||
elif n <= 0:
|
||||
elif n <= 0:
|
||||
return (if line.len == 0: RecvFail else: RecvPartialLine)
|
||||
return RecvFullLine
|
||||
elif c == '\L': return RecvFullLine
|
||||
add(line.string, c)
|
||||
|
||||
proc readLineAsync*(socket: Socket,
|
||||
proc readLineAsync*(socket: Socket,
|
||||
line: var TaintedString): ReadLineResult {.tags: [ReadIOEffect].} =
|
||||
## Similar to ``recvLine`` but designed for non-blocking sockets.
|
||||
##
|
||||
|
|
@ -1376,24 +1376,24 @@ proc readLineAsync*(socket: Socket,
|
|||
## * If no data could be retrieved; ``ReadNone`` is returned.
|
||||
## * If call to ``recv`` failed; **an EOS exception is raised.**
|
||||
setLen(line.string, 0)
|
||||
|
||||
|
||||
template errorOrNone =
|
||||
socket.raiseSocketError(async = true)
|
||||
return ReadNone
|
||||
|
||||
|
||||
while true:
|
||||
var c: char
|
||||
var n = recv(socket, addr(c), 1)
|
||||
#echo(n)
|
||||
if n < 0:
|
||||
if line.len == 0: errorOrNone else: return ReadPartialLine
|
||||
elif n == 0:
|
||||
elif n == 0:
|
||||
return (if line.len == 0: ReadDisconnected else: ReadPartialLine)
|
||||
if c == '\r':
|
||||
n = peekChar(socket, c)
|
||||
if n > 0 and c == '\L':
|
||||
discard recv(socket, addr(c), 1)
|
||||
elif n <= 0:
|
||||
elif n <= 0:
|
||||
if line.len == 0: errorOrNone else: return ReadPartialLine
|
||||
return ReadFullLine
|
||||
elif c == '\L': return ReadFullLine
|
||||
|
|
@ -1424,7 +1424,7 @@ proc recv*(socket: Socket): TaintedString {.tags: [ReadIOEffect], deprecated.} =
|
|||
var bytesRead = recv(socket, cstring(buf), bufSize-1)
|
||||
# Error
|
||||
if bytesRead == -1: OSError(osLastError())
|
||||
|
||||
|
||||
buf[bytesRead] = '\0' # might not be necessary
|
||||
setLen(buf, bytesRead)
|
||||
add(result.string, buf)
|
||||
|
|
@ -1442,13 +1442,13 @@ proc recvTimeout*(socket: Socket, timeout: int): TaintedString {.
|
|||
var s = @[socket]
|
||||
if s.select(timeout) != 1:
|
||||
raise newException(TimeoutError, "Call to recv() timed out.")
|
||||
|
||||
|
||||
return socket.recv
|
||||
{.pop.}
|
||||
|
||||
proc recvAsync*(socket: Socket, s: var TaintedString): bool {.
|
||||
tags: [ReadIOEffect], deprecated.} =
|
||||
## receives all the data from a non-blocking socket. If socket is non-blocking
|
||||
## receives all the data from a non-blocking socket. If socket is non-blocking
|
||||
## and there are no messages available, `False` will be returned.
|
||||
## Other socket errors will result in an ``EOS`` error.
|
||||
## If socket is not a connectionless socket and socket is not connected
|
||||
|
|
@ -1478,7 +1478,7 @@ proc recvAsync*(socket: Socket, s: var TaintedString): bool {.
|
|||
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
||||
raiseSslError()
|
||||
else: raiseSslError("Unknown Error")
|
||||
|
||||
|
||||
if bytesRead == -1 and not (when defined(ssl): socket.isSSL else: false):
|
||||
let err = osLastError()
|
||||
when defined(windows):
|
||||
|
|
@ -1510,7 +1510,7 @@ proc recvFrom*(socket: Socket, data: var string, length: int,
|
|||
## so when ``socket`` is buffered the non-buffered implementation will be
|
||||
## used. Therefore if ``socket`` contains something in its buffer this
|
||||
## function will make no effort to return it.
|
||||
|
||||
|
||||
# TODO: Buffered sockets
|
||||
data.setLen(length)
|
||||
var sockAddress: Sockaddr_in
|
||||
|
|
@ -1524,7 +1524,7 @@ proc recvFrom*(socket: Socket, data: var string, length: int,
|
|||
port = ntohs(sockAddress.sin_port).Port
|
||||
|
||||
proc recvFromAsync*(socket: Socket, data: var string, length: int,
|
||||
address: var string, port: var Port,
|
||||
address: var string, port: var Port,
|
||||
flags = 0'i32): bool {.tags: [ReadIOEffect].} =
|
||||
## Variant of ``recvFrom`` for non-blocking sockets. Unlike ``recvFrom``,
|
||||
## this function will raise an EOS error whenever a socket error occurs.
|
||||
|
|
@ -1573,11 +1573,11 @@ proc send*(socket: Socket, data: pointer, size: int): int {.
|
|||
when defined(ssl):
|
||||
if socket.isSSL:
|
||||
return SSLWrite(socket.sslHandle, cast[cstring](data), size)
|
||||
|
||||
|
||||
when defined(windows) or defined(macosx):
|
||||
result = send(socket.fd, data, size.cint, 0'i32)
|
||||
else:
|
||||
when defined(solaris):
|
||||
when defined(solaris):
|
||||
const MSG_NOSIGNAL = 0
|
||||
result = send(socket.fd, data, size, int32(MSG_NOSIGNAL))
|
||||
|
||||
|
|
@ -1590,7 +1590,7 @@ proc send*(socket: Socket, data: string) {.tags: [WriteIOEffect].} =
|
|||
when defined(ssl):
|
||||
if socket.isSSL:
|
||||
raiseSslError()
|
||||
|
||||
|
||||
raiseOSError(osLastError())
|
||||
|
||||
if sent != data.len:
|
||||
|
|
@ -1633,7 +1633,7 @@ proc sendAsync*(socket: Socket, data: string): int {.tags: [WriteIOEffect].} =
|
|||
if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK:
|
||||
return 0
|
||||
else: raiseOSError(err)
|
||||
|
||||
|
||||
|
||||
proc trySend*(socket: Socket, data: string): bool {.tags: [WriteIOEffect].} =
|
||||
## safe alternative to ``send``. Does not raise an EOS when an error occurs,
|
||||
|
|
@ -1644,7 +1644,7 @@ proc sendTo*(socket: Socket, address: string, port: Port, data: pointer,
|
|||
size: int, af: Domain = AF_INET, flags = 0'i32): int {.
|
||||
tags: [WriteIOEffect].} =
|
||||
## low-level sendTo proc. 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.
|
||||
##
|
||||
## **Note:** This proc is not available for SSL sockets.
|
||||
|
|
@ -1654,7 +1654,7 @@ proc sendTo*(socket: Socket, address: string, port: Port, data: pointer,
|
|||
hints.ai_socktype = toInt(SOCK_STREAM)
|
||||
hints.ai_protocol = toInt(IPPROTO_TCP)
|
||||
gaiNim(address, port, hints, aiList)
|
||||
|
||||
|
||||
# try all possibilities:
|
||||
var success = false
|
||||
var it = aiList
|
||||
|
|
@ -1668,7 +1668,7 @@ proc sendTo*(socket: Socket, address: string, port: Port, data: pointer,
|
|||
|
||||
freeaddrinfo(aiList)
|
||||
|
||||
proc sendTo*(socket: Socket, address: string, port: Port,
|
||||
proc sendTo*(socket: Socket, address: string, port: Port,
|
||||
data: string): int {.tags: [WriteIOEffect].} =
|
||||
## Friendlier version of the low-level ``sendTo``.
|
||||
result = socket.sendTo(address, port, cstring(data), data.len)
|
||||
|
|
@ -1677,10 +1677,10 @@ when defined(Windows):
|
|||
const
|
||||
IOCPARM_MASK = 127
|
||||
IOC_IN = int(-2147483648)
|
||||
FIONBIO = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or
|
||||
FIONBIO = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or
|
||||
(102 shl 8) or 126
|
||||
|
||||
proc ioctlsocket(s: SocketHandle, cmd: clong,
|
||||
proc ioctlsocket(s: SocketHandle, cmd: clong,
|
||||
argptr: ptr clong): cint {.
|
||||
stdcall, importc:"ioctlsocket", dynlib: "ws2_32.dll".}
|
||||
|
||||
|
|
@ -1713,7 +1713,7 @@ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int,
|
|||
## the connection to the server to be made.
|
||||
let originalStatus = not socket.nonblocking
|
||||
socket.setBlocking(false)
|
||||
|
||||
|
||||
socket.connectAsync(address, port, af)
|
||||
var s: seq[Socket] = @[socket]
|
||||
if selectWrite(s, timeout) != 1:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue