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 }