1 /+ dub.sdl: 2 name "t3" 3 dflags "-I../source" 4 #dflags "-debug" 5 lflags "-lcares" 6 buildRequirements "allowWarnings" 7 dependency "hio" version="*" 8 dependency "nbuff" version="*" 9 # debugVersions "hiosocket" 10 +/ 11 12 module tests.t3; 13 import std.experimental.logger; 14 import std.datetime; 15 import std.string; 16 import std.algorithm; 17 import std.range; 18 19 import core.atomic; 20 21 import hio.socket; 22 import hio.scheduler; 23 24 import nbuff: Nbuff; 25 26 shared int ops; 27 28 enum BufferSize = 4*1024; 29 30 void handler(HioSocket s) 31 { 32 scope(exit) 33 { 34 s.close(); 35 } 36 37 Nbuff buffer; 38 size_t p, scanned; 39 int connections; 40 41 while(true) 42 { 43 IOResult message = s.recv(BufferSize, 10.seconds); 44 if (message.error) 45 { 46 errorf("error receiving request"); 47 return; 48 } 49 if (message.timedout) 50 { 51 errorf("Timeout waiting for request"); 52 return; 53 } 54 if (message.input.length == 0) 55 { 56 break; 57 } 58 buffer.append(message.input); 59 p = buffer.countUntil("\n\n".representation, scanned); 60 if (p>=0) 61 { 62 connections++; 63 if (connections < 5) 64 { 65 s.send("HTTP/1.0 200 OK\nContent-Type: text/plain\nContent-Length: 10\n\n0123456789".representation); 66 buffer = Nbuff(); 67 p = 0; 68 scanned = 0; 69 continue; 70 } 71 else 72 { 73 s.send("HTTP/1.0 200 OK\nContent-Type: text/plain\nContent-Length: 10\nConnection: close\n\n0123456789".representation); 74 return; 75 } 76 } 77 else 78 { 79 scanned = buffer.length - 1; 80 } 81 } 82 } 83 84 void server(int so, int n) 85 { 86 auto sock = new HioSocket(so); 87 scope(exit) 88 { 89 sock.close(); 90 } 91 while(true) 92 { 93 auto client_socket = sock.accept(); 94 ops.atomicOp!"+="(1); 95 task(&handler, client_socket).start; 96 } 97 } 98 99 enum servers = 4; 100 101 void main() 102 { 103 globalLogLevel = LogLevel.info; 104 App({ 105 auto server_socket = new HioSocket(); 106 server_socket.bind("0.0.0.0:12345"); 107 server_socket.listen(1024); 108 109 auto server_threads = iota(servers).map!(i => threaded(&server, server_socket.fileno, i).start).array; 110 111 hlSleep(60.seconds); 112 113 server_threads.each!(t => t.stopThreadLoop()); 114 server_threads.each!(t => t.wait()); 115 server_socket.close(); 116 infof("done %d", ops); 117 }); 118 }