From 08f4a6fa0b9166f5c70715ffe9dab6ac4daf1a02 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 30 Nov 2017 16:54:50 -0500 Subject: fix log parser error when uploading very large logs --- docs/release-notes.md | 1 + .../Framework/LogParser/PastebinClient.cs | 41 +++++++++++++++------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 833f96b4..683e97b8 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -9,6 +9,7 @@ * Updated compatibility list. * The [log parser][] no longer expires logs after a week. * The [log parser][] now lets you close modals with `ESC` or a click outside it. + * Fixed [log parser][] error when uploading very large logs. * For modders: * Added `DaysSinceStart` property to `SDate` dates. diff --git a/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs b/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs index 60441234..1cfaed17 100644 --- a/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs +++ b/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; +using System.Text; using System.Threading.Tasks; +using System.Web; using Pathoschild.Http.Client; namespace StardewModdingAPI.Web.Framework.LogParser @@ -67,6 +69,8 @@ namespace StardewModdingAPI.Web.Framework.LogParser } } + /// Save a paste to Pastebin. + /// The paste content. public async Task PostAsync(string content) { try @@ -77,18 +81,18 @@ namespace StardewModdingAPI.Web.Framework.LogParser // post to API string response = await this.Client - .PostAsync("api/api_post.php") - .WithBodyContent(new FormUrlEncodedContent(new Dictionary - { - ["api_option"] = "paste", - ["api_user_key"] = this.UserKey, - ["api_dev_key"] = this.DevKey, - ["api_paste_private"] = "1", // unlisted - ["api_paste_name"] = $"SMAPI log {DateTime.UtcNow:s}", - ["api_paste_expire_date"] = "N", // never expire - ["api_paste_code"] = content - })) - .AsString(); + .PostAsync("api/api_post.php") + .WithBodyContent(this.GetFormUrlEncodedContent(new Dictionary + { + ["api_option"] = "paste", + ["api_user_key"] = this.UserKey, + ["api_dev_key"] = this.DevKey, + ["api_paste_private"] = "1", // unlisted + ["api_paste_name"] = $"SMAPI log {DateTime.UtcNow:s}", + ["api_paste_expire_date"] = "N", // never expire + ["api_paste_code"] = content + })) + .AsString(); // handle Pastebin errors if (string.IsNullOrWhiteSpace(response)) @@ -113,5 +117,18 @@ namespace StardewModdingAPI.Web.Framework.LogParser { this.Client.Dispose(); } + + + /********* + ** Private methods + *********/ + /// Build an HTTP content body with form-url-encoded content. + /// The content to encode. + /// This bypasses an issue where restricts the body length to the maximum size of a URL, which isn't applicable here. + private HttpContent GetFormUrlEncodedContent(IDictionary data) + { + string body = string.Join("&", from arg in data select $"{HttpUtility.UrlEncode(arg.Key)}={HttpUtility.UrlEncode(arg.Value)}"); + return new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded"); + } } } -- cgit