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 }