1 module HttpClientTest;
2 
3 import hunt.http.client;
4 
5 import hunt.logging.ConsoleLogger;
6 import hunt.Exceptions;
7 import hunt.util.DateTime;
8 import hunt.util.MimeType;
9 
10 import std.stdio;
11 import core.runtime;
12 
13 // string str = runGet("http://10.1.223.222/test.html");
14 // enum string httpUrl = runGet("http://10.1.223.222:8080/index.html");
15 // string str = runGet("http://127.0.0.1:8080/json");
16 // string str = runGet("http://www.putao.com/");
17 
18 void main(string[] args) {
19     // trace_setlogfilename("./hunt-profile.log");
20     // profilegc_setlogfilename("./hunt-gc.log");
21 
22     testSimpleHttpClient();
23     // testHttpClientWithCookie();
24     // testHttpClientWithMultipart();
25     // testWebSocketClient();
26     // testHttpClientWithTLS();
27     // testHttpClientWithMutualTLS();
28     version (WITH_HUNT_TRACE)
29         testOpenTracing();
30 }
31 
32 void testSimpleHttpClient() {
33 
34     HttpClientTest test = new HttpClientTest();
35     scope(exit) {
36         test.close();
37     }
38     try {
39         test.testGet();
40         // test.testGetHttps();
41         // test.testAsynchronousGet();
42         // test.testPost();
43         // test.testFormPost();
44 
45     } catch (Exception ex) {
46         warning(ex);
47     }
48 }
49 
50 void testHttpClientWithCookie() {
51     string url = "http://127.0.0.1:8080/session/foo";
52     HttpClient client = new HttpClient();
53     scope (exit) {
54         client.close();
55     }
56 
57     client.useCookieStore();
58 
59     // post
60     FormBody formBody = new FormBody.Builder().add("age", 20).build();
61 
62     Response response = postForm(client, url, formBody);
63 
64     if (response.haveBody()) {
65         warningf("response: %s", response.getBody().asString());
66     }
67 
68     // Cookie[] cookies = response.cookies();
69     // foreach(c ; cookies) {
70     //     trace(c.toString());
71     // }
72 
73     // get
74     RequestBuilder rb = new RequestBuilder().url(url);
75     // rb.cookies(cookies);
76 
77     Request request = rb.build();
78     response = client.newCall(request).execute();
79 
80     if (response !is null) {
81         tracef("status code: %d", response.getStatus());
82         warning("response: ", response.getBody().asString());
83     }
84 }
85 
86 void testHttpClientWithMultipart() {
87     // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
88     // string url = "http://127.0.0.1:8080/upload/file";
89     string url = "http://10.1.223.222:8080/upload/file";
90     HttpClient client = new HttpClient();
91     scope (exit) {
92         client.close();
93     }
94     // client.useCookieStore();
95 
96     // post
97     MultipartBody requestBody = new MultipartBody.Builder() // .setType(MultipartBody.FORM)
98     // .enableChunk()
99     .addFormDataPart("title",
100             "Putao Logo", MimeType.TEXT_PLAIN_VALUE)
101         .addFormDataPart("image", "favicon.ico", HttpBody.create("image/ico", "dub.json")) // HttpBody.createFromFile("image/ico", "dub.json"))
102         // HttpBody.createFromFile("image/ico", "resources/favicon.ico"))
103         .build();
104 
105     Response response = postForm(client, url, requestBody);
106 
107     if (response.haveBody()) {
108         warningf("response: %s", response.getBody().asString());
109     }
110 }
111 
112 Response postForm(HttpClient client, string url, HttpBody content) {
113     Request request = new RequestBuilder().url(url) // .header("Authorization", "Basic cHV0YW86MjAxOQ==")
114     .authorization(
115             AuthenticationScheme.Basic, "cHV0YW86MjAxOQ==").post(content).build();
116 
117     Response response = client.newCall(request).execute();
118     return response;
119 }
120 
121 void testWebSocketClient() {
122 
123     HttpClient client = new HttpClient();
124     scope (exit) {
125         client.close();
126     }
127     //
128     string url = "http://127.0.0.1:8080/ws1";
129     Request request = new RequestBuilder().url(url) // .header("Authorization", "Basic cHV0YW86MjAxOQ==")
130     .authorization(
131             AuthenticationScheme.Basic, "cHV0YW86MjAxOQ==").build();
132 
133     // dfmt off
134     WebSocketConnection wsConn = client.newWebSocket(request,
135             new class AbstractWebSocketMessageHandler {
136                 override void onOpen(WebSocketConnection connection) {
137                     warning("Connection opened"); connection.sendText(
138                         "Hello WebSocket. " ~ DateTime.getTimeAsGMT());}
139 
140                     override void onText(WebSocketConnection connection, string text) {
141                         warningf("received (from %s): %s", connection.getRemoteAddress(), text);
142                     }
143                 }
144     );
145     // dfmt on
146     // import core.thread;
147     // import core.time;
148     // Thread.sleep(5.seconds);
149     // wsConn.close();
150     // client.close();
151 }
152 
153 void testHttpClientWithTLS() {
154     string url = "https://10.1.223.222:443/";
155     // string url = "https://publicobject.com/helloworld.txt";
156     // string url = "https://www.bing.com/";
157 
158     HttpClient client = new HttpClient();
159     scope (exit) {
160         client.close();
161     }
162 
163     Request request = new RequestBuilder().url(url).build();
164     Response response = client.newCall(request).execute();
165 
166     if (response !is null) {
167         tracef("status code: %d", response.getStatus());
168         trace(response.getBody().asString());
169     }
170 
171     warning("done.");
172 }
173 
174 void testHttpClientWithMutualTLS() {
175     // https://www.naschenweng.info/2018/02/01/java-mutual-ssl-authentication-2-way-ssl-authentication/
176     // mutual TLS
177     string url = "https://10.1.223.222:443/";
178     // string url = "https://publicobject.com/helloworld.txt";
179     // string url = "https://www.bing.com/";
180 
181     HttpClient client = new HttpClient();
182     scope (exit) {
183         client.close();
184     }
185 
186     Request request = new RequestBuilder().url(url).caCert("cert/ca.crt", "hunt2019")
187         .mutualTls("cert/client.crt", "cert/client.key", "hunt2019", "hunt2019").build();
188 
189     Response response = client.newCall(request).execute();
190 
191     if (response !is null) {
192         tracef("status code: %d", response.getStatus());
193         trace(response.getBody().asString());
194     }
195 
196     warning("done.");
197 }
198 
199 class HttpClientTest {
200     HttpClient client;
201 
202     this() {
203         client = new HttpClient();
204     }
205 
206     void close() {
207         import hunt.net.NetUtil;
208         NetUtil.eventLoop.stop();
209     }
210 
211     // 
212     void testGet() {
213         string str = runGet("http://10.1.223.222/test.html");
214         // string str = runGet("http://10.1.223.222:8080/index.html");
215         // string str = runGet("http://127.0.0.1:8080/json");
216         // string str = runGet("http://www.putao.com/");
217         warning(str);
218 
219         trace("===============================");
220 
221         // str = runGet("http://10.1.223.222/index.html");
222         // str = runGet("http://www.putao.com/");
223         // trace(str);
224     }
225 
226     //
227     void testGetHttps() {
228 
229         string url = "https://10.1.223.222:440/";
230         // string url = "https://publicobject.com/helloworld.txt";
231         string str = runGet(url);
232 
233         trace(str);
234     }
235 
236     string runGet(string url) {
237 
238         Request request = new RequestBuilder().url(url).build();
239         Response response = client.newCall(request).execute();
240 
241         if (response !is null) {
242             tracef("status code: %d", response.getStatus());
243             return response.getBody().asString();
244         }
245 
246         return "";
247     }
248 
249     //
250     void testAsynchronousGet() {
251 
252         // string url = "https://10.1.223.222:6677/index";
253         string url = "https://publicobject.com/helloworld.txt";
254         Request request = new RequestBuilder().url(url).build();
255 
256         // dfmt off
257             client.newCall(request).enqueue(new class Callback {
258                 void onFailure(Call call, IOException e) {
259                     warning(e.toString());}
260 
261                     void onResponse(Call call, Response response) {
262                         HttpBody responseBody = response.getBody(); if (!response.isSuccessful())
263                             throw new IOException("Unexpected code " ~ response.toString());
264 
265                                 HttpFields responseHeaders = response.headers(); foreach (
266                                     HttpField header; responseHeaders) {
267                                     trace(header.getName() ~ ": " ~ header.getValue());
268                                 }
269 
270                         trace(responseBody.asString());}
271                     }
272             );
273             // dfmt on
274 
275         info("A request has been sent.");
276     }
277 
278     // void testPost() {
279     //     UrlEncoded encoder = new UrlEncoded(UrlEncodeStyle.HtmlForm);
280     //     encoder.put("email", "test@putao.com");
281     //     encoder.put("password", "test");
282     //     // string content = "email=test%40putao.com&password=test";
283     //     string content = encoder.encode();
284     //     string response = post("http://10.1.223.222:8080/testpost",
285     //             "application/x-www-form-urlencoded", content);
286 
287     //     // string content = `{"type":"news", "offset": "0", "count": "20"}`;
288     //     // string url = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=24_1IgJevIE2nBKEylZUX-eV1AEsPoFOu8Q_5_slFPPbw-Zh4wozxl6vS0DfBgbXDWD8nFu0j6_WVUAS5HvxjBLZBNAg4wzr7dplhfI7O0E9nHQtOdDbcTwZ2UzlPjEUhgEiLSiZ-0qiyPu0DOCXBIfAIAPTA";
289 
290     //     // string response = post(url, MimeType.APPLICATION_JSON_UTF_8.toString(), content);
291 
292     //     trace(response);
293     // }
294 
295     void testPost() {
296 
297         import core.time;
298     
299         string[string] postData = [
300         "__VIEWSTATE" : "/wEPDwUKLTEwMDYyNTk0N2RkUSZixNmxd0w9kosXl7Hd+TgdQy0=",
301         "__VIEWSTATEGENERATOR" : "C2EE9ABB1",
302         "login_id" : "18001930082",
303         "password" : "putao@521",
304         "verify_code" : "",
305         "mobile" : "",
306         "verification_code" : "",
307         "deviceId" : "B32V7RRDLESDBIKHC24V3EWK7IEU2N76ETEGUWRAH6JV2NSAG7YS5NEUKUMCAAJA7SQYAMOAKX45DMR7XSRRXMQBIU",
308         "__CALLBACKID" : "ACall",
309         "__CALLBACKPARAM" : `{"Method":"Login","CallControl":"{page}"}`
310         ];
311 
312         UrlEncoded encoder = new UrlEncoded(UrlEncodeStyle.HtmlForm);
313         foreach (string name, string value; postData) {
314             encoder.put(name, value);
315         }
316         string content = encoder.encode();
317 
318         HttpBody b = HttpBody.create("application/x-www-form-urlencoded", content);
319         auto builder = new RequestBuilder()
320             .url("https://www.erp321.com/login.aspx")
321             .post(b);
322         auto request = builder.build();
323         auto options = new HttpClientOptions();
324         auto clientOptions = options.getTcpConfiguration();
325         clientOptions.setConnectTimeout(30.seconds);
326         clientOptions.setIdleTimeout(120.seconds);
327         HttpClient client = new HttpClient(options);
328         Response response = client.newCall(request).execute();
329         HttpBody res = response.getBody();
330         // logError(res);
331         logErrorf("jushuitan response http status code: %d", response.getStatus());
332         logError( res.asString());
333     }    
334 
335     string post(string url, string contentType, string content) {
336         HttpBody b = HttpBody.create(contentType, content);
337 
338         Request request = new RequestBuilder().url(url).post(b).build();
339 
340         Response response = client.newCall(request).execute();
341         HttpBody res = response.getBody();
342         if (res is null)
343             return "";
344         else
345             return res.asString();
346     }
347 
348     // 
349     void testFormPost() {
350         FormBody form = new FormBody.Builder().add("sim", "ple").add("hey",
351                 "there").add("help", "me").build();
352 
353         string response = postForm("http://10.1.11.164:8080/testpost", form);
354         // string response = postForm("http://10.1.223.222:8080/testpost", form);
355         trace(response);
356     }
357 
358     string postForm(string url, HttpBody content) {
359         Request request = new RequestBuilder().url(url).header("Authorization",
360                 "Basic cHV0YW86MjAxOQ==").post(content).build();
361 
362         Response response = client.newCall(request).execute();
363         if (response.haveBody())
364             return response.getBody().asString();
365         return "";
366     }
367 
368 }
369 
370 version (WITH_HUNT_TRACE) {
371     void testOpenTracing() {
372         import hunt.trace.HttpSender;
373 
374         // string endpoint = "http://10.1.11.34:9411/api/v2/spans";
375         string endpoint = "http://10.1.223.222:9411/api/v2/spans";
376         httpSender().endpoint(endpoint);
377 
378         // string url = "http://10.1.223.222/index.html";
379         string url = "http://127.0.0.1:8080/plaintext";
380         HttpClient client = new HttpClient();
381 
382         Request request = new RequestBuilder().url(url).localServiceName("HttpClientDemo").build();
383         Response response = client.newCall(request).execute();
384 
385         if (response !is null) {
386             warningf("status code: %d", response.getStatus());
387             // if(response.haveBody())
388             //  trace(response.getBody().asString());
389         } else {
390             warning("no response");
391         }
392 
393         getchar();
394     }
395 }