/// <summary> /// Calculates a new CompatabilityHash based on the specified networkVersion and /// the list of loaded plugins /// </summary> /// <param name="engine">FrooxEngine reference</param> /// <param name="networkVersion">the current network version from which to base the CompatabilityHash. -1 Means the value is determined automatically</param> /// <param name="loadedPlugins">additionally loaded assemblies, to factor into the CompatabilityHash</param> public static void OverrideHash(Engine engine, int networkVersion = -1, string versionString = null, Dictionary <string, string> loadedPlugins = null) { MD5CryptoServiceProvider csp = new MD5CryptoServiceProvider(); ConcatenatedStream hashStream = new ConcatenatedStream(); if (networkVersion == -1) { networkVersion = GetCurrentVersion(); } hashStream.EnqueueStream(new MemoryStream(BitConverter.GetBytes(networkVersion))); if (loadedPlugins != null) { string PluginsBase = PathUtility.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\Plugins\\"; foreach (string assemblyPath in loadedPlugins.Keys) { try { FileStream fileStream = File.OpenRead(PluginsBase + assemblyPath); fileStream.Seek(375L, SeekOrigin.Current); hashStream.EnqueueStream(fileStream); } catch { UniLog.Log("Failed to load assembly for hashing: " + PluginsBase + assemblyPath); } } } AssemblyName currentAssemblyName = Assembly.GetExecutingAssembly().GetName(); SetHash(Convert.ToBase64String(csp.ComputeHash(hashStream)), versionString ?? (currentAssemblyName.Name + "-" + currentAssemblyName.Version), engine); }
public void CanReadTest() { ConcatenatedStream cStream = new ConcatenatedStream(streamSampleOne, streamSampleTwo, streamSampleThree); int totalLength = sampleStreamSize * 2; List <byte> output = new List <byte>(); while (cStream.CanRead) { output.Add((byte)cStream.ReadByte()); } Assert.IsTrue( output.Take(sampleStreamSize).SequenceEqual(streamSampleOne.ToArray()), "First array does not match"); Assert.IsTrue( output.Skip(sampleStreamSize).Take(sampleStreamSize).SequenceEqual(streamSampleTwo.ToArray()), "Second array does not match"); Assert.IsTrue( output.Skip(sampleStreamSize * 2).Take(sampleStreamSize).SequenceEqual(streamSampleThree.ToArray()), "Third array does not match"); }
private void SendResponse() { var statusCode = response.Status; var responseBody = ProcessRanges(response, ref statusCode); var responseStream = new ConcatenatedStream(); try { var headerBlock = new StringBuilder(); headerBlock.AppendFormat( "HTTP/1.1 {0} {1}\r\n", (uint)statusCode, HttpPhrases.Phrases[statusCode] ); headerBlock.Append(response.Headers.HeaderBlock); headerBlock.Append(CRLF); var headerStream = new MemoryStream( Encoding.ASCII.GetBytes(headerBlock.ToString())); responseStream.AddStream(headerStream); if (Method != "HEAD" && responseBody != null) { responseStream.AddStream(responseBody); responseBody = null; } DebugFormat("{0} - {1} response for {2}", this, (uint)statusCode, Path); state = HttpStates.Writing; var sp = new StreamPump(responseStream, stream, BUFFER_SIZE); sp.Pump((pump, result) => { pump.Input.Close(); pump.Input.Dispose(); if (result == StreamPumpResult.Delivered) { DebugFormat("{0} - Done writing response", this); string conn; if (Headers.TryGetValue("connection", out conn) && conn.ToUpperInvariant() == "KEEP-ALIVE") { ReadNext(); return; } } else { DebugFormat("{0} - Client aborted connection", this); } Close(); }); } catch (Exception) { responseStream.Dispose(); throw; } finally { responseBody?.Dispose(); } }
public void CanCatenateSingleStream() { var buffer = new byte[5]; var one = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 }); var concatenated = new ConcatenatedStream(new Stream[] { one }); concatenated.Read(buffer, 0, 5); Assert.Equal(new byte[] { 1, 2, 3, 4, 5 }, buffer); }
public void Create_Empty() { var stream = new ConcatenatedStream(); Assert.AreEqual(0, stream.Length); Assert.AreEqual(0, stream.Position); stream = new ConcatenatedStream(new List <Stream>()); Assert.AreEqual(0, stream.Length); Assert.AreEqual(0, stream.Position); }
public void CanConcatenateTwoStreams() { byte[] buffer = new byte[10]; var one = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 }); var two = new MemoryStream(new byte[] { 6, 7, 8, 9, 10 }); var concatenated = new ConcatenatedStream(new Stream[] { one, two }); concatenated.Read(buffer, 0, 10); Assert.Equal(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, buffer); }
public void CanConcatenateThreeStreams() { byte[] buffer = new byte[15]; var one = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 }); var two = new MemoryStream(new byte[] { 6, 7, 8, 9, 10 }); var three = new MemoryStream(new byte[] { 11, 12, 13, 14, 15 }); var concatenated = new ConcatenatedStream(new Stream[] { one, two, three }); concatenated.Read(buffer, 0, 15); Assert.Equal(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, buffer); }
public void InitializeTests() { stream1 = Bio.RandomStream(32); stream2 = Bio.RandomStream(16); combinedLength = stream1.Length + stream2.Length; combinedData = new byte[combinedLength]; stream1.Read(combinedData, 0, (int)stream1.Length); stream2.Read(combinedData, (int)stream1.Length, (int)stream2.Length); stream1.MoveToStart(); stream2.MoveToStart(); concatenated = new ConcatenatedStream(stream1, stream2); }
public Stream Encrypt(out byte[] dataKey, Stream plaintextStream, IDictionary <string, string> context) { byte[] plaintextKey; _dataKeyProvider.GenerateKey(_config.KeyBits, out plaintextKey, out dataKey, context); ISymmetricAlgorithm algo = null; try { algo = _algorithmFactory.CreateAlgorithm(_config); algo.Key = plaintextKey; algo.GenerateIV(); // All these hoops with the concatenated streams, StreamWithDisposable, etc. // are to support: using (Stream foo = provider.Encrypt(...)) {...} ICryptoTransform encryptor = algo.CreateEncryptor(); Stream ivStream = new MemoryStream(algo.IV); Stream cryptoStream = new CryptoStream(plaintextStream, encryptor, CryptoStreamMode.Read); Stream streamPair = new ConcatenatedStream(ivStream, cryptoStream); // when this stream is disposed, so will be all of its constituent streams, // plus the algorithm and the encryptor. return(new StreamWithDisposables(streamPair, new IDisposable[] { algo, encryptor })); } catch (Exception e) { // If we had trouble creating the stream, destroy the algorithm to prevent the key leaking. if (algo != null) { try { algo.Dispose(); } catch (Exception disposalException) { throw new AggregateException(e, disposalException); } } throw; } }
public void ReadAllTest() { ConcatenatedStream cStream = new ConcatenatedStream(streamSampleOne, streamSampleTwo, streamSampleThree); int totalLength = sampleStreamSize * 3; byte[] output = new byte[totalLength]; cStream.Read(output, 0, totalLength); Assert.IsTrue( output.Take(sampleStreamSize).SequenceEqual(streamSampleOne.ToArray()), "First array does not match"); Assert.IsTrue( output.Skip(sampleStreamSize).Take(sampleStreamSize).SequenceEqual(streamSampleTwo.ToArray()), "Second array does not match"); Assert.IsTrue( output.Skip(sampleStreamSize * 2).Take(sampleStreamSize).SequenceEqual(streamSampleThree.ToArray()), "Third array does not match"); }
private void SendResponse() { var responseBody = response.Body; var st = response.Status; var contentLength = GetContentLengthFromStream(responseBody); string ar; if (st == HttpCodes.OK && contentLength > 0 && headers.TryGetValue("Range", out ar)) { try { var m = bytes.Match(ar); if (!m.Success) { throw new InvalidDataException("Not parsed!"); } var totalLength = contentLength; var start = 0L; var end = totalLength - 1; if (!long.TryParse(m.Groups[1].Value, out start) || start < 0) { throw new InvalidDataException("Not parsed"); } if (m.Groups.Count != 3 || !long.TryParse(m.Groups[2].Value, out end) || end <= start || end >= totalLength) { end = totalLength - 1; } if (start >= end) { responseBody.Close(); response = Error416.HandleRequest(this); SendResponse(); return; } if (start > 0) { responseBody.Seek(start, SeekOrigin.Current); } contentLength = end - start + 1; response.Headers["Content-Length"] = contentLength.ToString(); response.Headers.Add("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, totalLength)); st = HttpCodes.PARTIAL; } catch (Exception ex) { Warn(String.Format("{0} - Failed to process range request!", this), ex); } } var hb = new StringBuilder(); hb.AppendFormat("HTTP/1.1 {0} {1}\r\n", (uint)st, HttpPhrases.Phrases[st]); hb.Append(response.Headers.HeaderBlock); hb.Append("\r\n"); var rs = new ConcatenatedStream(); try { var headerStream = new MemoryStream(Encoding.ASCII.GetBytes(hb.ToString())); rs.AddStream(headerStream); if (method != "HEAD" && responseBody != null) { rs.AddStream(responseBody); } InfoFormat("{0} - {1} response for {2}", this, (uint)st, path); state = HttpStates.WRITING; new StreamPump(rs, stream, (pump, result) => { pump.Input.Close(); pump.Input.Dispose(); if (result == StreamPumpResult.Delivered) { DebugFormat("{0} - Done writing response", this); string conn; if (headers.TryGetValue("connection", out conn) && conn.ToLower() == "keep-alive") { ReadNext(); return; } } Close(); }, BUFFER_SIZE); } catch (Exception) { rs.Dispose(); throw; } }
/// <inheritdoc/> public HashResult HashZippedBeatmap(string zipPath, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(zipPath)) { throw new ArgumentNullException(nameof(zipPath)); } if (cancellationToken.IsCancellationRequested) { return(HashResult.AsCanceled); } bool missingDiffs = false; string?message = null; if (!File.Exists(zipPath)) { return(new HashResult(null, $"File doesn't exist: '{zipPath}'", new FileNotFoundException($"File doesn't exist: '{zipPath}'"))); } ZipArchive?zip = null; try { try { zip = ZipFile.OpenRead(zipPath); } catch (Exception ex) { return(new HashResult(null, $"Unable to hash beatmap zip '{zipPath}': {ex.Message}", ex)); } ZipArchiveEntry?infoFile = zip.Entries.FirstOrDefault(e => e.FullName.Equals("info.dat", StringComparison.OrdinalIgnoreCase)); if (infoFile == null) { return(new HashResult(null, $"Could not find 'info.dat' file in '{zipPath}'", null)); } JObject?token = null; using (Stream info = infoFile.Open()) using (StreamReader reader = new StreamReader(info)) using (JsonTextReader jsonReader = new JsonTextReader(reader)) { token = JsonSerializer.Deserialize <JObject>(jsonReader); } if (token == null) { return(new HashResult(null, $"Could not read 'info.dat' file in '{zipPath}'", null)); } if (cancellationToken.IsCancellationRequested) { return(HashResult.AsCanceled); } using Stream infoStream = infoFile.Open(); string[] beatmapFiles = Utilities.GetDifficultyFileNames(token).ToArray(); using ConcatenatedStream streams = new ConcatenatedStream(beatmapFiles.Length + 1); streams.Append(infoStream); for (int i = 0; i < beatmapFiles.Length; i++) { if (cancellationToken.IsCancellationRequested) { return(HashResult.AsCanceled); } ZipArchiveEntry?diff = zip.Entries.FirstOrDefault(e => e.FullName.Equals(beatmapFiles[i], StringComparison.OrdinalIgnoreCase)); if (diff == null) { if (missingDiffs == false) { message = $"Could not find difficulty file '{beatmapFiles[i]}' in '{zipPath}'"; } else { message = $"Missing multiple difficulty files in '{zipPath}'"; } missingDiffs = true; continue; } streams.Append(diff.Open()); } if (cancellationToken.IsCancellationRequested) { return(HashResult.AsCanceled); } string?hash = null; if (streams.StreamCount > 0) { hash = Utilities.CreateSha1FromStream(streams); } return(new HashResult(hash, message, null)); } catch (Exception ex) { return(new HashResult(null, $"Error hashing '{zipPath}'", ex)); } finally { zip?.Dispose(); } }