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 <vladimir@thecybershadow.net>
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.net;
21 
22 static import std.file;
23 
24 class AENetwork : Network
25 {
26 	private Data getData(string url)
27 	{
28 		Data result;
29 		bool got;
30 
31 		httpGet(url,
32 			(Data data) { result = data; got = true; },
33 			(string error) { throw new Exception(error); }
34 		);
35 
36 		socketManager.loop();
37 		assert(got);
38 		return result;
39 	}
40 
41 	override void downloadFile(string url, string target)
42 	{
43 		Data data = getData(url);
44 		std.file.write(target, data.contents);
45 	}
46 
47 	override void[] getFile(string url)
48 	{
49 		return getData(url).toHeap;
50 	}
51 
52 	override void[] post(string url, in void[] data)
53 	{
54 		Data result;
55 		bool got;
56 
57 		httpPost(url, [Data(data)], null,
58 			(Data data) { result = data; got = true; },
59 			(string error) { throw new Exception(error); }
60 		);
61 
62 		socketManager.loop();
63 		assert(got);
64 		return result.toHeap;
65 	}
66 
67 	override bool urlOK(string url)
68 	{
69 		bool got, result;
70 
71 		auto request = new HttpRequest;
72 		request.method = "HEAD";
73 		request.resource = url;
74 		try
75 		{
76 			.httpRequest(request,
77 				(HttpResponse response, string disconnectReason)
78 				{
79 					got = true;
80 					if (!response)
81 						result = false;
82 					else
83 						result = response.status == HttpStatusCode.OK;
84 				}
85 			);
86 
87 			socketManager.loop();
88 		}
89 		catch (Exception e)
90 			return false;
91 
92 		assert(got);
93 		return result;
94 	}
95 
96 	override string resolveRedirect(string url)
97 	{
98 		string result; bool got;
99 
100 		auto request = new HttpRequest;
101 		request.method = "HEAD";
102 		request.resource = url;
103 		.httpRequest(request,
104 			(HttpResponse response, string disconnectReason)
105 			{
106 				if (!response)
107 					throw new Exception(disconnectReason);
108 				else
109 				{
110 					got = true;
111 					result = response.headers.get("Location", null);
112 					if (result)
113 						result = url.applyRelativeURL(result);
114 				}
115 			}
116 		);
117 
118 		socketManager.loop();
119 		assert(got);
120 		return result;
121 	}
122 
123 	override HttpResponse httpRequest(HttpRequest request)
124 	{
125 		HttpResponse result;
126 
127 		.httpRequest(request,
128 			(HttpResponse response, string disconnectReason)
129 			{
130 				if (!response)
131 					throw new Exception(disconnectReason);
132 				else
133 					result = response;
134 			}
135 		);
136 
137 		socketManager.loop();
138 		assert(result);
139 		return result;
140 	}
141 }
142 
143 static this()
144 {
145 	net = new AENetwork();
146 }