5using System.Runtime.InteropServices;
7using System.Net.NetworkInformation;
14using Uri = System.Uri;
34 byte[] buffer =
new byte[8192];
42 await targetStream.WriteAsync(buffer.AsMemory(0, read),
m_progress.CancellationToken);
44 m_progress.Completed = written;
49 [DllImport(
"wininet.dll")]
50 internal static extern bool InternetGetConnectedState(out
int Description,
int ReservedValue);
52#pragma warning disable CA1416
53#pragma warning disable CA1422
54 internal static ConnectivityManager m_connectivityManager {
get; } = GetConnectivityManager();
59 switch (Build.VERSION.SdkInt) {
60 case >= (BuildVersionCodes)29:
61 return m_connectivityManager?.GetNetworkCapabilities(m_connectivityManager.ActiveNetwork)
62 ?.HasCapability(NetCapability.Validated)
64 case >= (BuildVersionCodes)21:
return m_connectivityManager?.ActiveNetworkInfo?.IsConnected ??
false;
68 return InternetGetConnectedState(out
int _, 0);
70 return NetworkInterface.GetIsNetworkAvailable();
82 static ConnectivityManager GetConnectivityManager() => Build.VERSION.SdkInt >= (BuildVersionCodes)21
83 ? (ConnectivityManager)
Window.Activity.GetSystemService(
"connectivity")
85#pragma warning restore CA1416
86#pragma warning restore CA1422
89 public static void Get(
string address,
90 Dictionary<string, string> parameters,
91 Dictionary<string, string> headers,
93 Action<
byte[]> success,
94 Action<Exception> failure) {
95 MemoryStream targetStream;
99 Uri requestUri = parameters !=
null && parameters.Count > 0
100 ?
new Uri($
"{address}?{UrlParametersToString(parameters)}")
105 throw new InvalidOperationException(
"Internet connection is unavailable.");
107 using (HttpClient client =
new()) {
108 client.DefaultRequestHeaders.Referrer =
new Uri(address);
109 if (headers !=
null) {
110 foreach (KeyValuePair<string, string> header
in headers) {
111 client.DefaultRequestHeaders.Add(header.Key, header.Value);
114 HttpResponseMessage responseMessage = await client.GetAsync(
116 HttpCompletionOption.ResponseHeadersRead,
120 progress.Total = responseMessage.Content.Headers.ContentLength ?? 0;
121 await
using Stream responseStream = await responseMessage.Content.ReadAsStreamAsync();
122 targetStream =
new MemoryStream();
125 byte[] buffer =
new byte[8192];
131 await targetStream.WriteAsync(buffer.AsMemory(0, read), progress.
CancellationToken);
133 progress.Completed = written;
135 if (success !=
null) {
139 success(targetStream?.ToArray());
146 ((IDisposable)targetStream)?.Dispose();
150 catch (Exception ex) {
151 Log.
Warning($
"{e.Message}:\nThe connection is unavailable. Url: {requestUri}");
152 if (failure !=
null) {
160 public static void Put(
string address,
161 Dictionary<string, string> parameters,
162 Dictionary<string, string> headers,
165 Action<
byte[]> success,
166 Action<Exception> failure) {
179 public static void Post(
string address,
180 Dictionary<string, string> parameters,
181 Dictionary<string, string> headers,
184 Action<
byte[]> success,
185 Action<Exception> failure) {
198 public static async Task<byte[]>
GetAsync(
string address,
199 Dictionary<string, string> parameters =
null,
200 Dictionary<string, string> headers =
null,
203 Uri requestUri = parameters !=
null && parameters.Count > 0
204 ?
new Uri($
"{address}?{UrlParametersToString(parameters)}")
207 throw new InvalidOperationException(
"Internet connection is unavailable.");
209 using HttpClient client =
new();
210 client.DefaultRequestHeaders.Referrer =
new Uri(address);
211 if (headers !=
null) {
212 foreach (KeyValuePair<string, string> header
in headers) {
213 client.DefaultRequestHeaders.Add(header.Key, header.Value);
216 using HttpResponseMessage responseMessage = await client.GetAsync(
218 HttpCompletionOption.ResponseHeadersRead,
219 progress.CancellationToken
222 progress.Total = responseMessage.Content.Headers.ContentLength ?? 0;
223 await
using Stream responseStream = await responseMessage.Content.ReadAsStreamAsync();
224 using MemoryStream targetStream =
new();
226 byte[] buffer =
new byte[8192];
228 int read = await responseStream.ReadAsync(buffer.AsMemory(0, buffer.Length), progress.CancellationToken);
232 await targetStream.WriteAsync(buffer.AsMemory(0, read), progress.CancellationToken);
234 progress.Completed = written;
236 return targetStream.ToArray();
239 public static async Task<byte[]>
PutAsync(
string address,
240 Dictionary<string, string> parameters,
241 Dictionary<string, string> headers,
254 public static async Task<byte[]>
PostAsync(
string address,
255 Dictionary<string, string> parameters,
256 Dictionary<string, string> headers,
270 StringBuilder stringBuilder =
new();
271 string value =
string.Empty;
272 foreach (KeyValuePair<string, string> value2
in values) {
273 stringBuilder.Append(value);
275 stringBuilder.Append(
Uri.EscapeDataString(value2.Key));
276 stringBuilder.Append(
'=');
277 if (!
string.IsNullOrEmpty(value2.Value)) {
278 stringBuilder.Append(
Uri.EscapeDataString(value2.Value));
281 return stringBuilder.ToString();
290 Dictionary<string, string> dictionary =
new();
291 string[] array = s.Split(
'&', StringSplitOptions.RemoveEmptyEntries);
292 for (
int i = 0; i < array.Length; i++) {
293 string[] array2 =
Uri.UnescapeDataString(array[i]).Split(
'=');
294 if (array2.Length == 2) {
295 dictionary[array2[0]] = array2[1];
306 Dictionary<string, string> parameters,
307 Dictionary<string, string> headers,
310 Action<
byte[]> success,
311 Action<Exception> failure) {
314 Uri requestUri = parameters !=
null && parameters.Count > 0
315 ?
new Uri($
"{address}?{UrlParametersToString(parameters)}")
319 throw new InvalidOperationException(
"Internet connection is unavailable.");
321 using HttpClient client =
new();
322 Dictionary<string, string> dictionary =
new();
323 if (headers !=
null) {
324 foreach (KeyValuePair<string, string> header
in headers) {
325 if (!client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value)) {
326 dictionary.Add(header.Key, header.Value);
333 HttpContent httpContent = progress !=
null ?
new ProgressHttpContent(data, progress) :
new StreamContent(data);
335 foreach (KeyValuePair<string, string> item
in dictionary) {
336 httpContent.Headers.Add(item.Key, item.Value);
339 HttpResponseMessage responseMessage = isPost
343 HttpResponseMessage responseMessage = isPost ?
345 ? await client.PostAsync(requestUri, httpContent)
346 : await client.PostAsync(requestUri, httpContent, progress.CancellationToken) :
347 progress ==
null ? await client.PutAsync(requestUri, httpContent) :
348 await client.PutAsync(requestUri, httpContent, progress.CancellationToken);
351 byte[] responseData = await responseMessage.Content.ReadAsByteArrayAsync();
352 if (success !=
null) {
356 catch (Exception e) {
357 Log.
Warning($
"{e.Message}:\nThe connection is unavailable. Url: {requestUri}");
358 if (failure !=
null) {
368 Dictionary<string, string> parameters,
369 Dictionary<string, string> headers,
372 Uri requestUri = parameters !=
null && parameters.Count > 0
373 ?
new Uri($
"{address}?{UrlParametersToString(parameters)}")
376 throw new InvalidOperationException(
"Internet connection is unavailable.");
378 using HttpClient client =
new();
379 Dictionary<string, string> dictionary =
new();
380 if (headers !=
null) {
381 foreach (KeyValuePair<string, string> header
in headers) {
382 if (!client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value)) {
383 dictionary.Add(header.Key, header.Value);
390 HttpContent httpContent = progress !=
null ?
new ProgressHttpContent(data, progress) :
new StreamContent(data);
392 foreach (KeyValuePair<string, string> item
in dictionary) {
393 httpContent.Headers.Add(item.Key, item.Value);
396 HttpResponseMessage responseMessage = isPost
397 ? await client.PostAsync(requestUri, httpContent, progress.CancellationToken)
398 : await client.PutAsync(requestUri, httpContent, progress.CancellationToken);
400 HttpResponseMessage responseMessage = isPost ?
402 ? await client.PostAsync(requestUri, httpContent)
403 : await client.PostAsync(requestUri, httpContent, progress.CancellationToken) :
404 progress ==
null ? await client.PutAsync(requestUri, httpContent) :
405 await client.PutAsync(requestUri, httpContent, progress.CancellationToken);
408 byte[] responseData = await responseMessage.Content.ReadAsByteArrayAsync();
413 if (!message.IsSuccessStatusCode) {
414 string responseText =
string.Empty;
416 responseText = await message.Content.ReadAsStringAsync();
421 throw new InvalidOperationException($
"{message.StatusCode} ({(int)message.StatusCode})\n{responseText}");
System.OperationCanceledException OperationCanceledException
static void Dispatch(Action action, bool waitUntilCompleted=false)
static void Warning(object message)
readonly CancellationToken CancellationToken
static string MakeFullErrorMessage(Exception e)
override bool TryComputeLength(out long length)
override async Task SerializeToStreamAsync(Stream targetStream, TransportContext context)
CancellableProgress m_progress
ProgressHttpContent(Stream sourceStream, CancellableProgress progress)
static void Post(string address, Dictionary< string, string > parameters, Dictionary< string, string > headers, Stream data, CancellableProgress progress, Action< byte[]> success, Action< Exception > failure)
static async Task VerifyResponse(HttpResponseMessage message)
static async Task< byte[]> PostAsync(string address, Dictionary< string, string > parameters, Dictionary< string, string > headers, Stream data, CancellableProgress progress=null)
static bool IsInternetConnectionAvailable()
static byte[] UrlParametersToBytes(Dictionary< string, string > values)
static void Put(string address, Dictionary< string, string > parameters, Dictionary< string, string > headers, Stream data, CancellableProgress progress, Action< byte[]> success, Action< Exception > failure)
static void PutOrPost(bool isPost, string address, Dictionary< string, string > parameters, Dictionary< string, string > headers, Stream data, CancellableProgress progress, Action< byte[]> success, Action< Exception > failure)
static Dictionary< string, string > UrlParametersFromBytes(byte[] bytes)
static MemoryStream UrlParametersToStream(Dictionary< string, string > values)
static void Get(string address, Dictionary< string, string > parameters, Dictionary< string, string > headers, CancellableProgress progress, Action< byte[]> success, Action< Exception > failure)
static async Task< byte[]> GetAsync(string address, Dictionary< string, string > parameters=null, Dictionary< string, string > headers=null, CancellableProgress progress=null)
static Dictionary< string, string > UrlParametersFromString(string s)
static async Task< byte[]> PutAsync(string address, Dictionary< string, string > parameters, Dictionary< string, string > headers, Stream data, CancellableProgress progress=null)
static async Task< byte[]> PutOrPostAAsync(bool isPost, string address, Dictionary< string, string > parameters, Dictionary< string, string > headers, Stream data, CancellableProgress progress)
static string UrlParametersToString(Dictionary< string, string > values)