1 /** 2 * ae.sys.net implementation using ae.net 3 * Note: ae.net requires an SSL provider for HTTPS links. 4 * 5 * License: 6 * This Source Code Form is subject to the terms of 7 * the Mozilla Public License, v. 2.0. If a copy of 8 * the MPL was not distributed with this file, You 9 * can obtain one at http://mozilla.org/MPL/2.0/. 10 * 11 * Authors: 12 * Vladimir Panteleev <ae@cy.md> 13 */ 14 15 module ae.sys.net.ae; 16 17 import ae.net.asockets; 18 import ae.net.http.client; 19 import ae.net.ietf.url; 20 import ae.sys.dataset : DataVec; 21 import ae.sys.net; 22 23 static import std.file; 24 25 /// `Network` implementation based on `ae.net`. 26 class AENetwork : Network 27 { 28 private Data getData(string url) 29 { 30 Data result; 31 bool got; 32 33 httpGet(url, 34 (Data data) { result = data; got = true; }, 35 (string error) { throw new Exception(error); } 36 ); 37 38 socketManager.loop(); 39 assert(got); 40 return result; 41 } 42 43 override void downloadFile(string url, string target) 44 { 45 Data data = getData(url); 46 data.enter((contents) { 47 std.file.write(target, contents); 48 }); 49 } /// 50 51 override ubyte[] getFile(string url) 52 { 53 return getData(url).toGC(); 54 } /// 55 56 override ubyte[] post(string url, const(ubyte)[] data) 57 { 58 Data result; 59 bool got; 60 61 httpPost(url, DataVec(Data(data)), null, 62 (Data data) { result = data; got = true; }, 63 (string error) { throw new Exception(error); } 64 ); 65 66 socketManager.loop(); 67 assert(got); 68 return result.toGC(); 69 } /// 70 71 override bool urlOK(string url) 72 { 73 bool got, result; 74 75 auto request = new HttpRequest; 76 request.method = "HEAD"; 77 request.resource = url; 78 try 79 { 80 .httpRequest(request, 81 (HttpResponse response, string disconnectReason) 82 { 83 got = true; 84 if (!response) 85 result = false; 86 else 87 result = response.status == HttpStatusCode.OK; 88 } /// 89 ); 90 91 socketManager.loop(); 92 } /// 93 catch (Exception e) 94 return false; 95 96 assert(got); 97 return result; 98 } /// 99 100 override string resolveRedirect(string url) 101 { 102 string result; bool got; 103 104 auto request = new HttpRequest; 105 request.method = "HEAD"; 106 request.resource = url; 107 .httpRequest(request, 108 (HttpResponse response, string disconnectReason) 109 { 110 if (!response) 111 throw new Exception(disconnectReason); 112 else 113 { 114 got = true; 115 result = response.headers.get("Location", null); 116 if (result) 117 result = url.applyRelativeURL(result); 118 } /// 119 } /// 120 ); 121 122 socketManager.loop(); 123 assert(got); 124 return result; 125 } /// 126 127 override HttpResponse httpRequest(HttpRequest request) 128 { 129 HttpResponse result; 130 131 .httpRequest(request, 132 (HttpResponse response, string disconnectReason) 133 { 134 if (!response) 135 throw new Exception(disconnectReason); 136 else 137 result = response; 138 } /// 139 ); 140 141 socketManager.loop(); 142 assert(result); 143 return result; 144 } /// 145 } 146 147 static this() 148 { 149 net = new AENetwork(); 150 }