From 6bcc23bea1c5eabcbc383196887d6406fb5c7105 Mon Sep 17 00:00:00 2001 From: Kimura Youichi <kim.upsilon@bucyou.net> Date: Tue, 12 Dec 2023 01:24:24 +0900 Subject: [PATCH 1/7] =?UTF-8?q?IApiConnectionLegacy.PostJsonAsync=E3=82=92?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=81=97=E3=81=A6=E3=81=84=E3=82=8B=E7=AE=87?= =?UTF-8?q?=E6=89=80=E3=82=92PostJsonRequest=E3=81=AB=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Api/TwitterApiTest.cs | 27 ++++++++++++++++--------- OpenTween/Api/TwitterApi.cs | 29 ++++++++++++++++++--------- OpenTween/Connection/ApiResponse.cs | 9 +++++++++ 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/OpenTween.Tests/Api/TwitterApiTest.cs b/OpenTween.Tests/Api/TwitterApiTest.cs index 1fde2e592..87df7119d 100644 --- a/OpenTween.Tests/Api/TwitterApiTest.cs +++ b/OpenTween.Tests/Api/TwitterApiTest.cs @@ -23,6 +23,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Net.Http; using System.Reflection; using System.Runtime.InteropServices; @@ -674,8 +675,9 @@ public async Task DirectMessagesEventsList_Test() [Fact] public async Task DirectMessagesEventsNew_Test() { + using var responseMessage = new HttpResponseMessage(HttpStatusCode.OK); var mock = new Mock<IApiConnectionLegacy>(); - var responseText = """ + var requestJson = """ { "event": { "type": "message_create", @@ -697,11 +699,14 @@ public async Task DirectMessagesEventsNew_Test() } """; mock.Setup(x => - x.PostJsonAsync<TwitterMessageEventSingle>( - new Uri("direct_messages/events/new.json", UriKind.Relative), - responseText) + x.SendAsync( + It.Is<PostJsonRequest>(r => + r.RequestUri == new Uri("direct_messages/events/new.json", UriKind.Relative) && + r.JsonString == requestJson + ) + ) ) - .ReturnsAsync(LazyJson.Create(new TwitterMessageEventSingle())); + .ReturnsAsync(new ApiResponse(responseMessage)); using var twitterApi = new TwitterApi(); twitterApi.ApiConnection = mock.Object; @@ -1304,11 +1309,13 @@ public async Task MediaMetadataCreate_Test() { var mock = new Mock<IApiConnectionLegacy>(); mock.Setup(x => - x.PostJsonAsync( - new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute), - """{"media_id": "12345", "alt_text": {"text": "hogehoge"}}""") - ) - .ReturnsAsync(""); + x.SendAsync( + It.Is<PostJsonRequest>(r => + r.RequestUri == new Uri("https://upload.twitter.com/1.1/media/metadata/create.json") && + r.JsonString == """{"media_id": "12345", "alt_text": {"text": "hogehoge"}}""" + ) + ) + ); using var twitterApi = new TwitterApi(); twitterApi.ApiConnection = mock.Object; diff --git a/OpenTween/Api/TwitterApi.cs b/OpenTween/Api/TwitterApi.cs index 6614555e7..e3d3be4f0 100644 --- a/OpenTween/Api/TwitterApi.cs +++ b/OpenTween/Api/TwitterApi.cs @@ -425,10 +425,8 @@ public Task<TwitterMessageEventList> DirectMessagesEventsList(int? count = null, return this.Connection.GetAsync<TwitterMessageEventList>(endpoint, param, "/direct_messages/events/list"); } - public Task<LazyJson<TwitterMessageEventSingle>> DirectMessagesEventsNew(long recipientId, string text, long? mediaId = null) + public async Task<LazyJson<TwitterMessageEventSingle>> DirectMessagesEventsNew(long recipientId, string text, long? mediaId = null) { - var endpoint = new Uri("direct_messages/events/new.json", UriKind.Relative); - var attachment = ""; if (mediaId != null) { @@ -458,7 +456,16 @@ public Task<LazyJson<TwitterMessageEventSingle>> DirectMessagesEventsNew(long re } """; - return this.Connection.PostJsonAsync<TwitterMessageEventSingle>(endpoint, json); + var request = new PostJsonRequest + { + RequestUri = new("direct_messages/events/new.json", UriKind.Relative), + JsonString = json, + }; + + var response = await this.Connection.SendAsync(request) + .ConfigureAwait(false); + + return response.ReadAsLazyJson<TwitterMessageEventSingle>(); } public Task DirectMessagesEventsDestroy(TwitterDirectMessageId eventId) @@ -792,14 +799,18 @@ public Task<TwitterUploadMediaResult> MediaUploadStatus(long mediaId) return this.Connection.GetAsync<TwitterUploadMediaResult>(endpoint, param, endpointName: null); } - public Task MediaMetadataCreate(long mediaId, string altText) + public async Task MediaMetadataCreate(long mediaId, string altText) { - var endpoint = new Uri("https://upload.twitter.com/1.1/media/metadata/create.json"); - var escapedAltText = JsonUtils.EscapeJsonString(altText); - var json = $$$"""{"media_id": "{{{mediaId}}}", "alt_text": {"text": "{{{escapedAltText}}}"}}"""; + var request = new PostJsonRequest + { + RequestUri = new("https://upload.twitter.com/1.1/media/metadata/create.json"), + JsonString = $$$"""{"media_id": "{{{mediaId}}}", "alt_text": {"text": "{{{escapedAltText}}}"}}""", + }; - return this.Connection.PostJsonAsync(endpoint, json); + await this.Connection.SendAsync(request) + .IgnoreResponse() + .ConfigureAwait(false); } public OAuthEchoHandler CreateOAuthEchoHandler(HttpMessageHandler innerHandler, Uri authServiceProvider, Uri? realm = null) diff --git a/OpenTween/Connection/ApiResponse.cs b/OpenTween/Connection/ApiResponse.cs index ee1560058..da03230e9 100644 --- a/OpenTween/Connection/ApiResponse.cs +++ b/OpenTween/Connection/ApiResponse.cs @@ -114,4 +114,13 @@ public async Task<string> ReadAsString() .ConfigureAwait(false); } } + + public static class ApiResponseTaskExtension + { + public static async Task IgnoreResponse(this Task<ApiResponse> task) + { + using var response = await task.ConfigureAwait(false); + // レスポンスボディを読み込まず破棄する + } + } } From 666676ab362b431014b9a11e1e41f5d1d95555b2 Mon Sep 17 00:00:00 2001 From: Kimura Youichi <kim.upsilon@bucyou.net> Date: Tue, 12 Dec 2023 01:27:32 +0900 Subject: [PATCH 2/7] =?UTF-8?q?TwitterApiConnection.PostJsonAsync=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Connection/TwitterApiConnectionTest.cs | 69 ------------------- OpenTween/Connection/IApiConnectionLegacy.cs | 4 -- OpenTween/Connection/TwitterApiConnection.cs | 29 -------- 3 files changed, 102 deletions(-) diff --git a/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs b/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs index c646f07bb..b793548e3 100644 --- a/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs +++ b/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs @@ -481,75 +481,6 @@ public async Task PostLazyAsync_Multipart_NullTest() Assert.Equal(0, mockHandler.QueueCount); } - [Fact] - public async Task PostJsonAsync_Test() - { - using var mockHandler = new HttpMessageHandlerMock(); - using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection(); - apiConnection.Http = http; - - mockHandler.Enqueue(async x => - { - Assert.Equal(HttpMethod.Post, x.Method); - Assert.Equal("https://api.twitter.com/1.1/hoge/tetete.json", - x.RequestUri.AbsoluteUri); - - Assert.Equal("application/json; charset=utf-8", x.Content.Headers.ContentType.ToString()); - - var body = await x.Content.ReadAsStringAsync(); - - Assert.Equal("""{"aaaa": 1111}""", body); - - return new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new StringContent(@"{""ok"":true}"), - }; - }); - - var endpoint = new Uri("hoge/tetete.json", UriKind.Relative); - - var response = await apiConnection.PostJsonAsync(endpoint, """{"aaaa": 1111}"""); - - Assert.Equal(@"{""ok"":true}", response); - Assert.Equal(0, mockHandler.QueueCount); - } - - [Fact] - public async Task PostJsonAsync_T_Test() - { - using var mockHandler = new HttpMessageHandlerMock(); - using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection(); - apiConnection.Http = http; - - mockHandler.Enqueue(async x => - { - Assert.Equal(HttpMethod.Post, x.Method); - Assert.Equal("https://api.twitter.com/1.1/hoge/tetete.json", - x.RequestUri.AbsoluteUri); - - Assert.Equal("application/json; charset=utf-8", x.Content.Headers.ContentType.ToString()); - - var body = await x.Content.ReadAsStringAsync(); - - Assert.Equal("""{"aaaa": 1111}""", body); - - return new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new StringContent("\"hogehoge\""), - }; - }); - - var endpoint = new Uri("hoge/tetete.json", UriKind.Relative); - var response = await apiConnection.PostJsonAsync<string>(endpoint, """{"aaaa": 1111}"""); - var result = await response.LoadJsonAsync(); - - Assert.Equal("hogehoge", result); - - Assert.Equal(0, mockHandler.QueueCount); - } - [Fact] public async Task DeleteAsync_Test() { diff --git a/OpenTween/Connection/IApiConnectionLegacy.cs b/OpenTween/Connection/IApiConnectionLegacy.cs index 4175e589d..b72dd5072 100644 --- a/OpenTween/Connection/IApiConnectionLegacy.cs +++ b/OpenTween/Connection/IApiConnectionLegacy.cs @@ -46,10 +46,6 @@ public interface IApiConnectionLegacy : IApiConnection, IDisposable Task PostAsync(Uri uri, IDictionary<string, string>? param, IDictionary<string, IMediaItem>? media); - Task<string> PostJsonAsync(Uri uri, string json); - - Task<LazyJson<T>> PostJsonAsync<T>(Uri uri, string json); - Task DeleteAsync(Uri uri); } } diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index bfcc99b0d..2b3f651bc 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -351,35 +351,6 @@ await TwitterApiConnection.CheckStatusCode(response) } } - public async Task<string> PostJsonAsync(Uri uri, string json) - { - var request = new PostJsonRequest - { - RequestUri = uri, - JsonString = json, - }; - - using var response = await this.SendAsync(request) - .ConfigureAwait(false); - - return await response.ReadAsString() - .ConfigureAwait(false); - } - - public async Task<LazyJson<T>> PostJsonAsync<T>(Uri uri, string json) - { - var request = new PostJsonRequest - { - RequestUri = uri, - JsonString = json, - }; - - using var response = await this.SendAsync(request) - .ConfigureAwait(false); - - return response.ReadAsLazyJson<T>(); - } - public async Task DeleteAsync(Uri uri) { var requestUri = new Uri(RestApiBase, uri); From 0cf3ada054f61714f7acf56a69e49d215e8c13fa Mon Sep 17 00:00:00 2001 From: Kimura Youichi <kim.upsilon@bucyou.net> Date: Tue, 12 Dec 2023 01:50:26 +0900 Subject: [PATCH 3/7] =?UTF-8?q?DeleteRequest=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Connection/DeleteRequestTest.cs | 50 +++++++++++++++++++ OpenTween/Connection/DeleteRequest.cs | 45 +++++++++++++++++ OpenTween/Connection/TwitterApiConnection.cs | 23 +++------ 3 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 OpenTween.Tests/Connection/DeleteRequestTest.cs create mode 100644 OpenTween/Connection/DeleteRequest.cs diff --git a/OpenTween.Tests/Connection/DeleteRequestTest.cs b/OpenTween.Tests/Connection/DeleteRequestTest.cs new file mode 100644 index 000000000..3b72c5b0d --- /dev/null +++ b/OpenTween.Tests/Connection/DeleteRequestTest.cs @@ -0,0 +1,50 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2023 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/> +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see <http://www.gnu.org/licenses/>, or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Net.Http; +using Xunit; + +namespace OpenTween.Connection +{ + public class DeleteRequestTest + { + [Fact] + public void CreateMessage_Test() + { + var request = new DeleteRequest + { + RequestUri = new("hoge/aaa.json", UriKind.Relative), + Query = new Dictionary<string, string> + { + ["id"] = "12345", + }, + }; + + var baseUri = new Uri("https://example.com/v1/"); + using var requestMessage = request.CreateMessage(baseUri); + + Assert.Equal(HttpMethod.Delete, requestMessage.Method); + Assert.Equal(new("https://example.com/v1/hoge/aaa.json?id=12345"), requestMessage.RequestUri); + } + } +} diff --git a/OpenTween/Connection/DeleteRequest.cs b/OpenTween/Connection/DeleteRequest.cs new file mode 100644 index 000000000..f15502814 --- /dev/null +++ b/OpenTween/Connection/DeleteRequest.cs @@ -0,0 +1,45 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2023 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/> +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see <http://www.gnu.org/licenses/>, or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Net.Http; + +namespace OpenTween.Connection +{ + public class DeleteRequest : IHttpRequest + { + public required Uri RequestUri { get; set; } + + public IDictionary<string, string>? Query { get; set; } + + public string? EndpointName { get; set; } + + public HttpRequestMessage CreateMessage(Uri baseUri) + => new() + { + Method = HttpMethod.Delete, + RequestUri = GetRequest.BuildUriWithQuery(new(baseUri, this.RequestUri), this.Query), + }; + } +} diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index 2b3f651bc..93db05aaa 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -353,25 +353,14 @@ await TwitterApiConnection.CheckStatusCode(response) public async Task DeleteAsync(Uri uri) { - var requestUri = new Uri(RestApiBase, uri); - using var request = new HttpRequestMessage(HttpMethod.Delete, requestUri); - - try + var request = new DeleteRequest { - using var response = await this.Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); + RequestUri = uri, + }; - await TwitterApiConnection.CheckStatusCode(response) - .ConfigureAwait(false); - } - catch (HttpRequestException ex) - { - throw TwitterApiException.CreateFromException(ex); - } - catch (OperationCanceledException ex) - { - throw TwitterApiException.CreateFromException(ex); - } + await this.SendAsync(request) + .IgnoreResponse() + .ConfigureAwait(false); } public static async Task<T> HandleTimeout<T>(Func<CancellationToken, Task<T>> func, TimeSpan timeout) From c79d992c15612c7db85c899d1d355e7f22907d41 Mon Sep 17 00:00:00 2001 From: Kimura Youichi <kim.upsilon@bucyou.net> Date: Tue, 12 Dec 2023 02:05:06 +0900 Subject: [PATCH 4/7] =?UTF-8?q?IApiConnectionLegacy.DeleteAsync=E3=82=92?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=81=97=E3=81=A6=E3=81=84=E3=82=8B=E7=AE=87?= =?UTF-8?q?=E6=89=80=E3=82=92DeleteRequest=E3=81=AB=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Api/TwitterApiTest.cs | 13 +++++++++---- OpenTween/Api/TwitterApi.cs | 18 ++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/OpenTween.Tests/Api/TwitterApiTest.cs b/OpenTween.Tests/Api/TwitterApiTest.cs index 87df7119d..c660337a3 100644 --- a/OpenTween.Tests/Api/TwitterApiTest.cs +++ b/OpenTween.Tests/Api/TwitterApiTest.cs @@ -721,10 +721,15 @@ public async Task DirectMessagesEventsDestroy_Test() { var mock = new Mock<IApiConnectionLegacy>(); mock.Setup(x => - x.DeleteAsync( - new Uri("direct_messages/events/destroy.json?id=100", UriKind.Relative)) - ) - .Returns(Task.CompletedTask); + x.SendAsync( + It.Is<DeleteRequest>(r => + r.RequestUri == new Uri("direct_messages/events/destroy.json", UriKind.Relative) && + r.Query != null && + r.Query.Count == 1 && + r.Query["id"] == "100" + ) + ) + ); using var twitterApi = new TwitterApi(); twitterApi.ApiConnection = mock.Object; diff --git a/OpenTween/Api/TwitterApi.cs b/OpenTween/Api/TwitterApi.cs index e3d3be4f0..342122287 100644 --- a/OpenTween/Api/TwitterApi.cs +++ b/OpenTween/Api/TwitterApi.cs @@ -468,18 +468,20 @@ public async Task<LazyJson<TwitterMessageEventSingle>> DirectMessagesEventsNew(l return response.ReadAsLazyJson<TwitterMessageEventSingle>(); } - public Task DirectMessagesEventsDestroy(TwitterDirectMessageId eventId) + public async Task DirectMessagesEventsDestroy(TwitterDirectMessageId eventId) { - var endpoint = new Uri("direct_messages/events/destroy.json", UriKind.Relative); - var param = new Dictionary<string, string> + var request = new DeleteRequest { - ["id"] = eventId.Id, + RequestUri = new("direct_messages/events/destroy.json", UriKind.Relative), + Query = new Dictionary<string, string> + { + ["id"] = eventId.Id, + }, }; - // なぜか application/x-www-form-urlencoded でパラメーターを送ると Bad Request になる謎仕様 - endpoint = new Uri(endpoint.OriginalString + "?" + MyCommon.BuildQueryString(param), UriKind.Relative); - - return this.Connection.DeleteAsync(endpoint); + await this.Connection.SendAsync(request) + .IgnoreResponse() + .ConfigureAwait(false); } public Task<TwitterUser> UsersShow(string screenName) From 76f1ff02d3592e13e9c9e4ba2bed11c0ab6f2ba0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi <kim.upsilon@bucyou.net> Date: Tue, 12 Dec 2023 02:06:29 +0900 Subject: [PATCH 5/7] =?UTF-8?q?TwitterApiConnection.DeleteAsync=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Connection/TwitterApiConnectionTest.cs | 24 ------------------- OpenTween/Connection/IApiConnectionLegacy.cs | 2 -- OpenTween/Connection/TwitterApiConnection.cs | 12 ---------- 3 files changed, 38 deletions(-) diff --git a/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs b/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs index b793548e3..bfb4b5f96 100644 --- a/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs +++ b/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs @@ -481,30 +481,6 @@ public async Task PostLazyAsync_Multipart_NullTest() Assert.Equal(0, mockHandler.QueueCount); } - [Fact] - public async Task DeleteAsync_Test() - { - using var mockHandler = new HttpMessageHandlerMock(); - using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection(); - apiConnection.Http = http; - - mockHandler.Enqueue(x => - { - Assert.Equal(HttpMethod.Delete, x.Method); - Assert.Equal("https://api.twitter.com/1.1/hoge/tetete.json", - x.RequestUri.AbsoluteUri); - - return new HttpResponseMessage(HttpStatusCode.NoContent); - }); - - var endpoint = new Uri("hoge/tetete.json", UriKind.Relative); - - await apiConnection.DeleteAsync(endpoint); - - Assert.Equal(0, mockHandler.QueueCount); - } - [Fact] public async Task HandleTimeout_SuccessTest() { diff --git a/OpenTween/Connection/IApiConnectionLegacy.cs b/OpenTween/Connection/IApiConnectionLegacy.cs index b72dd5072..7f364f6ac 100644 --- a/OpenTween/Connection/IApiConnectionLegacy.cs +++ b/OpenTween/Connection/IApiConnectionLegacy.cs @@ -45,7 +45,5 @@ public interface IApiConnectionLegacy : IApiConnection, IDisposable Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param, IDictionary<string, IMediaItem>? media); Task PostAsync(Uri uri, IDictionary<string, string>? param, IDictionary<string, IMediaItem>? media); - - Task DeleteAsync(Uri uri); } } diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index 93db05aaa..7c7e578f6 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -351,18 +351,6 @@ await TwitterApiConnection.CheckStatusCode(response) } } - public async Task DeleteAsync(Uri uri) - { - var request = new DeleteRequest - { - RequestUri = uri, - }; - - await this.SendAsync(request) - .IgnoreResponse() - .ConfigureAwait(false); - } - public static async Task<T> HandleTimeout<T>(Func<CancellationToken, Task<T>> func, TimeSpan timeout) { using var cts = new CancellationTokenSource(); From 1668176ee22fd71149bd25d900af36f9213f0de7 Mon Sep 17 00:00:00 2001 From: Kimura Youichi <kim.upsilon@bucyou.net> Date: Tue, 12 Dec 2023 01:32:28 +0900 Subject: [PATCH 6/7] =?UTF-8?q?TwitterApiConnection.GetStreamAsync?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Connection/TwitterApiConnectionTest.cs | 46 ------------------- OpenTween/Connection/IApiConnectionLegacy.cs | 4 -- OpenTween/Connection/TwitterApiConnection.cs | 38 --------------- OpenTween/ErrorReportHandler.cs | 12 ----- 4 files changed, 100 deletions(-) diff --git a/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs b/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs index bfb4b5f96..cc8935625 100644 --- a/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs +++ b/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs @@ -280,52 +280,6 @@ public async Task SendAsync_ErrorJsonTest() Assert.Equal(0, mockHandler.QueueCount); } - [Fact] - public async Task GetStreamAsync_Test() - { - using var mockHandler = new HttpMessageHandlerMock(); - using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection(); - using var image = TestUtils.CreateDummyImage(); - apiConnection.Http = http; - - mockHandler.Enqueue(x => - { - Assert.Equal(HttpMethod.Get, x.Method); - Assert.Equal("https://api.twitter.com/1.1/hoge/tetete.json", - x.RequestUri.GetLeftPart(UriPartial.Path)); - - var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - - Assert.Equal("1111", query["aaaa"]); - Assert.Equal("2222", query["bbbb"]); - - return new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new ByteArrayContent(image.Stream.ToArray()), - }; - }); - - var endpoint = new Uri("hoge/tetete.json", UriKind.Relative); - var param = new Dictionary<string, string> - { - ["aaaa"] = "1111", - ["bbbb"] = "2222", - }; - - var stream = await apiConnection.GetStreamAsync(endpoint, param); - - using (var memoryStream = new MemoryStream()) - { - // 内容の比較のために MemoryStream にコピー - await stream.CopyToAsync(memoryStream); - - Assert.Equal(image.Stream.ToArray(), memoryStream.ToArray()); - } - - Assert.Equal(0, mockHandler.QueueCount); - } - [Fact] public async Task PostLazyAsync_Test() { diff --git a/OpenTween/Connection/IApiConnectionLegacy.cs b/OpenTween/Connection/IApiConnectionLegacy.cs index 7f364f6ac..9b9e7d8c0 100644 --- a/OpenTween/Connection/IApiConnectionLegacy.cs +++ b/OpenTween/Connection/IApiConnectionLegacy.cs @@ -34,10 +34,6 @@ public interface IApiConnectionLegacy : IApiConnection, IDisposable { Task<T> GetAsync<T>(Uri uri, IDictionary<string, string>? param, string? endpointName); - Task<Stream> GetStreamAsync(Uri uri, IDictionary<string, string>? param); - - Task<Stream> GetStreamAsync(Uri uri, IDictionary<string, string>? param, string? endpointName); - Task<Stream> GetStreamingStreamAsync(Uri uri, IDictionary<string, string>? param); Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param); diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index 7c7e578f6..bf81c2363 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -164,44 +164,6 @@ private void ThrowIfRateLimitExceeded(string endpointName) } } - public Task<Stream> GetStreamAsync(Uri uri, IDictionary<string, string>? param) - => this.GetStreamAsync(uri, param, null); - - public async Task<Stream> GetStreamAsync(Uri uri, IDictionary<string, string>? param, string? endpointName) - { - // レートリミット規制中はAPIリクエストを送信せずに直ちにエラーを発生させる - if (endpointName != null) - this.ThrowIfRateLimitExceeded(endpointName); - - var requestUri = new Uri(RestApiBase, uri); - - if (param != null) - requestUri = new Uri(requestUri, "?" + MyCommon.BuildQueryString(param)); - - try - { - var response = await this.Http.GetAsync(requestUri) - .ConfigureAwait(false); - - if (endpointName != null) - MyCommon.TwitterApiInfo.UpdateFromHeader(response.Headers, endpointName); - - await TwitterApiConnection.CheckStatusCode(response) - .ConfigureAwait(false); - - return await response.Content.ReadAsStreamAsync() - .ConfigureAwait(false); - } - catch (HttpRequestException ex) - { - throw TwitterApiException.CreateFromException(ex); - } - catch (OperationCanceledException ex) - { - throw TwitterApiException.CreateFromException(ex); - } - } - public async Task<Stream> GetStreamingStreamAsync(Uri uri, IDictionary<string, string>? param) { var requestUri = new Uri(RestApiBase, uri); diff --git a/OpenTween/ErrorReportHandler.cs b/OpenTween/ErrorReportHandler.cs index af9d572f6..166b1727b 100644 --- a/OpenTween/ErrorReportHandler.cs +++ b/OpenTween/ErrorReportHandler.cs @@ -106,18 +106,6 @@ public static bool IsExceptionIgnorable(Exception ex) return true; } - if (ex is TaskCanceledException cancelEx) - { - // ton.twitter.com の画像でタイムアウトした場合、try-catch で例外がキャッチできない - // https://osdn.net/ticket/browse.php?group_id=6526&tid=37433 - var stackTrace = new StackTrace(cancelEx); - var lastFrameMethod = stackTrace.GetFrame(stackTrace.FrameCount - 1).GetMethod(); - var matchClass = lastFrameMethod.ReflectedType == typeof(TwitterApiConnection); - var matchMethod = lastFrameMethod.Name == nameof(TwitterApiConnection.GetStreamAsync); - if (matchClass && matchMethod) - return true; - } - return false; } } From a5614fe46cf642c88084098da4e5364c7511db7a Mon Sep 17 00:00:00 2001 From: Kimura Youichi <kim.upsilon@bucyou.net> Date: Tue, 12 Dec 2023 01:39:40 +0900 Subject: [PATCH 7/7] =?UTF-8?q?TwitterApiConnection.GetStreamingStreamAsyn?= =?UTF-8?q?c=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Connection/IApiConnectionLegacy.cs | 2 - OpenTween/Connection/TwitterApiConnection.cs | 48 ++------------------ 2 files changed, 5 insertions(+), 45 deletions(-) diff --git a/OpenTween/Connection/IApiConnectionLegacy.cs b/OpenTween/Connection/IApiConnectionLegacy.cs index 9b9e7d8c0..839ad462e 100644 --- a/OpenTween/Connection/IApiConnectionLegacy.cs +++ b/OpenTween/Connection/IApiConnectionLegacy.cs @@ -34,8 +34,6 @@ public interface IApiConnectionLegacy : IApiConnection, IDisposable { Task<T> GetAsync<T>(Uri uri, IDictionary<string, string>? param, string? endpointName); - Task<Stream> GetStreamingStreamAsync(Uri uri, IDictionary<string, string>? param); - Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param); Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param, IDictionary<string, IMediaItem>? media); diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index bf81c2363..0e860607c 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -54,7 +54,6 @@ public static string RestApiHost internal HttpClient Http; internal HttpClient HttpUpload; - internal HttpClient HttpStreaming; internal ITwitterCredential Credential { get; } @@ -71,16 +70,13 @@ public TwitterApiConnection(ITwitterCredential credential) Networking.WebProxyChanged += this.Networking_WebProxyChanged; } - [MemberNotNull(nameof(Http), nameof(HttpUpload), nameof(HttpStreaming))] + [MemberNotNull(nameof(Http), nameof(HttpUpload))] private void InitializeHttpClients() { this.Http = InitializeHttpClient(this.Credential); this.HttpUpload = InitializeHttpClient(this.Credential); this.HttpUpload.Timeout = Networking.UploadImageTimeout; - - this.HttpStreaming = InitializeHttpClient(this.Credential, disableGzip: true); - this.HttpStreaming.Timeout = Timeout.InfiniteTimeSpan; } public async Task<ApiResponse> SendAsync(IHttpRequest request) @@ -164,35 +160,6 @@ private void ThrowIfRateLimitExceeded(string endpointName) } } - public async Task<Stream> GetStreamingStreamAsync(Uri uri, IDictionary<string, string>? param) - { - var requestUri = new Uri(RestApiBase, uri); - - if (param != null) - requestUri = new Uri(requestUri, "?" + MyCommon.BuildQueryString(param)); - - try - { - var request = new HttpRequestMessage(HttpMethod.Get, requestUri); - var response = await this.HttpStreaming.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - - await TwitterApiConnection.CheckStatusCode(response) - .ConfigureAwait(false); - - return await response.Content.ReadAsStreamAsync() - .ConfigureAwait(false); - } - catch (HttpRequestException ex) - { - throw TwitterApiException.CreateFromException(ex); - } - catch (OperationCanceledException ex) - { - throw TwitterApiException.CreateFromException(ex); - } - } - public async Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param) { var requestUri = new Uri(RestApiBase, uri); @@ -438,7 +405,6 @@ protected virtual void Dispose(bool disposing) Networking.WebProxyChanged -= this.Networking_WebProxyChanged; this.Http.Dispose(); this.HttpUpload.Dispose(); - this.HttpStreaming.Dispose(); } } @@ -524,17 +490,13 @@ await TwitterApiConnection.CheckStatusCode(response) } } - private static HttpClient InitializeHttpClient(ITwitterCredential credential, bool disableGzip = false) + private static HttpClient InitializeHttpClient(ITwitterCredential credential) { var builder = Networking.CreateHttpClientBuilder(); - builder.SetupHttpClientHandler(x => - { - x.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); - - if (disableGzip) - x.AutomaticDecompression = DecompressionMethods.None; - }); + builder.SetupHttpClientHandler( + x => x.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache) + ); builder.AddHandler(x => credential.CreateHttpHandler(x));