Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify WebBrowser API in regards to nullable bodies #2593

Merged
merged 3 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal static class CatAPI {

ObjectResponse<MeowResponse>? response = await webBrowser.UrlGetToJsonObject<MeowResponse>(request).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotC

ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionInProgress, appTokens.Count, packageTokens.Count, depotKeys.Count));

OptionalObjectResponse<ResponseData>? response = await ASF.WebBrowser.UrlPostToOptionalJsonObject<ResponseData, RequestData>(request, data: requestData, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors).ConfigureAwait(false);
ObjectResponse<ResponseData>? response = await ASF.WebBrowser.UrlPostToJsonObject<ResponseData, RequestData>(request, data: requestData, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors).ConfigureAwait(false);

if (response == null) {
ASF.ArchiLogger.LogGenericWarning(ArchiSteamFarm.Localization.Strings.WarningFailed);
Expand Down
2 changes: 1 addition & 1 deletion ArchiSteamFarm/Core/ArchiNet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ internal static class ArchiNet {

ObjectResponse<ChecksumResponse>? response = await ASF.WebBrowser.UrlGetToJsonObject<ChecksumResponse>(request).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return null;
}

Expand Down
36 changes: 18 additions & 18 deletions ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public sealed class ArchiWebHandler : IDisposable {

response = await UrlGetToJsonObjectWithSession<InventoryResponse>(request, requestOptions: WebBrowser.ERequestOptions.ReturnServerErrors, rateLimitingDelay: rateLimitingDelay).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
throw new HttpRequestException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorObjectIsNull, nameof(response)));
}

Expand Down Expand Up @@ -210,7 +210,7 @@ public sealed class ArchiWebHandler : IDisposable {
}
}

if (response == null) {
if (response?.Content == null) {
throw new HttpRequestException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorObjectIsNull, nameof(response)));
}

Expand Down Expand Up @@ -434,7 +434,7 @@ public sealed class ArchiWebHandler : IDisposable {
for (byte i = 0; (i < WebBrowser.MaxTries) && (response == null); i++) {
response = await UrlPostToJsonObjectWithSession<TradeOfferSendResponse>(request, data: data, referer: referer, requestOptions: WebBrowser.ERequestOptions.ReturnServerErrors).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return (false, mobileTradeOfferIDs);
}

Expand All @@ -453,7 +453,7 @@ public sealed class ArchiWebHandler : IDisposable {
}
}

if (response == null) {
if (response?.Content == null) {
return (false, mobileTradeOfferIDs);
}

Expand Down Expand Up @@ -1231,7 +1231,7 @@ public sealed class ArchiWebHandler : IDisposable {

ObjectResponse<ResultResponse>? response = await UrlPostToJsonObjectWithSession<ResultResponse>(request, data: data).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return false;
}

Expand Down Expand Up @@ -1263,7 +1263,7 @@ public sealed class ArchiWebHandler : IDisposable {
for (byte i = 0; (i < WebBrowser.MaxTries) && (response == null); i++) {
response = await UrlPostToJsonObjectWithSession<TradeOfferAcceptResponse>(request, data: data, referer: referer, requestOptions: WebBrowser.ERequestOptions.ReturnServerErrors).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return (false, false);
}

Expand All @@ -1282,7 +1282,7 @@ public sealed class ArchiWebHandler : IDisposable {
}
}

return response != null ? (true, response.Content.RequiresMobileConfirmation) : (false, false);
return response?.Content != null ? (true, response.Content.RequiresMobileConfirmation) : (false, false);
}

internal async Task<(EResult Result, EPurchaseResultDetail PurchaseResult)> AddFreeLicense(uint subID) {
Expand Down Expand Up @@ -1354,7 +1354,7 @@ public sealed class ArchiWebHandler : IDisposable {

ObjectResponse<ResultResponse>? response = await UrlPostToJsonObjectWithSession<ResultResponse>(request, data: data).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return false;
}

Expand Down Expand Up @@ -1400,7 +1400,7 @@ public sealed class ArchiWebHandler : IDisposable {

ObjectResponse<NewDiscoveryQueueResponse>? response = await UrlPostToJsonObjectWithSession<NewDiscoveryQueueResponse>(request, data: data).ConfigureAwait(false);

return response?.Content.Queue;
return response?.Content?.Queue;
}

internal async Task<HashSet<TradeOffer>?> GetActiveTradeOffers() {
Expand Down Expand Up @@ -1717,7 +1717,7 @@ public sealed class ArchiWebHandler : IDisposable {

using HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request, checkSessionPreemptively: false).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return null;
}

Expand Down Expand Up @@ -1763,7 +1763,7 @@ public sealed class ArchiWebHandler : IDisposable {

using HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request, checkSessionPreemptively: false).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return null;
}

Expand Down Expand Up @@ -1855,7 +1855,7 @@ public sealed class ArchiWebHandler : IDisposable {

using HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request, checkSessionPreemptively: false).ConfigureAwait(false);

IElement? htmlNode = response?.Content.SelectSingleNode("//div[@class='pagecontent']/script");
IElement? htmlNode = response?.Content?.SelectSingleNode("//div[@class='pagecontent']/script");

