Merge branch 'bigbreak' of https://github.com/Araq/Nimrod into bigbreak
This commit is contained in:
commit
d3a7fa20ae
3 changed files with 59 additions and 59 deletions
|
|
@ -720,42 +720,42 @@ else:
|
||||||
|
|
||||||
proc update(sock: TAsyncFD, events: set[TEvent]) =
|
proc update(sock: TAsyncFD, events: set[TEvent]) =
|
||||||
let p = getGlobalDispatcher()
|
let p = getGlobalDispatcher()
|
||||||
assert sock.TSocketHandle in p.selector
|
assert sock.SocketHandle in p.selector
|
||||||
discard p.selector.update(sock.TSocketHandle, events)
|
discard p.selector.update(sock.SocketHandle, events)
|
||||||
|
|
||||||
proc register(sock: TAsyncFD) =
|
proc register(sock: TAsyncFD) =
|
||||||
let p = getGlobalDispatcher()
|
let p = getGlobalDispatcher()
|
||||||
var data = PData(sock: sock, readCBs: @[], writeCBs: @[])
|
var data = PData(sock: sock, readCBs: @[], writeCBs: @[])
|
||||||
p.selector.register(sock.TSocketHandle, {}, data.PObject)
|
p.selector.register(sock.SocketHandle, {}, data.PObject)
|
||||||
|
|
||||||
proc newAsyncRawSocket*(domain: TDomain = AF_INET,
|
proc newAsyncRawSocket*(domain: TDomain = AF_INET,
|
||||||
typ: TType = SOCK_STREAM,
|
typ: TType = SOCK_STREAM,
|
||||||
protocol: TProtocol = IPPROTO_TCP): TAsyncFD =
|
protocol: TProtocol = IPPROTO_TCP): TAsyncFD =
|
||||||
result = newRawSocket(domain, typ, protocol).TAsyncFD
|
result = newRawSocket(domain, typ, protocol).TAsyncFD
|
||||||
result.TSocketHandle.setBlocking(false)
|
result.SocketHandle.setBlocking(false)
|
||||||
register(result)
|
register(result)
|
||||||
|
|
||||||
proc closeSocket*(sock: TAsyncFD) =
|
proc closeSocket*(sock: TAsyncFD) =
|
||||||
let disp = getGlobalDispatcher()
|
let disp = getGlobalDispatcher()
|
||||||
sock.TSocketHandle.close()
|
sock.SocketHandle.close()
|
||||||
disp.selector.unregister(sock.TSocketHandle)
|
disp.selector.unregister(sock.SocketHandle)
|
||||||
|
|
||||||
proc unregister*(fd: TAsyncFD) =
|
proc unregister*(fd: TAsyncFD) =
|
||||||
getGlobalDispatcher().selector.unregister(fd.TSocketHandle)
|
getGlobalDispatcher().selector.unregister(fd.SocketHandle)
|
||||||
|
|
||||||
proc addRead(sock: TAsyncFD, cb: TCallback) =
|
proc addRead(sock: TAsyncFD, cb: TCallback) =
|
||||||
let p = getGlobalDispatcher()
|
let p = getGlobalDispatcher()
|
||||||
if sock.TSocketHandle notin p.selector:
|
if sock.SocketHandle notin p.selector:
|
||||||
raise newException(EInvalidValue, "File descriptor not registered.")
|
raise newException(EInvalidValue, "File descriptor not registered.")
|
||||||
p.selector[sock.TSocketHandle].data.PData.readCBs.add(cb)
|
p.selector[sock.SocketHandle].data.PData.readCBs.add(cb)
|
||||||
update(sock, p.selector[sock.TSocketHandle].events + {EvRead})
|
update(sock, p.selector[sock.SocketHandle].events + {EvRead})
|
||||||
|
|
||||||
proc addWrite(sock: TAsyncFD, cb: TCallback) =
|
proc addWrite(sock: TAsyncFD, cb: TCallback) =
|
||||||
let p = getGlobalDispatcher()
|
let p = getGlobalDispatcher()
|
||||||
if sock.TSocketHandle notin p.selector:
|
if sock.SocketHandle notin p.selector:
|
||||||
raise newException(EInvalidValue, "File descriptor not registered.")
|
raise newException(EInvalidValue, "File descriptor not registered.")
|
||||||
p.selector[sock.TSocketHandle].data.PData.writeCBs.add(cb)
|
p.selector[sock.SocketHandle].data.PData.writeCBs.add(cb)
|
||||||
update(sock, p.selector[sock.TSocketHandle].events + {EvWrite})
|
update(sock, p.selector[sock.SocketHandle].events + {EvWrite})
|
||||||
|
|
||||||
proc poll*(timeout = 500) =
|
proc poll*(timeout = 500) =
|
||||||
let p = getGlobalDispatcher()
|
let p = getGlobalDispatcher()
|
||||||
|
|
@ -808,7 +808,7 @@ else:
|
||||||
var lastError: TOSErrorCode
|
var lastError: TOSErrorCode
|
||||||
var it = aiList
|
var it = aiList
|
||||||
while it != nil:
|
while it != nil:
|
||||||
var ret = connect(socket.TSocketHandle, it.ai_addr, it.ai_addrlen.TSocklen)
|
var ret = connect(socket.SocketHandle, it.ai_addr, it.ai_addrlen.Socklen)
|
||||||
if ret == 0:
|
if ret == 0:
|
||||||
# Request to connect completed immediately.
|
# Request to connect completed immediately.
|
||||||
success = true
|
success = true
|
||||||
|
|
@ -837,7 +837,7 @@ else:
|
||||||
|
|
||||||
proc cb(sock: TAsyncFD): bool =
|
proc cb(sock: TAsyncFD): bool =
|
||||||
result = true
|
result = true
|
||||||
let res = recv(sock.TSocketHandle, addr readBuffer[0], size.cint,
|
let res = recv(sock.SocketHandle, addr readBuffer[0], size.cint,
|
||||||
flags.toOSFlags())
|
flags.toOSFlags())
|
||||||
#echo("recv cb res: ", res)
|
#echo("recv cb res: ", res)
|
||||||
if res < 0:
|
if res < 0:
|
||||||
|
|
@ -870,7 +870,7 @@ else:
|
||||||
result = true
|
result = true
|
||||||
let netSize = data.len-written
|
let netSize = data.len-written
|
||||||
var d = data.cstring
|
var d = data.cstring
|
||||||
let res = send(sock.TSocketHandle, addr d[written], netSize.cint,
|
let res = send(sock.SocketHandle, addr d[written], netSize.cint,
|
||||||
MSG_NOSIGNAL)
|
MSG_NOSIGNAL)
|
||||||
if res < 0:
|
if res < 0:
|
||||||
let lastError = osLastError()
|
let lastError = osLastError()
|
||||||
|
|
@ -898,10 +898,10 @@ else:
|
||||||
client: TAsyncFD]]("acceptAddr")
|
client: TAsyncFD]]("acceptAddr")
|
||||||
proc cb(sock: TAsyncFD): bool =
|
proc cb(sock: TAsyncFD): bool =
|
||||||
result = true
|
result = true
|
||||||
var sockAddress: Tsockaddr_in
|
var sockAddress: SockAddr_in
|
||||||
var addrLen = sizeof(sockAddress).TSocklen
|
var addrLen = sizeof(sockAddress).Socklen
|
||||||
var client = accept(sock.TSocketHandle,
|
var client = accept(sock.SocketHandle,
|
||||||
cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen))
|
cast[ptr SockAddr](addr(sockAddress)), addr(addrLen))
|
||||||
if client == osInvalidSocket:
|
if client == osInvalidSocket:
|
||||||
let lastError = osLastError()
|
let lastError = osLastError()
|
||||||
assert lastError.int32 notin {EWOULDBLOCK, EAGAIN}
|
assert lastError.int32 notin {EWOULDBLOCK, EAGAIN}
|
||||||
|
|
|
||||||
|
|
@ -125,16 +125,16 @@ when defined(ssl):
|
||||||
ErrLoadBioStrings()
|
ErrLoadBioStrings()
|
||||||
OpenSSL_add_all_algorithms()
|
OpenSSL_add_all_algorithms()
|
||||||
|
|
||||||
proc SSLError(s = "") =
|
proc raiseSSLError(s = "") =
|
||||||
if s != "":
|
if s != "":
|
||||||
raise newException(ESSL, s)
|
raise newException(SSLError, s)
|
||||||
let err = ErrPeekLastError()
|
let err = ErrPeekLastError()
|
||||||
if err == 0:
|
if err == 0:
|
||||||
raise newException(ESSL, "No error reported.")
|
raise newException(SSLError, "No error reported.")
|
||||||
if err == -1:
|
if err == -1:
|
||||||
OSError(OSLastError())
|
raiseOSError(osLastError())
|
||||||
var errStr = ErrErrorString(err, nil)
|
var errStr = ErrErrorString(err, nil)
|
||||||
raise newException(ESSL, $errStr)
|
raise newException(SSLError, $errStr)
|
||||||
|
|
||||||
# http://simplestcodings.blogspot.co.uk/2010/08/secure-server-client-using-openssl-in-c.html
|
# http://simplestcodings.blogspot.co.uk/2010/08/secure-server-client-using-openssl-in-c.html
|
||||||
proc loadCertificates(ctx: PSSL_CTX, certFile, keyFile: string) =
|
proc loadCertificates(ctx: PSSL_CTX, certFile, keyFile: string) =
|
||||||
|
|
@ -146,23 +146,23 @@ when defined(ssl):
|
||||||
if certFile != "":
|
if certFile != "":
|
||||||
var ret = SSLCTXUseCertificateChainFile(ctx, certFile)
|
var ret = SSLCTXUseCertificateChainFile(ctx, certFile)
|
||||||
if ret != 1:
|
if ret != 1:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
|
|
||||||
# TODO: Password? www.rtfm.com/openssl-examples/part1.pdf
|
# TODO: Password? www.rtfm.com/openssl-examples/part1.pdf
|
||||||
if keyFile != "":
|
if keyFile != "":
|
||||||
if SSL_CTX_use_PrivateKey_file(ctx, keyFile,
|
if SSL_CTX_use_PrivateKey_file(ctx, keyFile,
|
||||||
SSL_FILETYPE_PEM) != 1:
|
SSL_FILETYPE_PEM) != 1:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
|
|
||||||
if SSL_CTX_check_private_key(ctx) != 1:
|
if SSL_CTX_check_private_key(ctx) != 1:
|
||||||
SSLError("Verification of private key file failed.")
|
raiseSSLError("Verification of private key file failed.")
|
||||||
|
|
||||||
proc newContext*(protVersion = ProtSSLv23, verifyMode = CVerifyPeer,
|
proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer,
|
||||||
certFile = "", keyFile = ""): PSSLContext =
|
certFile = "", keyFile = ""): PSSLContext =
|
||||||
## Creates an SSL context.
|
## Creates an SSL context.
|
||||||
##
|
##
|
||||||
## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are
|
## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are
|
||||||
## 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 currently only two options for verify mode;
|
## There are currently only two options for verify mode;
|
||||||
|
|
@ -189,14 +189,14 @@ when defined(ssl):
|
||||||
newCTX = SSL_CTX_new(TLSv1_method())
|
newCTX = SSL_CTX_new(TLSv1_method())
|
||||||
|
|
||||||
if newCTX.SSLCTXSetCipherList("ALL") != 1:
|
if newCTX.SSLCTXSetCipherList("ALL") != 1:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
case verifyMode
|
case verifyMode
|
||||||
of CVerifyPeer:
|
of CVerifyPeer:
|
||||||
newCTX.SSLCTXSetVerify(SSLVerifyPeer, nil)
|
newCTX.SSLCTXSetVerify(SSLVerifyPeer, nil)
|
||||||
of CVerifyNone:
|
of CVerifyNone:
|
||||||
newCTX.SSLCTXSetVerify(SSLVerifyNone, nil)
|
newCTX.SSLCTXSetVerify(SSLVerifyNone, nil)
|
||||||
if newCTX == nil:
|
if newCTX == nil:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
|
|
||||||
discard newCTX.SSLCTXSetMode(SSL_MODE_AUTO_RETRY)
|
discard newCTX.SSLCTXSetMode(SSL_MODE_AUTO_RETRY)
|
||||||
newCTX.loadCertificates(certFile, keyFile)
|
newCTX.loadCertificates(certFile, keyFile)
|
||||||
|
|
@ -215,10 +215,10 @@ when defined(ssl):
|
||||||
socket.sslNoHandshake = false
|
socket.sslNoHandshake = false
|
||||||
socket.sslHasPeekChar = false
|
socket.sslHasPeekChar = false
|
||||||
if socket.sslHandle == nil:
|
if socket.sslHandle == nil:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
|
|
||||||
if SSLSetFd(socket.sslHandle, socket.fd) != 1:
|
if SSLSetFd(socket.sslHandle, socket.fd) != 1:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
|
|
||||||
proc socketError*(socket: Socket, err: int = -1, async = false,
|
proc socketError*(socket: Socket, err: int = -1, async = false,
|
||||||
lastError = (-1).OSErrorCode) =
|
lastError = (-1).OSErrorCode) =
|
||||||
|
|
@ -235,20 +235,20 @@ proc socketError*(socket: Socket, err: int = -1, async = false,
|
||||||
var ret = SSLGetError(socket.sslHandle, err.cint)
|
var ret = SSLGetError(socket.sslHandle, err.cint)
|
||||||
case ret
|
case ret
|
||||||
of SSL_ERROR_ZERO_RETURN:
|
of SSL_ERROR_ZERO_RETURN:
|
||||||
SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
|
raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
|
||||||
of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT:
|
of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT:
|
||||||
if async:
|
if async:
|
||||||
return
|
return
|
||||||
else: SSLError("Not enough data on socket.")
|
else: raiseSSLError("Not enough data on socket.")
|
||||||
of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ:
|
of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ:
|
||||||
if async:
|
if async:
|
||||||
return
|
return
|
||||||
else: SSLError("Not enough data on socket.")
|
else: raiseSSLError("Not enough data on socket.")
|
||||||
of SSL_ERROR_WANT_X509_LOOKUP:
|
of SSL_ERROR_WANT_X509_LOOKUP:
|
||||||
SSLError("Function for x509 lookup has been called.")
|
raiseSSLError("Function for x509 lookup has been called.")
|
||||||
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
else: SSLError("Unknown Error")
|
else: raiseSSLError("Unknown Error")
|
||||||
|
|
||||||
if err == -1 and not (when defined(ssl): socket.isSSL else: false):
|
if err == -1 and not (when defined(ssl): socket.isSSL else: false):
|
||||||
let lastE = if lastError.int == -1: osLastError() else: lastError
|
let lastE = if lastError.int == -1: osLastError() else: lastError
|
||||||
|
|
@ -260,7 +260,7 @@ proc socketError*(socket: Socket, err: int = -1, async = false,
|
||||||
else:
|
else:
|
||||||
if lastE.int32 == EAGAIN or lastE.int32 == EWOULDBLOCK:
|
if lastE.int32 == EAGAIN or lastE.int32 == EWOULDBLOCK:
|
||||||
return
|
return
|
||||||
else: osError(lastE)
|
else: raiseOSError(lastE)
|
||||||
else: raiseOSError(lastE)
|
else: raiseOSError(lastE)
|
||||||
|
|
||||||
proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
|
proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
|
||||||
|
|
@ -371,17 +371,17 @@ when false: #defined(ssl):
|
||||||
if err != SSL_ERROR_WANT_ACCEPT:
|
if err != SSL_ERROR_WANT_ACCEPT:
|
||||||
case err
|
case err
|
||||||
of SSL_ERROR_ZERO_RETURN:
|
of SSL_ERROR_ZERO_RETURN:
|
||||||
SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
|
raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
|
||||||
of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE,
|
of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE,
|
||||||
SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT:
|
SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT:
|
||||||
client.sslNoHandshake = true
|
client.sslNoHandshake = true
|
||||||
return AcceptNoHandshake
|
return AcceptNoHandshake
|
||||||
of SSL_ERROR_WANT_X509_LOOKUP:
|
of SSL_ERROR_WANT_X509_LOOKUP:
|
||||||
SSLError("Function for x509 lookup has been called.")
|
raiseSSLError("Function for x509 lookup has been called.")
|
||||||
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
else:
|
else:
|
||||||
SSLError("Unknown error")
|
raiseSSLError("Unknown error")
|
||||||
client.sslNoHandshake = false
|
client.sslNoHandshake = false
|
||||||
|
|
||||||
if client.isSSL and client.sslNoHandshake:
|
if client.isSSL and client.sslNoHandshake:
|
||||||
|
|
@ -485,19 +485,19 @@ when defined(ssl):
|
||||||
var errret = SSLGetError(socket.sslHandle, ret)
|
var errret = SSLGetError(socket.sslHandle, ret)
|
||||||
case errret
|
case errret
|
||||||
of SSL_ERROR_ZERO_RETURN:
|
of SSL_ERROR_ZERO_RETURN:
|
||||||
SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
|
raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
|
||||||
of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT,
|
of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT,
|
||||||
SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE:
|
SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE:
|
||||||
return false
|
return false
|
||||||
of SSL_ERROR_WANT_X509_LOOKUP:
|
of SSL_ERROR_WANT_X509_LOOKUP:
|
||||||
SSLError("Function for x509 lookup has been called.")
|
raiseSSLError("Function for x509 lookup has been called.")
|
||||||
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
||||||
SSLError()
|
raiseSSLError()
|
||||||
else:
|
else:
|
||||||
SSLError("Unknown Error")
|
raiseSSLError("Unknown Error")
|
||||||
socket.sslNoHandshake = false
|
socket.sslNoHandshake = false
|
||||||
else:
|
else:
|
||||||
SSLError("Socket is not an SSL socket.")
|
raiseSSLError("Socket is not an SSL socket.")
|
||||||
|
|
||||||
proc gotHandshake*(socket: PSocket): bool =
|
proc gotHandshake*(socket: PSocket): bool =
|
||||||
## Determines whether a handshake has occurred between a client (``socket``)
|
## Determines whether a handshake has occurred between a client (``socket``)
|
||||||
|
|
@ -507,7 +507,7 @@ when defined(ssl):
|
||||||
if socket.isSSL:
|
if socket.isSSL:
|
||||||
return not socket.sslNoHandshake
|
return not socket.sslNoHandshake
|
||||||
else:
|
else:
|
||||||
SSLError("Socket is not an SSL socket.")
|
raiseSSLError("Socket is not an SSL socket.")
|
||||||
|
|
||||||
proc hasDataBuffered*(s: Socket): bool =
|
proc hasDataBuffered*(s: Socket): bool =
|
||||||
## Determines whether a socket has data buffered.
|
## Determines whether a socket has data buffered.
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,7 @@ proc BIO_get_ssl*(bio: PBIO, ssl: ptr PSSL): int =
|
||||||
proc BIO_set_conn_hostname*(bio: PBIO, name: cstring): int =
|
proc BIO_set_conn_hostname*(bio: PBIO, name: cstring): int =
|
||||||
return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, name)
|
return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, name)
|
||||||
proc BIO_do_handshake*(bio: PBIO): int =
|
proc BIO_do_handshake*(bio: PBIO): int =
|
||||||
return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NIL)
|
return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, nil)
|
||||||
proc BIO_do_connect*(bio: PBIO): int =
|
proc BIO_do_connect*(bio: PBIO): int =
|
||||||
return BIO_do_handshake(bio)
|
return BIO_do_handshake(bio)
|
||||||
|
|
||||||
|
|
@ -448,11 +448,11 @@ type
|
||||||
|
|
||||||
{.pragma: ic, importc: "$1".}
|
{.pragma: ic, importc: "$1".}
|
||||||
{.push callconv:cdecl, dynlib:DLLUtilName.}
|
{.push callconv:cdecl, dynlib:DLLUtilName.}
|
||||||
proc MD5_Init*(c: var MD5_CTX): cint{.ic.}
|
proc md5_Init*(c: var MD5_CTX): cint{.ic.}
|
||||||
proc MD5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.ic.}
|
proc md5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.ic.}
|
||||||
proc MD5_Final*(md: cstring; c: var MD5_CTX): cint{.ic.}
|
proc md5_Final*(md: cstring; c: var MD5_CTX): cint{.ic.}
|
||||||
proc MD5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.ic.}
|
proc md5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.ic.}
|
||||||
proc MD5_Transform*(c: var MD5_CTX; b: ptr cuchar){.ic.}
|
proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.ic.}
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
from strutils import toHex,toLower
|
from strutils import toHex,toLower
|
||||||
|
|
@ -463,7 +463,7 @@ proc hexStr (buf:cstring): string =
|
||||||
for i in 0 .. <16:
|
for i in 0 .. <16:
|
||||||
result.add toHex(buf[i].ord, 2).toLower
|
result.add toHex(buf[i].ord, 2).toLower
|
||||||
|
|
||||||
proc MD5_File* (file: string): string {.raises:[EIO,Ebase].} =
|
proc md5_File* (file: string): string {.raises:[EIO,Ebase].} =
|
||||||
## Generate MD5 hash for a file. Result is a 32 character
|
## Generate MD5 hash for a file. Result is a 32 character
|
||||||
# hex string with lowercase characters (like the output
|
# hex string with lowercase characters (like the output
|
||||||
# of `md5sum`
|
# of `md5sum`
|
||||||
|
|
@ -483,7 +483,7 @@ proc MD5_File* (file: string): string {.raises:[EIO,Ebase].} =
|
||||||
|
|
||||||
result = hexStr(buf)
|
result = hexStr(buf)
|
||||||
|
|
||||||
proc MD5_Str* (str:string): string {.raises:[EIO].} =
|
proc md5_Str* (str:string): string {.raises:[EIO].} =
|
||||||
##Generate MD5 hash for a string. Result is a 32 character
|
##Generate MD5 hash for a string. Result is a 32 character
|
||||||
#hex string with lowercase characters
|
#hex string with lowercase characters
|
||||||
var
|
var
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue