diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-08-04 16:37:10 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-09-14 19:00:36 -0400 |
commit | c86db64880d52630c372aa24f7aadf0036fb3fcf (patch) | |
tree | a102db0cf57f1ce12ef24ddf8f8d7ee8590bc94a /src/SMAPI.Web/Controllers | |
parent | 8e0ddd1d00e3d0d11fbaa0ffce804b3e7186c254 (diff) | |
download | SMAPI-c86db64880d52630c372aa24f7aadf0036fb3fcf.tar.gz SMAPI-c86db64880d52630c372aa24f7aadf0036fb3fcf.tar.bz2 SMAPI-c86db64880d52630c372aa24f7aadf0036fb3fcf.zip |
encapsulate gzip logic for reuse (#654)
Diffstat (limited to 'src/SMAPI.Web/Controllers')
-rw-r--r-- | src/SMAPI.Web/Controllers/LogParserController.cs | 82 |
1 files changed, 8 insertions, 74 deletions
diff --git a/src/SMAPI.Web/Controllers/LogParserController.cs b/src/SMAPI.Web/Controllers/LogParserController.cs index 21e4a56f..dc5895b0 100644 --- a/src/SMAPI.Web/Controllers/LogParserController.cs +++ b/src/SMAPI.Web/Controllers/LogParserController.cs @@ -1,13 +1,11 @@ using System; -using System.IO; -using System.IO.Compression; using System.Linq; -using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using StardewModdingAPI.Web.Framework; using StardewModdingAPI.Web.Framework.Clients.Pastebin; +using StardewModdingAPI.Web.Framework.Compression; using StardewModdingAPI.Web.Framework.ConfigModels; using StardewModdingAPI.Web.Framework.LogParsing; using StardewModdingAPI.Web.Framework.LogParsing.Models; @@ -27,9 +25,8 @@ namespace StardewModdingAPI.Web.Controllers /// <summary>The underlying Pastebin client.</summary> private readonly IPastebinClient Pastebin; - /// <summary>The first bytes in a valid zip file.</summary> - /// <remarks>See <a href="https://en.wikipedia.org/wiki/Zip_(file_format)#File_headers"/>.</remarks> - private const uint GzipLeadBytes = 0x8b1f; + /// <summary>The underlying text compression helper.</summary> + private readonly IGzipHelper GzipHelper; /********* @@ -41,10 +38,12 @@ namespace StardewModdingAPI.Web.Controllers /// <summary>Construct an instance.</summary> /// <param name="siteConfig">The context config settings.</param> /// <param name="pastebin">The Pastebin API client.</param> - public LogParserController(IOptions<SiteConfig> siteConfig, IPastebinClient pastebin) + /// <param name="gzipHelper">The underlying text compression helper.</param> + public LogParserController(IOptions<SiteConfig> siteConfig, IPastebinClient pastebin, IGzipHelper gzipHelper) { this.Config = siteConfig.Value; this.Pastebin = pastebin; + this.GzipHelper = gzipHelper; } /*** @@ -84,7 +83,7 @@ namespace StardewModdingAPI.Web.Controllers return this.View("Index", new LogParserModel(this.Config.LogParserUrl, null) { UploadError = "The log file seems to be empty." }); // upload log - input = this.CompressString(input); + input = this.GzipHelper.CompressString(input); SavePasteResult result = await this.Pastebin.PostAsync(input); // handle errors @@ -106,75 +105,10 @@ namespace StardewModdingAPI.Web.Controllers private async Task<PasteInfo> GetAsync(string id) { PasteInfo response = await this.Pastebin.GetAsync(id); - response.Content = this.DecompressString(response.Content); + response.Content = this.GzipHelper.DecompressString(response.Content); return response; } - /// <summary>Compress a string.</summary> - /// <param name="text">The text to compress.</param> - /// <remarks>Derived from <a href="https://stackoverflow.com/a/17993002/262123"/>.</remarks> - private string CompressString(string text) - { - // get raw bytes - byte[] buffer = Encoding.UTF8.GetBytes(text); - - // compressed - byte[] compressedData; - using (MemoryStream stream = new MemoryStream()) - { - using (GZipStream zipStream = new GZipStream(stream, CompressionLevel.Optimal, leaveOpen: true)) - zipStream.Write(buffer, 0, buffer.Length); - - stream.Position = 0; - compressedData = new byte[stream.Length]; - stream.Read(compressedData, 0, compressedData.Length); - } - - // prefix length - byte[] zipBuffer = new byte[compressedData.Length + 4]; - Buffer.BlockCopy(compressedData, 0, zipBuffer, 4, compressedData.Length); - Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, zipBuffer, 0, 4); - - // return string representation - return Convert.ToBase64String(zipBuffer); - } - /// <summary>Decompress a string.</summary> - /// <param name="rawText">The compressed text.</param> - /// <remarks>Derived from <a href="https://stackoverflow.com/a/17993002/262123"/>.</remarks> - private string DecompressString(string rawText) - { - // get raw bytes - byte[] zipBuffer; - try - { - zipBuffer = Convert.FromBase64String(rawText); - } - catch - { - return rawText; // not valid base64, wasn't compressed by the log parser - } - - // skip if not gzip - if (BitConverter.ToUInt16(zipBuffer, 4) != LogParserController.GzipLeadBytes) - return rawText; - - // decompress - using (MemoryStream memoryStream = new MemoryStream()) - { - // read length prefix - int dataLength = BitConverter.ToInt32(zipBuffer, 0); - memoryStream.Write(zipBuffer, 4, zipBuffer.Length - 4); - - // read data - byte[] buffer = new byte[dataLength]; - memoryStream.Position = 0; - using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) - gZipStream.Read(buffer, 0, buffer.Length); - - // return original string - return Encoding.UTF8.GetString(buffer); - } - } } } |