1 module client; 2 3 import std.stdio; 4 5 // import hunt.http.client.ClientHttp2SessionListener; 6 // import hunt.http.client.HttpClient; 7 // import hunt.http.client.Http2ClientConnection; 8 // import hunt.http.client.HttpClientConnection; 9 10 import hunt.http.client; 11 import hunt.http.codec.http.frame; 12 import hunt.http.codec.http.model; 13 import hunt.http.codec.http.stream; 14 15 import hunt.collection; 16 import hunt.concurrency.FuturePromise; 17 import hunt.Exceptions; 18 import hunt.logging; 19 import hunt.util.Common; 20 21 import core.time; 22 import std.format; 23 24 25 void main(string[] args) { 26 27 enum host = "127.0.0.1"; 28 enum port = 8080; 29 30 HttpClientOptions clientOptions = new HttpClientOptions(); 31 clientOptions.setSecureConnectionEnabled(false); 32 clientOptions.setFlowControlStrategy("simple"); 33 clientOptions.getTcpConfiguration().setIdleTimeout(60.seconds); 34 clientOptions.setProtocol(HttpVersion.HTTP_2.toString()); 35 36 FuturePromise!(HttpClientConnection) promise = new FuturePromise!(HttpClientConnection)(); 37 HttpClient client = new HttpClient(clientOptions); 38 39 client.connect(host, port, promise, new class ClientHttp2SessionListener { 40 41 override 42 Map!(int, int) onPreface(Session session) { 43 infof("client preface: %s", session); 44 Map!(int, int) settings = new HashMap!(int, int)(); 45 settings.put(SettingsFrame.HEADER_TABLE_SIZE, clientOptions.getMaxDynamicTableSize()); 46 settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, clientOptions.getInitialStreamSendWindow()); 47 return settings; 48 } 49 50 override 51 StreamListener onNewStream(Stream stream, HeadersFrame frame) { 52 return null; 53 } 54 55 override 56 void onSettings(Session session, SettingsFrame frame) { 57 infof("client received settings frame: %s", frame.toString()); 58 } 59 60 override 61 void onPing(Session session, PingFrame frame) { 62 } 63 64 override 65 void onReset(Session session, ResetFrame frame) { 66 infof("client resets %s", frame.toString()); 67 } 68 69 override 70 void onClose(Session session, GoAwayFrame frame) { 71 infof("client is closed %s", frame.toString()); 72 } 73 74 override 75 void onFailure(Session session, Exception failure) { 76 errorf("client failure, %s", failure, session); 77 } 78 79 override 80 bool onIdleTimeout(Session session) { 81 return false; 82 } 83 }); 84 85 86 HttpFields fields = new HttpFields(); 87 fields.put(HttpHeader.ACCEPT, "text/html"); 88 fields.put(HttpHeader.USER_AGENT, "Hunt Client 1.0"); 89 fields.put(HttpHeader.CONTENT_LENGTH, "28"); 90 91 HttpRequest metaData = new HttpRequest("POST", HttpScheme.HTTP, host, port, 92 "/data", HttpVersion.HTTP_2, fields); 93 94 HttpConnection connection = promise.get(); 95 Http2ClientConnection clientConnection = cast(Http2ClientConnection) connection; 96 97 FuturePromise!(Stream) streamPromise = new FuturePromise!(Stream)(); 98 auto http2Session = clientConnection.getHttp2Session(); 99 http2Session.newStream(new HeadersFrame(metaData, null, false), streamPromise, 100 new class StreamListener { 101 102 override 103 void onHeaders(Stream stream, HeadersFrame frame) { 104 infof("client received headers: %s", frame.toString()); 105 } 106 107 override 108 StreamListener onPush(Stream stream, 109 PushPromiseFrame frame) { 110 return null; 111 } 112 113 override 114 void onData(Stream stream, DataFrame frame, hunt.util.Common.Callback callback) { 115 infof("client received data: %s, %s", BufferUtils.toString(frame.getData()), frame.toString()); 116 callback.succeeded(); 117 } 118 119 void onReset(Stream stream, ResetFrame frame, hunt.util.Common.Callback callback) { 120 try { 121 onReset(stream, frame); 122 callback.succeeded(); 123 } catch (Exception x) { 124 callback.failed(x); 125 } 126 } 127 128 override 129 void onReset(Stream stream, ResetFrame frame) { 130 infof("client reset: %s, %s", stream, frame.toString()); 131 } 132 133 override 134 bool onIdleTimeout(Stream stream, Exception x) { 135 errorf("the client stream %s is timeout", stream.toString()); 136 return true; 137 } 138 139 override string toString() 140 { 141 return super.toString(); 142 } 143 144 } 145 ); 146 147 Stream clientStream = streamPromise.get(); 148 infof("client stream id is %d", clientStream.getId()); 149 150 DataFrame smallDataFrame = new DataFrame(clientStream.getId(), 151 BufferUtils.toBuffer(cast(byte[])"hello world!"), false); 152 153 DataFrame bigDataFrame = new DataFrame(clientStream.getId(), 154 BufferUtils.toBuffer(cast(byte[])"big hello world!"), true); 155 156 clientStream.data(smallDataFrame, new class NoopCallback { 157 158 override 159 void succeeded() { 160 infof("client sent small data successfully"); 161 clientStream.data(bigDataFrame, new class NoopCallback { 162 163 override 164 void succeeded() { 165 infof("client sent big data successfully"); 166 } 167 168 override 169 void failed(Exception x) { 170 warning("client failed to send big data "); 171 } 172 }); 173 } 174 175 override 176 void failed(Exception x) { 177 infof("client sends small data failure"); 178 } 179 }); 180 181 }