if (htmlNode == null) {
// Trade can be no longer valid
Expand Down Expand Up @@ -2005,7 +2005,7 @@ public sealed class ArchiWebHandler : IDisposable {

ObjectResponse<BooleanResponse>? response = await UrlGetToJsonObjectWithSession<BooleanResponse>(request).ConfigureAwait(false);

return response?.Content.Success;
return response?.Content?.Success;
}

internal async Task<bool?> HandleConfirmations(string deviceID, string confirmationHash, uint time, IReadOnlyCollection<Confirmation> confirmations, bool accept) {
Expand Down Expand Up @@ -2059,7 +2059,7 @@ public sealed class ArchiWebHandler : IDisposable {

ObjectResponse<BooleanResponse>? response = await UrlPostToJsonObjectWithSession<BooleanResponse>(request, data: data).ConfigureAwait(false);

return response?.Content.Success;
return response?.Content?.Success;
}

internal async Task<bool> Init(ulong steamID, EUniverse universe, string webAPIUserNonce, string? parentalCode = null) {
Expand Down Expand Up @@ -2253,7 +2253,7 @@ public sealed class ArchiWebHandler : IDisposable {

ObjectResponse<RedeemWalletResponse>? response = await UrlPostToJsonObjectWithSession<RedeemWalletResponse>(request, data: data).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return null;
}

Expand Down Expand Up @@ -2292,15 +2292,15 @@ public sealed class ArchiWebHandler : IDisposable {

ObjectResponse<ResultResponse>? response = await UrlPostToJsonObjectWithSession<ResultResponse>(request, data: data).ConfigureAwait(false);

return response?.Content.Result == EResult.OK;
return response?.Content?.Result == EResult.OK;
}

private async Task<(ESteamApiKeyState State, string? Key)> GetApiKeyState() {
Uri request = new(SteamCommunityURL, "/dev/apikey?l=english");

using HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request, checkSessionPreemptively: false).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return (ESteamApiKeyState.Timeout, null);
}

Expand Down Expand Up @@ -2570,7 +2570,7 @@ public sealed class ArchiWebHandler : IDisposable {
ObjectResponse<AccessTokenResponse>? response = await UrlGetToJsonObjectWithSession<AccessTokenResponse>(request).ConfigureAwait(false);

// ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework
return !string.IsNullOrEmpty(response?.Content.Data.WebAPIToken) ? (true, response!.Content.Data.WebAPIToken) : (false, null);
return !string.IsNullOrEmpty(response?.Content?.Data.WebAPIToken) ? (true, response!.Content!.Data.WebAPIToken) : (false, null);
}

private async Task<(bool Success, string? Result)> ResolveApiKey() {
Expand Down
14 changes: 7 additions & 7 deletions ArchiSteamFarm/Web/GitHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,19 @@ internal static class GitHub {

Uri request = new($"{SharedInfo.ProjectURL}/wiki/{page}/_history");

using HtmlDocumentResponse? response = await ASF.WebBrowser.UrlGetToHtmlDocument(request, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
using HtmlDocumentResponse? response = await ASF.WebBrowser.UrlGetToHtmlDocument(request, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors).ConfigureAwait(false);

if (response == null) {
return null;
}

if (response.StatusCode.IsClientErrorCode()) {
if (response?.StatusCode.IsClientErrorCode() == true) {
return response.StatusCode switch {
HttpStatusCode.NotFound => new Dictionary<string, DateTime>(0),
_ => null
};
}

if (response?.Content == null) {
return null;
}

IEnumerable<IElement> revisionNodes = response.Content.SelectNodes("//li[contains(@class, 'wiki-history-revision')]");

Dictionary<string, DateTime> result = new();
Expand Down Expand Up @@ -148,7 +148,7 @@ internal static class GitHub {

using HtmlDocumentResponse? response = await ASF.WebBrowser.UrlGetToHtmlDocument(request).ConfigureAwait(false);

if (response == null) {
if (response?.Content == null) {
return null;
}

Expand Down
21 changes: 6 additions & 15 deletions ArchiSteamFarm/Web/Responses/HtmlDocumentResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,28 @@
using System.Threading.Tasks;
using AngleSharp;
using AngleSharp.Dom;
using ArchiSteamFarm.Core;
using JetBrains.Annotations;

namespace ArchiSteamFarm.Web.Responses;

public sealed class HtmlDocumentResponse : BasicResponse, IDisposable {
JustArchi marked this conversation as resolved.
Show resolved Hide resolved
[PublicAPI]
public IDocument Content { get; }
public IDocument? Content { get; }

private HtmlDocumentResponse(BasicResponse basicResponse, IDocument content) : base(basicResponse) {
ArgumentNullException.ThrowIfNull(basicResponse);
public HtmlDocumentResponse(BasicResponse basicResponse) : base(basicResponse) => ArgumentNullException.ThrowIfNull(basicResponse);

Content = content ?? throw new ArgumentNullException(nameof(content));
}
private HtmlDocumentResponse(BasicResponse basicResponse, IDocument content) : this(basicResponse) => Content = content ?? throw new ArgumentNullException(nameof(content));

public void Dispose() => Content.Dispose();
public void Dispose() => Content?.Dispose();

[PublicAPI]
public static async Task<HtmlDocumentResponse?> Create(StreamResponse streamResponse) {
ArgumentNullException.ThrowIfNull(streamResponse);

IBrowsingContext context = BrowsingContext.New();

try {
IDocument document = await context.OpenAsync(req => req.Content(streamResponse.Content, true)).ConfigureAwait(false);

return new HtmlDocumentResponse(streamResponse, document);
} catch (Exception e) {
ASF.ArchiLogger.LogGenericWarningException(e);
IDocument document = await context.OpenAsync(request => request.Content(streamResponse.Content, true)).ConfigureAwait(false);

return null;
}
return new HtmlDocumentResponse(streamResponse, document);
}
}
8 changes: 3 additions & 5 deletions ArchiSteamFarm/Web/Responses/ObjectResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@ namespace ArchiSteamFarm.Web.Responses;

public sealed class ObjectResponse<T> : BasicResponse {
[PublicAPI]
public T Content { get; }
public T? Content { get; }

public ObjectResponse(BasicResponse basicResponse, T content) : base(basicResponse) {
ArgumentNullException.ThrowIfNull(basicResponse);
public ObjectResponse(BasicResponse basicResponse, T? content) : this(basicResponse) => Content = content;

Content = content ?? throw new ArgumentNullException(nameof(content));
}
public ObjectResponse(BasicResponse basicResponse) : base(basicResponse) => ArgumentNullException.ThrowIfNull(basicResponse);
}
38 changes: 0 additions & 38 deletions ArchiSteamFarm/Web/Responses/OptionalObjectResponse.cs

This file was deleted.