First pass implementation

This commit is contained in:
DavidMaltby 2019-02-04 16:22:45 -06:00
parent 9e4719859c
commit 796d7b60f9
4 changed files with 76 additions and 19 deletions

View File

@ -1,6 +1,4 @@
using System; using System;
using System.Diagnostics;
using Xamarin.Forms;
using Xamarin.Forms.Internals; using Xamarin.Forms.Internals;
using Ooui.Forms; using Ooui.Forms;
using System.IO; using System.IO;
@ -8,6 +6,7 @@ using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ooui; using Ooui;
using System.Net.Http;
namespace Xamarin.Forms namespace Xamarin.Forms
{ {
@ -37,6 +36,9 @@ namespace Xamarin.Forms
public static event EventHandler<ViewInitializedEventArgs> ViewInitialized; public static event EventHandler<ViewInitializedEventArgs> ViewInitialized;
public static HttpClientHandler HttpClientHandler { get; set; }
public static void SendViewInitialized (this VisualElement self, Ooui.Element nativeView) public static void SendViewInitialized (this VisualElement self, Ooui.Element nativeView)
{ {
ViewInitialized?.Invoke (self, new ViewInitializedEventArgs { View = self, NativeView = nativeView }); ViewInitialized?.Invoke (self, new ViewInitializedEventArgs { View = self, NativeView = nativeView });
@ -69,7 +71,7 @@ namespace Xamarin.Forms
public string GetMD5Hash (string input) public string GetMD5Hash (string input)
{ {
throw new NotImplementedException (); return Utilities.GetMd5Hash(input);
} }
public double GetNamedSize (NamedSize size, Type targetElementType, bool useOldSizes) public double GetNamedSize (NamedSize size, Type targetElementType, bool useOldSizes)
@ -89,9 +91,30 @@ namespace Xamarin.Forms
} }
} }
public Task<Stream> GetStreamAsync (Uri uri, CancellationToken cancellationToken)
public async Task<Stream> GetStreamAsync (Uri uri, CancellationToken cancellationToken)
{ {
throw new NotImplementedException (); //NOTE: Wanted to use the same facility that ImageLoaderSourceHandler uses,
// but couldn't find an optional way to ignore certificate errors with self-signed
// certificates with that approach. Calling:
// ServicePointManager.ServerCertificateValidationCallback += (o, cert, chain, errors) => true;
// in web application seemed to get ignored.
//var imageSource = new UriImageSource() { Uri = uri };
//return imageSource.GetStreamAsync(cancellationToken);
using (var client = HttpClientHandler == null ? new HttpClient() : new HttpClient(HttpClientHandler))
{
HttpResponseMessage streamResponse = await client.GetAsync(uri.AbsoluteUri).ConfigureAwait(false);
if (!streamResponse.IsSuccessStatusCode)
{
Log.Warning("HTTP Request", $"Could not retrieve {uri}, status code {streamResponse.StatusCode}");
return null;
}
return await streamResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
}
} }
public IIsolatedStorageFile GetUserStoreForApplication () public IIsolatedStorageFile GetUserStoreForApplication ()

View File

@ -213,7 +213,7 @@ namespace Ooui.Forms.Renderers
using (var outputStream = new System.IO.MemoryStream (data)) { using (var outputStream = new System.IO.MemoryStream (data)) {
await streamImage.CopyToAsync (outputStream, 4096, cancelationToken).ConfigureAwait (false); await streamImage.CopyToAsync (outputStream, 4096, cancelationToken).ConfigureAwait (false);
} }
var hash = Ooui.Utilities.Hash (data); var hash = Ooui.Utilities.GetShaHash (data);
var etag = "\"" + hash + "\""; var etag = "\"" + hash + "\"";
image = "/images/" + hash; image = "/images/" + hash;
if (Ooui.UI.TryGetFileContentAtPath (image, out var file) && file.Etag == etag) { if (Ooui.UI.TryGetFileContentAtPath (image, out var file) && file.Etag == etag) {

View File

@ -85,7 +85,7 @@ namespace Ooui
clientJsBytes = Encoding.UTF8.GetBytes (r.ReadToEnd ()); clientJsBytes = Encoding.UTF8.GetBytes (r.ReadToEnd ());
} }
} }
clientJsEtag = "\"" + Utilities.Hash (clientJsBytes) + "\""; clientJsEtag = "\"" + Utilities.GetShaHash (clientJsBytes) + "\"";
} }
static void Publish (string path, RequestHandler handler) static void Publish (string path, RequestHandler handler)
@ -117,13 +117,13 @@ namespace Ooui
if (contentType == null) { if (contentType == null) {
contentType = GuessContentType (path, filePath); contentType = GuessContentType (path, filePath);
} }
var etag = "\"" + Utilities.Hash (data) + "\""; var etag = "\"" + Utilities.GetShaHash (data) + "\"";
Publish (path, new DataHandler (data, etag, contentType)); Publish (path, new DataHandler (data, etag, contentType));
} }
public static void PublishFile (string path, byte[] data, string contentType) public static void PublishFile (string path, byte[] data, string contentType)
{ {
var etag = "\"" + Utilities.Hash (data) + "\""; var etag = "\"" + Utilities.GetShaHash (data) + "\"";
Publish (path, new DataHandler (data, etag, contentType)); Publish (path, new DataHandler (data, etag, contentType));
} }
@ -168,7 +168,7 @@ namespace Ooui
public static void PublishJson (string path, object value) public static void PublishJson (string path, object value)
{ {
var data = JsonHandler.GetData (value); var data = JsonHandler.GetData (value);
var etag = "\"" + Utilities.Hash (data) + "\""; var etag = "\"" + Utilities.GetShaHash (data) + "\"";
Publish (path, new DataHandler (data, etag, JsonHandler.ContentType)); Publish (path, new DataHandler (data, etag, JsonHandler.ContentType));
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Security.Cryptography;
using System.Text; using System.Text;
namespace Ooui namespace Ooui
@ -6,21 +7,54 @@ namespace Ooui
public static class Utilities public static class Utilities
{ {
[ThreadStatic] [ThreadStatic]
static System.Security.Cryptography.SHA256 sha256; static SHA256 sha256;
public static string Hash (byte[] bytes) [ThreadStatic]
static MD5 md5;
public static string GetShaHash(byte[] bytes)
{ {
var sha = sha256; var sha = sha256;
if (sha == null) { if (sha == null)
sha = System.Security.Cryptography.SHA256.Create (); {
sha = SHA256.Create();
sha256 = sha; sha256 = sha;
} }
var data = sha.ComputeHash (bytes); var data = sha.ComputeHash(bytes);
StringBuilder sBuilder = new StringBuilder ();
for (int i = 0; i < data.Length; i++) { return BytesToString(data);
sBuilder.Append (data[i].ToString ("x2"));
} }
return sBuilder.ToString ();
public static string GetMd5Hash(string input)
{
var md = md5;
if (md == null)
{
md = MD5.Create();
md5 = md;
}
// Convert the input string to a byte array and compute the hash.
byte[] data = md.ComputeHash(Encoding.UTF8.GetBytes(input));
return BytesToString(data);
}
private static string BytesToString(byte[] data)
{
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
} }
} }
} }