123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- discard """
- matrix: "--mm:refc; --mm:orc"
- joinable: false
- disabled: "freebsd" # see #15713
- disabled: "openbsd" # see #15713
- disabled: "netbsd" # see #15713
- """
- import std/[net, nativesockets, assertions, typedthreads]
- when defined(posix): import os, posix
- else:
- import winlean
- const SD_SEND = 1
- when not defined(ssl):
- {.error: "This test must be compiled with -d:ssl".}
- const DummyData = "dummy data\n"
- proc abruptShutdown(port: Port) {.thread.} =
- let clientContext = newContext(verifyMode = CVerifyNone)
- var client = newSocket(buffered = false)
- clientContext.wrapSocket(client)
- client.connect("localhost", port)
- discard client.recvLine()
- client.getFd.close()
- proc notifiedShutdown(port: Port) {.thread.} =
- let clientContext = newContext(verifyMode = CVerifyNone)
- var client = newSocket(buffered = false)
- clientContext.wrapSocket(client)
- client.connect("localhost", port)
- discard client.recvLine()
- client.close()
- proc main() =
- when defined(posix):
- var
- ignoreAction = Sigaction(sa_handler: SIG_IGN)
- oldSigPipeHandler: Sigaction
- if sigemptyset(ignoreAction.sa_mask) == -1:
- raiseOSError(osLastError(), "Couldn't create an empty signal set")
- if sigaction(SIGPIPE, ignoreAction, oldSigPipeHandler) == -1:
- raiseOSError(osLastError(), "Couldn't ignore SIGPIPE")
- let serverContext = newContext(verifyMode = CVerifyNone,
- certFile = "tests/testdata/mycert.pem",
- keyFile = "tests/testdata/mycert.pem")
- block peer_close_during_write_without_shutdown:
- var server = newSocket(buffered = false)
- defer: server.close()
- serverContext.wrapSocket(server)
- server.bindAddr(address = "localhost")
- let (_, port) = server.getLocalAddr()
- server.listen()
- var clientThread: Thread[Port]
- createThread(clientThread, abruptShutdown, port)
- var peer: Socket
- try:
- server.accept(peer)
- peer.send(DummyData)
- joinThread clientThread
- while true:
- # Send data until we get EPIPE.
- peer.send(DummyData, {})
- except OSError:
- discard
- finally:
- peer.close()
- when defined(posix):
- if sigaction(SIGPIPE, oldSigPipeHandler, nil) == -1:
- raiseOSError(osLastError(), "Couldn't restore SIGPIPE handler")
- block peer_close_before_received_shutdown:
- var server = newSocket(buffered = false)
- defer: server.close()
- serverContext.wrapSocket(server)
- server.bindAddr(address = "localhost")
- let (_, port) = server.getLocalAddr()
- server.listen()
- var clientThread: Thread[Port]
- createThread(clientThread, abruptShutdown, port)
- var peer: Socket
- try:
- server.accept(peer)
- peer.send(DummyData)
- joinThread clientThread
- # Tell the OS to close off the write side so shutdown attempts will
- # be met with SIGPIPE.
- when defined(posix):
- discard peer.getFd.shutdown(SHUT_WR)
- else:
- discard peer.getFd.shutdown(SD_SEND)
- finally:
- peer.close()
- block peer_close_after_received_shutdown:
- var server = newSocket(buffered = false)
- defer: server.close()
- serverContext.wrapSocket(server)
- server.bindAddr(address = "localhost")
- let (_, port) = server.getLocalAddr()
- server.listen()
- var clientThread: Thread[Port]
- createThread(clientThread, notifiedShutdown, port)
- var peer: Socket
- try:
- server.accept(peer)
- peer.send(DummyData)
- doAssert peer.recv(1024) == "" # Get the shutdown notification
- joinThread clientThread
- # Tell the OS to close off the write side so shutdown attempts will
- # be met with SIGPIPE.
- when defined(posix):
- discard peer.getFd.shutdown(SHUT_WR)
- else:
- discard peer.getFd.shutdown(SD_SEND)
- finally:
- peer.close()
- when isMainModule: main()
|