This commit is contained in:
JustArchi 2020-09-13 21:43:25 +02:00
parent e125863fd4
commit d4345a1a16
5 changed files with 112 additions and 100 deletions

View file

@ -429,7 +429,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
ASF.ArchiLogger.LogGenericInfo($"Submitting registered apps/subs/depots: {appTokens.Count}/{packageTokens.Count}/{depotKeys.Count}..."); ASF.ArchiLogger.LogGenericInfo($"Submitting registered apps/subs/depots: {appTokens.Count}/{packageTokens.Count}/{depotKeys.Count}...");
WebBrowser.ObjectResponse<ResponseData>? response = await ASF.WebBrowser.UrlPostToJsonObject<ResponseData, RequestData>(request, requestData, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false); WebBrowser.ObjectResponse<ResponseData>? response = await ASF.WebBrowser.UrlPostToJsonObject<ResponseData, RequestData>(request, data: requestData, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
if ((response?.Content?.Data == null) || response.StatusCode.IsClientErrorCode()) { if ((response?.Content?.Data == null) || response.StatusCode.IsClientErrorCode()) {
ASF.ArchiLogger.LogGenericWarning(Strings.WarningFailed); ASF.ArchiLogger.LogGenericWarning(Strings.WarningFailed);

View file

@ -407,7 +407,7 @@ namespace ArchiSteamFarm {
foreach (Steam.TradeOfferSendRequest trade in trades) { foreach (Steam.TradeOfferSendRequest trade in trades) {
data["json_tradeoffer"] = JsonConvert.SerializeObject(trade); data["json_tradeoffer"] = JsonConvert.SerializeObject(trade);
WebBrowser.ObjectResponse<Steam.TradeOfferSendResponse>? response = await UrlPostToJsonObjectWithSession<Steam.TradeOfferSendResponse>(SteamCommunityURL, request, data, referer).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.TradeOfferSendResponse>? response = await UrlPostToJsonObjectWithSession<Steam.TradeOfferSendResponse>(SteamCommunityURL, request, data: data, referer: referer).ConfigureAwait(false);
if (response?.Content == null) { if (response?.Content == null) {
return (false, mobileTradeOfferIDs); return (false, mobileTradeOfferIDs);
@ -422,7 +422,7 @@ namespace ArchiSteamFarm {
} }
[PublicAPI] [PublicAPI]
public async Task<WebBrowser.HtmlDocumentResponse?> UrlGetToHtmlDocumentWithSession(string host, string request, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) { public async Task<WebBrowser.HtmlDocumentResponse?> UrlGetToHtmlDocumentWithSession(string host, string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) {
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request)) { if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(request)); throw new ArgumentNullException(nameof(host) + " || " + nameof(request));
} }
@ -440,7 +440,7 @@ namespace ArchiSteamFarm {
if (sessionExpired.GetValueOrDefault(true)) { if (sessionExpired.GetValueOrDefault(true)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlGetToHtmlDocumentWithSession(host, request, referer, requestOptions, true, --maxTries).ConfigureAwait(false); return await UrlGetToHtmlDocumentWithSession(host, request, headers, referer, requestOptions, true, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -469,7 +469,7 @@ namespace ArchiSteamFarm {
} }
} }
WebBrowser.HtmlDocumentResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlGetToHtmlDocument(host + request, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.HtmlDocumentResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlGetToHtmlDocument(host + request, headers, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) { if (response == null) {
return null; return null;
@ -477,7 +477,7 @@ namespace ArchiSteamFarm {
if (IsSessionExpiredUri(response.FinalUri)) { if (IsSessionExpiredUri(response.FinalUri)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlGetToHtmlDocumentWithSession(host, request, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlGetToHtmlDocumentWithSession(host, request, headers, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -490,14 +490,14 @@ namespace ArchiSteamFarm {
if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) { if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri))); Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri)));
return await UrlGetToHtmlDocumentWithSession(host, request, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlGetToHtmlDocumentWithSession(host, request, headers, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
return response; return response;
} }
[PublicAPI] [PublicAPI]
public async Task<WebBrowser.ObjectResponse<T>?> UrlGetToJsonObjectWithSession<T>(string host, string request, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) where T : class { public async Task<WebBrowser.ObjectResponse<T>?> UrlGetToJsonObjectWithSession<T>(string host, string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) where T : class {
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request)) { if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(request)); throw new ArgumentNullException(nameof(host) + " || " + nameof(request));
} }
@ -515,7 +515,7 @@ namespace ArchiSteamFarm {
if (sessionExpired.GetValueOrDefault(true)) { if (sessionExpired.GetValueOrDefault(true)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlGetToJsonObjectWithSession<T>(host, request, referer, requestOptions, true, --maxTries).ConfigureAwait(false); return await UrlGetToJsonObjectWithSession<T>(host, request, headers, referer, requestOptions, true, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -544,7 +544,7 @@ namespace ArchiSteamFarm {
} }
} }
WebBrowser.ObjectResponse<T>? response = await WebLimitRequest(host, async () => await WebBrowser.UrlGetToJsonObject<T>(host + request, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.ObjectResponse<T>? response = await WebLimitRequest(host, async () => await WebBrowser.UrlGetToJsonObject<T>(host + request, headers, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) { if (response == null) {
return default; return default;
@ -552,7 +552,7 @@ namespace ArchiSteamFarm {
if (IsSessionExpiredUri(response.FinalUri)) { if (IsSessionExpiredUri(response.FinalUri)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlGetToJsonObjectWithSession<T>(host, request, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlGetToJsonObjectWithSession<T>(host, request, headers, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -565,14 +565,14 @@ namespace ArchiSteamFarm {
if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) { if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri))); Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri)));
return await UrlGetToJsonObjectWithSession<T>(host, request, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlGetToJsonObjectWithSession<T>(host, request, headers, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
return response; return response;
} }
[PublicAPI] [PublicAPI]
public async Task<WebBrowser.XmlDocumentResponse?> UrlGetToXmlDocumentWithSession(string host, string request, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) { public async Task<WebBrowser.XmlDocumentResponse?> UrlGetToXmlDocumentWithSession(string host, string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) {
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request)) { if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(request)); throw new ArgumentNullException(nameof(host) + " || " + nameof(request));
} }
@ -590,7 +590,7 @@ namespace ArchiSteamFarm {
if (sessionExpired.GetValueOrDefault(true)) { if (sessionExpired.GetValueOrDefault(true)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlGetToXmlDocumentWithSession(host, request, referer, requestOptions, true, --maxTries).ConfigureAwait(false); return await UrlGetToXmlDocumentWithSession(host, request, headers, referer, requestOptions, true, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -619,7 +619,7 @@ namespace ArchiSteamFarm {
} }
} }
WebBrowser.XmlDocumentResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlGetToXmlDocument(host + request, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.XmlDocumentResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlGetToXmlDocument(host + request, headers, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) { if (response == null) {
return null; return null;
@ -627,7 +627,7 @@ namespace ArchiSteamFarm {
if (IsSessionExpiredUri(response.FinalUri)) { if (IsSessionExpiredUri(response.FinalUri)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlGetToXmlDocumentWithSession(host, request, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlGetToXmlDocumentWithSession(host, request, headers, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -640,14 +640,14 @@ namespace ArchiSteamFarm {
if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) { if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri))); Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri)));
return await UrlGetToXmlDocumentWithSession(host, request, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlGetToXmlDocumentWithSession(host, request, headers, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
return response; return response;
} }
[PublicAPI] [PublicAPI]
public async Task<bool> UrlHeadWithSession(string host, string request, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) { public async Task<bool> UrlHeadWithSession(string host, string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) {
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request)) { if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(request)); throw new ArgumentNullException(nameof(host) + " || " + nameof(request));
} }
@ -665,7 +665,7 @@ namespace ArchiSteamFarm {
if (sessionExpired.GetValueOrDefault(true)) { if (sessionExpired.GetValueOrDefault(true)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlHeadWithSession(host, request, referer, requestOptions, true, --maxTries).ConfigureAwait(false); return await UrlHeadWithSession(host, request, headers, referer, requestOptions, true, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -694,7 +694,7 @@ namespace ArchiSteamFarm {
} }
} }
WebBrowser.BasicResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlHead(host + request, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.BasicResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlHead(host + request, headers, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) { if (response == null) {
return false; return false;
@ -702,7 +702,7 @@ namespace ArchiSteamFarm {
if (IsSessionExpiredUri(response.FinalUri)) { if (IsSessionExpiredUri(response.FinalUri)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlHeadWithSession(host, request, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlHeadWithSession(host, request, headers, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -715,14 +715,14 @@ namespace ArchiSteamFarm {
if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) { if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri))); Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri)));
return await UrlHeadWithSession(host, request, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlHeadWithSession(host, request, headers, referer, requestOptions, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
return true; return true;
} }
[PublicAPI] [PublicAPI]
public async Task<WebBrowser.HtmlDocumentResponse?> UrlPostToHtmlDocumentWithSession(string host, string request, IDictionary<string, string>? data = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, ESession session = ESession.Lowercase, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) { public async Task<WebBrowser.HtmlDocumentResponse?> UrlPostToHtmlDocumentWithSession(string host, string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, IDictionary<string, string>? data = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, ESession session = ESession.Lowercase, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) {
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request) || !Enum.IsDefined(typeof(ESession), session)) { if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request) || !Enum.IsDefined(typeof(ESession), session)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(request) + " || " + nameof(session)); throw new ArgumentNullException(nameof(host) + " || " + nameof(request) + " || " + nameof(session));
} }
@ -740,7 +740,7 @@ namespace ArchiSteamFarm {
if (sessionExpired.GetValueOrDefault(true)) { if (sessionExpired.GetValueOrDefault(true)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlPostToHtmlDocumentWithSession(host, request, data, referer, requestOptions, session, true, --maxTries).ConfigureAwait(false); return await UrlPostToHtmlDocumentWithSession(host, request, headers, data, referer, requestOptions, session, true, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -792,7 +792,7 @@ namespace ArchiSteamFarm {
} }
} }
WebBrowser.HtmlDocumentResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToHtmlDocument(host + request, data, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.HtmlDocumentResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToHtmlDocument(host + request, headers, data, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) { if (response == null) {
return null; return null;
@ -800,7 +800,7 @@ namespace ArchiSteamFarm {
if (IsSessionExpiredUri(response.FinalUri)) { if (IsSessionExpiredUri(response.FinalUri)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlPostToHtmlDocumentWithSession(host, request, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlPostToHtmlDocumentWithSession(host, request, headers, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -813,14 +813,14 @@ namespace ArchiSteamFarm {
if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) { if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri))); Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri)));
return await UrlPostToHtmlDocumentWithSession(host, request, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlPostToHtmlDocumentWithSession(host, request, headers, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
return response; return response;
} }
[PublicAPI] [PublicAPI]
public async Task<WebBrowser.ObjectResponse<T>?> UrlPostToJsonObjectWithSession<T>(string host, string request, IDictionary<string, string>? data = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, ESession session = ESession.Lowercase, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) where T : class { public async Task<WebBrowser.ObjectResponse<T>?> UrlPostToJsonObjectWithSession<T>(string host, string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, IDictionary<string, string>? data = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, ESession session = ESession.Lowercase, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) where T : class {
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request) || !Enum.IsDefined(typeof(ESession), session)) { if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request) || !Enum.IsDefined(typeof(ESession), session)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(request) + " || " + nameof(session)); throw new ArgumentNullException(nameof(host) + " || " + nameof(request) + " || " + nameof(session));
} }
@ -838,7 +838,7 @@ namespace ArchiSteamFarm {
if (sessionExpired.GetValueOrDefault(true)) { if (sessionExpired.GetValueOrDefault(true)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlPostToJsonObjectWithSession<T>(host, request, data, referer, requestOptions, session, true, --maxTries).ConfigureAwait(false); return await UrlPostToJsonObjectWithSession<T>(host, request, headers, data, referer, requestOptions, session, true, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -890,7 +890,7 @@ namespace ArchiSteamFarm {
} }
} }
WebBrowser.ObjectResponse<T>? response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToJsonObject<T, IDictionary<string, string>>(host + request, data, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.ObjectResponse<T>? response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToJsonObject<T, IDictionary<string, string>>(host + request, headers, data, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) { if (response == null) {
return null; return null;
@ -898,7 +898,7 @@ namespace ArchiSteamFarm {
if (IsSessionExpiredUri(response.FinalUri)) { if (IsSessionExpiredUri(response.FinalUri)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlPostToJsonObjectWithSession<T>(host, request, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlPostToJsonObjectWithSession<T>(host, request, headers, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -911,14 +911,14 @@ namespace ArchiSteamFarm {
if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) { if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri))); Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri)));
return await UrlPostToJsonObjectWithSession<T>(host, request, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlPostToJsonObjectWithSession<T>(host, request, headers, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
return response; return response;
} }
[PublicAPI] [PublicAPI]
public async Task<WebBrowser.ObjectResponse<T>?> UrlPostToJsonObjectWithSession<T>(string host, string request, ICollection<KeyValuePair<string, string>>? data = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, ESession session = ESession.Lowercase, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) where T : class { public async Task<WebBrowser.ObjectResponse<T>?> UrlPostToJsonObjectWithSession<T>(string host, string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, ICollection<KeyValuePair<string, string>>? data = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, ESession session = ESession.Lowercase, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) where T : class {
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request) || !Enum.IsDefined(typeof(ESession), session)) { if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request) || !Enum.IsDefined(typeof(ESession), session)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(request) + " || " + nameof(session)); throw new ArgumentNullException(nameof(host) + " || " + nameof(request) + " || " + nameof(session));
} }
@ -936,7 +936,7 @@ namespace ArchiSteamFarm {
if (sessionExpired.GetValueOrDefault(true)) { if (sessionExpired.GetValueOrDefault(true)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlPostToJsonObjectWithSession<T>(host, request, data, referer, requestOptions, session, true, --maxTries).ConfigureAwait(false); return await UrlPostToJsonObjectWithSession<T>(host, request, headers, data, referer, requestOptions, session, true, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -991,7 +991,7 @@ namespace ArchiSteamFarm {
} }
} }
WebBrowser.ObjectResponse<T>? response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToJsonObject<T, ICollection<KeyValuePair<string, string>>>(host + request, data, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.ObjectResponse<T>? response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToJsonObject<T, ICollection<KeyValuePair<string, string>>>(host + request, headers, data, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) { if (response == null) {
return null; return null;
@ -999,7 +999,7 @@ namespace ArchiSteamFarm {
if (IsSessionExpiredUri(response.FinalUri)) { if (IsSessionExpiredUri(response.FinalUri)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlPostToJsonObjectWithSession<T>(host, request, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlPostToJsonObjectWithSession<T>(host, request, headers, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -1012,14 +1012,14 @@ namespace ArchiSteamFarm {
if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) { if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri))); Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri)));
return await UrlPostToJsonObjectWithSession<T>(host, request, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlPostToJsonObjectWithSession<T>(host, request, headers, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
return response; return response;
} }
[PublicAPI] [PublicAPI]
public async Task<bool> UrlPostWithSession(string host, string request, IDictionary<string, string>? data = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, ESession session = ESession.Lowercase, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) { public async Task<bool> UrlPostWithSession(string host, string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, IDictionary<string, string>? data = null, string? referer = null, WebBrowser.ERequestOptions requestOptions = WebBrowser.ERequestOptions.None, ESession session = ESession.Lowercase, bool checkSessionPreemptively = true, byte maxTries = WebBrowser.MaxTries) {
if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request) || !Enum.IsDefined(typeof(ESession), session)) { if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(request) || !Enum.IsDefined(typeof(ESession), session)) {
throw new ArgumentNullException(nameof(host) + " || " + nameof(request) + " || " + nameof(session)); throw new ArgumentNullException(nameof(host) + " || " + nameof(request) + " || " + nameof(session));
} }
@ -1037,7 +1037,7 @@ namespace ArchiSteamFarm {
if (sessionExpired.GetValueOrDefault(true)) { if (sessionExpired.GetValueOrDefault(true)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlPostWithSession(host, request, data, referer, requestOptions, session, true, --maxTries).ConfigureAwait(false); return await UrlPostWithSession(host, request, headers, data, referer, requestOptions, session, true, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -1089,7 +1089,7 @@ namespace ArchiSteamFarm {
} }
} }
WebBrowser.BasicResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlPost(host + request, data, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.BasicResponse? response = await WebLimitRequest(host, async () => await WebBrowser.UrlPost(host + request, headers, data, referer, requestOptions).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) { if (response == null) {
return false; return false;
@ -1097,7 +1097,7 @@ namespace ArchiSteamFarm {
if (IsSessionExpiredUri(response.FinalUri)) { if (IsSessionExpiredUri(response.FinalUri)) {
if (await RefreshSession().ConfigureAwait(false)) { if (await RefreshSession().ConfigureAwait(false)) {
return await UrlPostWithSession(host, request, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlPostWithSession(host, request, headers, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
@ -1110,7 +1110,7 @@ namespace ArchiSteamFarm {
if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) { if (await IsProfileUri(response.FinalUri).ConfigureAwait(false)) {
Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri))); Bot.ArchiLogger.LogGenericDebug(string.Format(Strings.WarningWorkaroundTriggered, nameof(IsProfileUri)));
return await UrlPostWithSession(host, request, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false); return await UrlPostWithSession(host, request, headers, data, referer, requestOptions, session, checkSessionPreemptively, --maxTries).ConfigureAwait(false);
} }
return true; return true;
@ -1173,7 +1173,7 @@ namespace ArchiSteamFarm {
{ "giftcardid", giftCardID.ToString() } { "giftcardid", giftCardID.ToString() }
}; };
WebBrowser.ObjectResponse<Steam.EResultResponse>? response = await UrlPostToJsonObjectWithSession<Steam.EResultResponse>(SteamStoreURL, request, data).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.EResultResponse>? response = await UrlPostToJsonObjectWithSession<Steam.EResultResponse>(SteamStoreURL, request, data: data).ConfigureAwait(false);
if (response?.Content == null) { if (response?.Content == null) {
return false; return false;
@ -1210,7 +1210,7 @@ namespace ArchiSteamFarm {
{ "tradeofferid", tradeID.ToString() } { "tradeofferid", tradeID.ToString() }
}; };
WebBrowser.ObjectResponse<Steam.TradeOfferAcceptResponse>? response = await UrlPostToJsonObjectWithSession<Steam.TradeOfferAcceptResponse>(SteamCommunityURL, request, data, referer, WebBrowser.ERequestOptions.ReturnServerErrors).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.TradeOfferAcceptResponse>? response = await UrlPostToJsonObjectWithSession<Steam.TradeOfferAcceptResponse>(SteamCommunityURL, request, data: data, referer: referer, requestOptions: WebBrowser.ERequestOptions.ReturnServerErrors).ConfigureAwait(false);
if (response == null) { if (response == null) {
return (false, false); return (false, false);
@ -1244,7 +1244,7 @@ namespace ArchiSteamFarm {
{ "subid", subID.ToString() } { "subid", subID.ToString() }
}; };
using WebBrowser.HtmlDocumentResponse? response = await UrlPostToHtmlDocumentWithSession(SteamStoreURL, request, data).ConfigureAwait(false); using WebBrowser.HtmlDocumentResponse? response = await UrlPostToHtmlDocumentWithSession(SteamStoreURL, request, data: data).ConfigureAwait(false);
return response?.Content?.SelectSingleNode("//div[@class='add_free_content_success_area']") != null; return response?.Content?.SelectSingleNode("//div[@class='add_free_content_success_area']") != null;
} }
@ -1270,7 +1270,7 @@ namespace ArchiSteamFarm {
{ "Privacy", JsonConvert.SerializeObject(userPrivacy.Settings) } { "Privacy", JsonConvert.SerializeObject(userPrivacy.Settings) }
}; };
WebBrowser.ObjectResponse<Steam.EResultResponse>? response = await UrlPostToJsonObjectWithSession<Steam.EResultResponse>(SteamCommunityURL, request, data).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.EResultResponse>? response = await UrlPostToJsonObjectWithSession<Steam.EResultResponse>(SteamCommunityURL, request, data: data).ConfigureAwait(false);
if (response?.Content == null) { if (response?.Content == null) {
return false; return false;
@ -1295,7 +1295,7 @@ namespace ArchiSteamFarm {
// Extra entry for sessionID // Extra entry for sessionID
Dictionary<string, string> data = new Dictionary<string, string>(2, StringComparer.Ordinal) { { "appid_to_clear_from_queue", appID.ToString() } }; Dictionary<string, string> data = new Dictionary<string, string>(2, StringComparer.Ordinal) { { "appid_to_clear_from_queue", appID.ToString() } };
return await UrlPostWithSession(SteamStoreURL, request, data).ConfigureAwait(false); return await UrlPostWithSession(SteamStoreURL, request, data: data).ConfigureAwait(false);
} }
internal async Task<bool> DeclineTradeOffer(ulong tradeID) { internal async Task<bool> DeclineTradeOffer(ulong tradeID) {
@ -1352,7 +1352,7 @@ namespace ArchiSteamFarm {
// Extra entry for sessionID // Extra entry for sessionID
Dictionary<string, string> data = new Dictionary<string, string>(2, StringComparer.Ordinal) { { "queuetype", "0" } }; Dictionary<string, string> data = new Dictionary<string, string>(2, StringComparer.Ordinal) { { "queuetype", "0" } };
WebBrowser.ObjectResponse<Steam.NewDiscoveryQueueResponse>? response = await UrlPostToJsonObjectWithSession<Steam.NewDiscoveryQueueResponse>(SteamStoreURL, request, data).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.NewDiscoveryQueueResponse>? response = await UrlPostToJsonObjectWithSession<Steam.NewDiscoveryQueueResponse>(SteamStoreURL, request, data: data).ConfigureAwait(false);
return response?.Content?.Queue; return response?.Content?.Queue;
} }
@ -1928,7 +1928,7 @@ namespace ArchiSteamFarm {
data.Add(new KeyValuePair<string, string>("ck[]", confirmation.Key.ToString())); data.Add(new KeyValuePair<string, string>("ck[]", confirmation.Key.ToString()));
} }
WebBrowser.ObjectResponse<Steam.BooleanResponse>? response = await UrlPostToJsonObjectWithSession<Steam.BooleanResponse>(SteamCommunityURL, request, data).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.BooleanResponse>? response = await UrlPostToJsonObjectWithSession<Steam.BooleanResponse>(SteamCommunityURL, request, data: data).ConfigureAwait(false);
return response?.Content?.Success; return response?.Content?.Success;
} }
@ -2063,7 +2063,7 @@ namespace ArchiSteamFarm {
// Extra entry for sessionID // Extra entry for sessionID
Dictionary<string, string> data = new Dictionary<string, string>(2, StringComparer.Ordinal) { { "action", "join" } }; Dictionary<string, string> data = new Dictionary<string, string>(2, StringComparer.Ordinal) { { "action", "join" } };
return await UrlPostWithSession(SteamCommunityURL, request, data, session: ESession.CamelCase).ConfigureAwait(false); return await UrlPostWithSession(SteamCommunityURL, request, data: data, session: ESession.CamelCase).ConfigureAwait(false);
} }
internal async Task MarkInventory() { internal async Task MarkInventory() {
@ -2136,7 +2136,7 @@ namespace ArchiSteamFarm {
// Extra entry for sessionID // Extra entry for sessionID
Dictionary<string, string> data = new Dictionary<string, string>(2, StringComparer.Ordinal) { { "wallet_code", key } }; Dictionary<string, string> data = new Dictionary<string, string>(2, StringComparer.Ordinal) { { "wallet_code", key } };
WebBrowser.ObjectResponse<Steam.RedeemWalletResponse>? responseValidateCode = await UrlPostToJsonObjectWithSession<Steam.RedeemWalletResponse>(SteamStoreURL, requestValidateCode, data).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.RedeemWalletResponse>? responseValidateCode = await UrlPostToJsonObjectWithSession<Steam.RedeemWalletResponse>(SteamStoreURL, requestValidateCode, data: data).ConfigureAwait(false);
if (responseValidateCode?.Content == null) { if (responseValidateCode?.Content == null) {
return null; return null;
@ -2155,7 +2155,7 @@ namespace ArchiSteamFarm {
if (responseValidateCode.Content.WalletCurrencyCode != responseValidateCode.Content.KeyDetails.CurrencyCode) { if (responseValidateCode.Content.WalletCurrencyCode != responseValidateCode.Content.KeyDetails.CurrencyCode) {
const string requestCheckFunds = "/account/createwalletandcheckfunds"; const string requestCheckFunds = "/account/createwalletandcheckfunds";
WebBrowser.ObjectResponse<Steam.EResultResponse>? responseCheckFunds = await UrlPostToJsonObjectWithSession<Steam.EResultResponse>(SteamStoreURL, requestCheckFunds, data).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.EResultResponse>? responseCheckFunds = await UrlPostToJsonObjectWithSession<Steam.EResultResponse>(SteamStoreURL, requestCheckFunds, data: data).ConfigureAwait(false);
if (responseCheckFunds?.Content == null) { if (responseCheckFunds?.Content == null) {
return null; return null;
@ -2168,7 +2168,7 @@ namespace ArchiSteamFarm {
const string requestConfirmRedeem = "/account/confirmredeemwalletcode"; const string requestConfirmRedeem = "/account/confirmredeemwalletcode";
WebBrowser.ObjectResponse<Steam.RedeemWalletResponse>? responseConfirmRedeem = await UrlPostToJsonObjectWithSession<Steam.RedeemWalletResponse>(SteamStoreURL, requestConfirmRedeem, data).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.RedeemWalletResponse>? responseConfirmRedeem = await UrlPostToJsonObjectWithSession<Steam.RedeemWalletResponse>(SteamStoreURL, requestConfirmRedeem, data: data).ConfigureAwait(false);
if (responseConfirmRedeem?.Content == null) { if (responseConfirmRedeem?.Content == null) {
return null; return null;
@ -2199,7 +2199,7 @@ namespace ArchiSteamFarm {
{ "communityitemid", itemID.ToString() } { "communityitemid", itemID.ToString() }
}; };
WebBrowser.ObjectResponse<Steam.EResultResponse>? response = await UrlPostToJsonObjectWithSession<Steam.EResultResponse>(SteamCommunityURL, request, data).ConfigureAwait(false); WebBrowser.ObjectResponse<Steam.EResultResponse>? response = await UrlPostToJsonObjectWithSession<Steam.EResultResponse>(SteamCommunityURL, request, data: data).ConfigureAwait(false);
return response?.Content?.Result == EResult.OK; return response?.Content?.Result == EResult.OK;
} }
@ -2464,7 +2464,7 @@ namespace ArchiSteamFarm {
{ "Submit", "Register" } { "Submit", "Register" }
}; };
return await UrlPostWithSession(SteamCommunityURL, request, data).ConfigureAwait(false); return await UrlPostWithSession(SteamCommunityURL, request, data: data).ConfigureAwait(false);
} }
private async Task<(bool Success, string? Result)> ResolveApiKey() { private async Task<(bool Success, string? Result)> ResolveApiKey() {
@ -2565,7 +2565,7 @@ namespace ArchiSteamFarm {
}; };
// This request doesn't go through UrlPostRetryWithSession as we have no access to session refresh capability (this is in fact session initialization) // This request doesn't go through UrlPostRetryWithSession as we have no access to session refresh capability (this is in fact session initialization)
WebBrowser.BasicResponse? response = await WebLimitRequest(serviceURL, async () => await WebBrowser.UrlPost(serviceURL + request, data, serviceURL).ConfigureAwait(false)).ConfigureAwait(false); WebBrowser.BasicResponse? response = await WebLimitRequest(serviceURL, async () => await WebBrowser.UrlPost(serviceURL + request, data: data, referer: serviceURL).ConfigureAwait(false)).ConfigureAwait(false);
if ((response == null) || IsSessionExpiredUri(response.FinalUri)) { if ((response == null) || IsSessionExpiredUri(response.FinalUri)) {
// There is no session refresh capability at this stage // There is no session refresh capability at this stage

View file

@ -102,7 +102,7 @@ namespace ArchiSteamFarm {
{ "SteamID", Bot.SteamID.ToString() } { "SteamID", Bot.SteamID.ToString() }
}; };
WebBrowser.BasicResponse? response = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false); WebBrowser.BasicResponse? response = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data: data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
if (response == null) { if (response == null) {
return; return;
@ -218,7 +218,7 @@ namespace ArchiSteamFarm {
{ "TradeToken", tradeToken! } { "TradeToken", tradeToken! }
}; };
WebBrowser.BasicResponse? response = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false); WebBrowser.BasicResponse? response = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data: data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
if (response == null) { if (response == null) {
return; return;

View file

@ -61,6 +61,21 @@ namespace ArchiSteamFarm {
return args[^1]; return args[^1];
} }
[PublicAPI]
public static string? GetCookieValue(this CookieContainer cookieContainer, string url, string name) {
if ((cookieContainer == null) || string.IsNullOrEmpty(url) || string.IsNullOrEmpty(name)) {
throw new ArgumentNullException(nameof(cookieContainer) + " || " + nameof(url) + " || " + nameof(name));
}
CookieCollection cookies = cookieContainer.GetCookies(new Uri(url));
#if NETFRAMEWORK
return cookies.Count > 0 ? (from Cookie cookie in cookies where cookie.Name == name select cookie.Value).FirstOrDefault() : null;
#else
return cookies.Count > 0 ? cookies.FirstOrDefault(cookie => cookie.Name == name)?.Value : null;
#endif
}
[PublicAPI] [PublicAPI]
public static uint GetUnixTime() => (uint) DateTimeOffset.UtcNow.ToUnixTimeSeconds(); public static uint GetUnixTime() => (uint) DateTimeOffset.UtcNow.ToUnixTimeSeconds();
@ -265,16 +280,6 @@ namespace ArchiSteamFarm {
} }
} }
internal static string? GetCookieValue(this CookieContainer cookieContainer, string url, string name) {
if ((cookieContainer == null) || string.IsNullOrEmpty(url) || string.IsNullOrEmpty(name)) {
throw new ArgumentNullException(nameof(cookieContainer) + " || " + nameof(url) + " || " + nameof(name));
}
CookieCollection cookies = cookieContainer.GetCookies(new Uri(url));
return cookies.Count > 0 ? (from Cookie cookie in cookies where cookie.Name.Equals(name) select cookie.Value).FirstOrDefault() : null;
}
internal static bool RelativeDirectoryStartsWith(string directory, params string[] prefixes) { internal static bool RelativeDirectoryStartsWith(string directory, params string[] prefixes) {
if (string.IsNullOrEmpty(directory) || (prefixes == null) || (prefixes.Length == 0)) { if (string.IsNullOrEmpty(directory) || (prefixes == null) || (prefixes.Length == 0)) {
throw new ArgumentNullException(nameof(directory) + " || " + nameof(prefixes)); throw new ArgumentNullException(nameof(directory) + " || " + nameof(prefixes));

View file

@ -46,9 +46,10 @@ namespace ArchiSteamFarm {
private const byte MaxIdleTime = 15; // Defines in seconds, how long socket is allowed to stay in CLOSE_WAIT state after there are no connections to it private const byte MaxIdleTime = 15; // Defines in seconds, how long socket is allowed to stay in CLOSE_WAIT state after there are no connections to it
[PublicAPI] [PublicAPI]
public TimeSpan Timeout => HttpClient.Timeout; public readonly CookieContainer CookieContainer = new CookieContainer();
internal readonly CookieContainer CookieContainer = new CookieContainer(); [PublicAPI]
public TimeSpan Timeout => HttpClient.Timeout;
private readonly ArchiLogger ArchiLogger; private readonly ArchiLogger ArchiLogger;
private readonly HttpClient HttpClient; private readonly HttpClient HttpClient;
@ -107,7 +108,7 @@ namespace ArchiSteamFarm {
} }
[PublicAPI] [PublicAPI]
public async Task<HtmlDocumentResponse?> UrlGetToHtmlDocument(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) { public async Task<HtmlDocumentResponse?> UrlGetToHtmlDocument(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -115,7 +116,7 @@ namespace ArchiSteamFarm {
HtmlDocumentResponse? result = null; HtmlDocumentResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
await using StreamResponse? response = await UrlGetToStream(request, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false); await using StreamResponse? response = await UrlGetToStream(request, headers, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
@ -157,7 +158,7 @@ namespace ArchiSteamFarm {
} }
[PublicAPI] [PublicAPI]
public async Task<ObjectResponse<T>?> UrlGetToJsonObject<T>(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class { public async Task<ObjectResponse<T>?> UrlGetToJsonObject<T>(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -165,7 +166,7 @@ namespace ArchiSteamFarm {
ObjectResponse<T>? result = null; ObjectResponse<T>? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
await using StreamResponse? response = await UrlGetToStream(request, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false); await using StreamResponse? response = await UrlGetToStream(request, headers, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
@ -219,7 +220,7 @@ namespace ArchiSteamFarm {
} }
[PublicAPI] [PublicAPI]
public async Task<XmlDocumentResponse?> UrlGetToXmlDocument(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) { public async Task<XmlDocumentResponse?> UrlGetToXmlDocument(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -227,7 +228,7 @@ namespace ArchiSteamFarm {
XmlDocumentResponse? result = null; XmlDocumentResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
await using StreamResponse? response = await UrlGetToStream(request, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false); await using StreamResponse? response = await UrlGetToStream(request, headers, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
@ -271,7 +272,7 @@ namespace ArchiSteamFarm {
} }
[PublicAPI] [PublicAPI]
public async Task<BasicResponse?> UrlHead(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) { public async Task<BasicResponse?> UrlHead(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -279,7 +280,7 @@ namespace ArchiSteamFarm {
BasicResponse? result = null; BasicResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
using HttpResponseMessage? response = await InternalHead(request, referer).ConfigureAwait(false); using HttpResponseMessage? response = await InternalHead(request, headers, referer).ConfigureAwait(false);
if (response == null) { if (response == null) {
continue; continue;
@ -313,7 +314,7 @@ namespace ArchiSteamFarm {
} }
[PublicAPI] [PublicAPI]
public async Task<BasicResponse?> UrlPost<T>(string request, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class { public async Task<BasicResponse?> UrlPost<T>(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -321,7 +322,7 @@ namespace ArchiSteamFarm {
BasicResponse? result = null; BasicResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
using HttpResponseMessage? response = await InternalPost(request, data, referer).ConfigureAwait(false); using HttpResponseMessage? response = await InternalPost(request, headers, data, referer).ConfigureAwait(false);
if (response == null) { if (response == null) {
continue; continue;
@ -355,7 +356,7 @@ namespace ArchiSteamFarm {
} }
[PublicAPI] [PublicAPI]
public async Task<HtmlDocumentResponse?> UrlPostToHtmlDocument<T>(string request, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class { public async Task<HtmlDocumentResponse?> UrlPostToHtmlDocument<T>(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -363,7 +364,7 @@ namespace ArchiSteamFarm {
HtmlDocumentResponse? result = null; HtmlDocumentResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
await using StreamResponse? response = await UrlPostToStream(request, data, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false); await using StreamResponse? response = await UrlPostToStream(request, headers, data, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
@ -405,7 +406,7 @@ namespace ArchiSteamFarm {
} }
[PublicAPI] [PublicAPI]
public async Task<ObjectResponse<TResult>?> UrlPostToJsonObject<TResult, TData>(string request, TData? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where TResult : class where TData : class { public async Task<ObjectResponse<TResult>?> UrlPostToJsonObject<TResult, TData>(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, TData? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where TResult : class where TData : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -413,7 +414,7 @@ namespace ArchiSteamFarm {
ObjectResponse<TResult>? result = null; ObjectResponse<TResult>? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
await using StreamResponse? response = await UrlPostToStream(request, data, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false); await using StreamResponse? response = await UrlPostToStream(request, headers, data, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
@ -482,7 +483,7 @@ namespace ArchiSteamFarm {
} }
} }
internal async Task<BinaryResponse?> UrlGetToBinary(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries, IProgress<byte>? progressReporter = null) { internal async Task<BinaryResponse?> UrlGetToBinary(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries, IProgress<byte>? progressReporter = null) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -490,7 +491,7 @@ namespace ArchiSteamFarm {
BinaryResponse? result = null; BinaryResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
await using StreamResponse? response = await UrlGetToStream(request, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false); await using StreamResponse? response = await UrlGetToStream(request, headers, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
@ -568,7 +569,7 @@ namespace ArchiSteamFarm {
return result; return result;
} }
internal async Task<StringResponse?> UrlGetToString(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) { internal async Task<StringResponse?> UrlGetToString(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -576,7 +577,7 @@ namespace ArchiSteamFarm {
StringResponse? result = null; StringResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
using HttpResponseMessage? response = await InternalGet(request, referer).ConfigureAwait(false); using HttpResponseMessage? response = await InternalGet(request, headers, referer).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
@ -609,31 +610,31 @@ namespace ArchiSteamFarm {
return result; return result;
} }
private async Task<HttpResponseMessage?> InternalGet(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) { private async Task<HttpResponseMessage?> InternalGet(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) {
if (string.IsNullOrEmpty(request)) { if (string.IsNullOrEmpty(request)) {
throw new ArgumentNullException(nameof(request)); throw new ArgumentNullException(nameof(request));
} }
return await InternalRequest<object>(new Uri(request), HttpMethod.Get, null, referer, requestOptions, httpCompletionOption).ConfigureAwait(false); return await InternalRequest<object>(new Uri(request), HttpMethod.Get, headers, null, referer, requestOptions, httpCompletionOption).ConfigureAwait(false);
} }
private async Task<HttpResponseMessage?> InternalHead(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) { private async Task<HttpResponseMessage?> InternalHead(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) {
if (string.IsNullOrEmpty(request)) { if (string.IsNullOrEmpty(request)) {
throw new ArgumentNullException(nameof(request)); throw new ArgumentNullException(nameof(request));
} }
return await InternalRequest<object>(new Uri(request), HttpMethod.Head, null, referer, requestOptions, httpCompletionOption).ConfigureAwait(false); return await InternalRequest<object>(new Uri(request), HttpMethod.Head, headers, null, referer, requestOptions, httpCompletionOption).ConfigureAwait(false);
} }
private async Task<HttpResponseMessage?> InternalPost<T>(string request, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) where T : class { private async Task<HttpResponseMessage?> InternalPost<T>(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) where T : class {
if (string.IsNullOrEmpty(request)) { if (string.IsNullOrEmpty(request)) {
throw new ArgumentNullException(nameof(request)); throw new ArgumentNullException(nameof(request));
} }
return await InternalRequest(new Uri(request), HttpMethod.Post, data, referer, requestOptions, httpCompletionOption).ConfigureAwait(false); return await InternalRequest(new Uri(request), HttpMethod.Post, headers, data, referer, requestOptions, httpCompletionOption).ConfigureAwait(false);
} }
private async Task<HttpResponseMessage?> InternalRequest<T>(Uri requestUri, HttpMethod httpMethod, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead, byte maxRedirections = MaxTries) where T : class { private async Task<HttpResponseMessage?> InternalRequest<T>(Uri requestUri, HttpMethod httpMethod, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead, byte maxRedirections = MaxTries) where T : class {
if ((requestUri == null) || (httpMethod == null)) { if ((requestUri == null) || (httpMethod == null)) {
throw new ArgumentNullException(nameof(requestUri) + " || " + nameof(httpMethod)); throw new ArgumentNullException(nameof(requestUri) + " || " + nameof(httpMethod));
} }
@ -645,6 +646,12 @@ namespace ArchiSteamFarm {
request.Version = HttpClient.DefaultRequestVersion; request.Version = HttpClient.DefaultRequestVersion;
#endif #endif
if (headers != null) {
foreach ((string header, string value) in headers) {
request.Headers.Add(header, value);
}
}
if (data != null) { if (data != null) {
switch (data) { switch (data) {
case HttpContent content: case HttpContent content:
@ -751,7 +758,7 @@ namespace ArchiSteamFarm {
redirectUri = new UriBuilder(redirectUri) { Fragment = requestUri.Fragment }.Uri; redirectUri = new UriBuilder(redirectUri) { Fragment = requestUri.Fragment }.Uri;
} }
return await InternalRequest(redirectUri, httpMethod, data, referer, requestOptions, httpCompletionOption, --maxRedirections).ConfigureAwait(false); return await InternalRequest(redirectUri, httpMethod, headers, data, referer, requestOptions, httpCompletionOption, --maxRedirections).ConfigureAwait(false);
} }
if (!Debugging.IsUserDebugging) { if (!Debugging.IsUserDebugging) {
@ -781,7 +788,7 @@ namespace ArchiSteamFarm {
} }
} }
private async Task<StreamResponse?> UrlGetToStream(string request, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) { private async Task<StreamResponse?> UrlGetToStream(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -789,7 +796,7 @@ namespace ArchiSteamFarm {
StreamResponse? result = null; StreamResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
HttpResponseMessage? response = await InternalGet(request, referer, requestOptions, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); HttpResponseMessage? response = await InternalGet(request, headers, referer, requestOptions, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
@ -822,7 +829,7 @@ namespace ArchiSteamFarm {
return result; return result;
} }
private async Task<StreamResponse?> UrlPostToStream<T>(string request, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class { private async Task<StreamResponse?> UrlPostToStream<T>(string request, IReadOnlyCollection<KeyValuePair<string, string>>? headers = null, T? data = null, string? referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) { if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries)); throw new ArgumentNullException(nameof(request) + " || " + nameof(maxTries));
} }
@ -830,7 +837,7 @@ namespace ArchiSteamFarm {
StreamResponse? result = null; StreamResponse? result = null;
for (byte i = 0; i < maxTries; i++) { for (byte i = 0; i < maxTries; i++) {
HttpResponseMessage? response = await InternalPost(request, data, referer, requestOptions, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); HttpResponseMessage? response = await InternalPost(request, headers, data, referer, requestOptions, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) { if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) { if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {