2017-11-18 17:27:06 +01:00
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
//
2018-01-01 02:56:53 +01:00
// Copyright 2015-2018 Łukasz "JustArchi" Domeradzki
2017-11-18 17:27:06 +01:00
// Contact: JustArchi@JustArchi.net
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2015-11-29 00:13:03 +01:00
2015-11-25 16:31:39 +01:00
using System ;
using System.Collections.Generic ;
2017-12-16 11:34:04 +01:00
using System.IO ;
2015-11-25 16:31:39 +01:00
using System.Net ;
using System.Net.Http ;
using System.Threading.Tasks ;
2016-03-15 04:20:28 +01:00
using System.Xml ;
2017-01-06 15:32:12 +01:00
using ArchiSteamFarm.Localization ;
2016-11-24 07:32:16 +01:00
using HtmlAgilityPack ;
using Newtonsoft.Json ;
2015-11-25 16:31:39 +01:00
namespace ArchiSteamFarm {
2017-08-04 19:26:37 +02:00
internal sealed class WebBrowser : IDisposable {
2017-07-09 09:09:46 +02:00
internal const byte MaxTries = 5 ; // Defines maximum number of recommended tries for a single request
2016-01-14 02:48:56 +01:00
2017-07-09 09:09:46 +02:00
private const byte ExtendedTimeoutMultiplier = 10 ; // Defines multiplier of timeout for WebBrowsers dealing with huge data (ASF update)
private const byte MaxConnections = 10 ; // Defines maximum number of connections per ServicePoint. Be careful, as it also defines maximum number of sockets in CLOSE_WAIT state
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
2016-03-15 05:15:22 +01:00
2016-04-12 16:58:45 +02:00
internal readonly CookieContainer CookieContainer = new CookieContainer ( ) ;
2016-03-06 23:28:56 +01:00
2017-09-09 20:24:57 +02:00
internal TimeSpan Timeout = > HttpClient . Timeout ;
2016-11-06 12:06:02 +01:00
private readonly ArchiLogger ArchiLogger ;
2016-04-12 16:58:45 +02:00
private readonly HttpClient HttpClient ;
2015-12-01 01:34:05 +01:00
2017-07-05 07:30:08 +02:00
internal WebBrowser ( ArchiLogger archiLogger , bool extendedTimeout = false ) {
2017-03-14 08:20:29 -03:00
ArchiLogger = archiLogger ? ? throw new ArgumentNullException ( nameof ( archiLogger ) ) ;
2016-11-24 07:32:16 +01:00
2016-11-24 07:46:37 +01:00
HttpClientHandler httpClientHandler = new HttpClientHandler {
2018-02-17 03:57:09 +01:00
AllowAutoRedirect = false , // This must be false if we want to handle custom redirection schemes such as "steammobile"
2016-11-24 07:46:37 +01:00
AutomaticDecompression = DecompressionMethods . Deflate | DecompressionMethods . GZip ,
2017-07-09 09:53:26 +02:00
CookieContainer = CookieContainer ,
2017-12-12 14:12:21 +01:00
MaxConnectionsPerServer = MaxConnections ,
UseProxy = false
2016-11-24 07:46:37 +01:00
} ;
2017-11-28 21:31:45 +01:00
HttpClient = new HttpClient ( httpClientHandler ) { Timeout = TimeSpan . FromSeconds ( extendedTimeout ? ExtendedTimeoutMultiplier * Program . GlobalConfig . ConnectionTimeout : Program . GlobalConfig . ConnectionTimeout ) } ;
2016-11-24 07:32:16 +01:00
// Most web services expect that UserAgent is set, so we declare it globally
2017-12-29 03:40:44 +01:00
HttpClient . DefaultRequestHeaders . UserAgent . ParseAdd ( SharedInfo . PublicIdentifier + "/" + SharedInfo . Version ) ;
2016-11-24 07:32:16 +01:00
}
2017-08-04 19:26:37 +02:00
public void Dispose ( ) = > HttpClient . Dispose ( ) ;
2016-04-12 16:58:45 +02:00
internal static void Init ( ) {
2016-01-14 20:37:01 +01:00
// Set max connection limit from default of 2 to desired value
ServicePointManager . DefaultConnectionLimit = MaxConnections ;
// Set max idle time from default of 100 seconds (100 * 1000) to desired value
2016-11-24 07:49:44 +01:00
ServicePointManager . MaxServicePointIdleTime = MaxIdleTime * 1000 ;
2015-12-13 15:25:00 +01:00
2016-01-14 20:37:01 +01:00
// Don't use Expect100Continue, we're sure about our POSTs, save some TCP packets
2015-12-13 15:25:00 +01:00
ServicePointManager . Expect100Continue = false ;
2015-11-25 16:31:39 +01:00
2017-06-26 03:36:51 +02:00
// Reuse ports if possible
ServicePointManager . ReusePort = true ;
2015-11-25 16:31:39 +01:00
}
2017-02-06 15:46:42 +01:00
internal static HtmlDocument StringToHtmlDocument ( string html ) {
2018-02-17 03:57:09 +01:00
if ( html = = null ) {
2017-02-06 15:46:42 +01:00
ASF . ArchiLogger . LogNullError ( nameof ( html ) ) ;
return null ;
}
HtmlDocument htmlDocument = new HtmlDocument ( ) ;
htmlDocument . LoadHtml ( html ) ;
return htmlDocument ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal async Task < BinaryResponse > UrlGetToBinaryWithProgressRetry ( string request , string referer = null ) {
2016-05-30 01:57:06 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2016-05-30 01:57:06 +02:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
BinaryResponse response = null ;
for ( byte i = 0 ; ( i < MaxTries ) & & ( response = = null ) ; i + + ) {
response = await UrlGetToBinaryWithProgress ( request , referer ) . ConfigureAwait ( false ) ;
2016-05-30 01:57:06 +02:00
}
2018-03-09 15:43:25 +01:00
if ( response = = null ) {
ArchiLogger . LogGenericWarning ( string . Format ( Strings . ErrorRequestFailedTooManyTimes , MaxTries ) ) ;
ArchiLogger . LogGenericDebug ( string . Format ( Strings . ErrorFailingRequest , request ) ) ;
return null ;
2016-05-30 01:57:06 +02:00
}
2018-03-09 15:43:25 +01:00
return response ;
2016-05-30 01:57:06 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal async Task < HtmlDocumentResponse > UrlGetToHtmlDocumentRetry ( string request , string referer = null ) {
2016-05-30 01:57:06 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2016-05-30 01:57:06 +02:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
StringResponse response = await UrlGetToStringRetry ( request , referer ) . ConfigureAwait ( false ) ;
return response ! = null ? new HtmlDocumentResponse ( response ) : null ;
2016-05-30 01:57:06 +02:00
}
2018-03-09 14:26:20 +01:00
internal async Task < ObjectResponse < T > > UrlGetToJsonObjectRetry < T > ( string request , string referer = null ) {
2016-05-30 01:57:06 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-05-30 01:57:06 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
StringResponse response = await UrlGetToStringRetry ( request , referer ) . ConfigureAwait ( false ) ;
2018-03-09 18:02:39 +01:00
if ( string . IsNullOrEmpty ( response ? . Content ) ) {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-05-30 01:57:06 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
T obj ;
2016-08-22 00:10:29 +02:00
try {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
obj = JsonConvert . DeserializeObject < T > ( response . Content ) ;
2016-08-22 00:10:29 +02:00
} catch ( JsonException e ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogGenericException ( e ) ;
2017-04-05 14:16:47 +02:00
if ( Debugging . IsUserDebugging ) {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
ArchiLogger . LogGenericDebug ( string . Format ( Strings . Content , response . Content ) ) ;
2017-04-05 14:16:47 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-04-12 07:40:02 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return new ObjectResponse < T > ( response , obj ) ;
2016-04-12 07:40:02 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal async Task < XmlResponse > UrlGetToXmlRetry ( string request , string referer = null ) {
2015-11-25 16:31:39 +01:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2016-05-30 01:57:06 +02:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
StringResponse response = await UrlGetToStringRetry ( request , referer ) . ConfigureAwait ( false ) ;
2016-05-30 01:57:06 +02:00
2018-03-09 18:02:39 +01:00
if ( string . IsNullOrEmpty ( response ? . Content ) ) {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-11-24 07:32:16 +01:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
XmlDocument xmlDocument = new XmlDocument ( ) ;
2016-11-24 07:32:16 +01:00
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
try {
xmlDocument . LoadXml ( response . Content ) ;
} catch ( XmlException e ) {
ArchiLogger . LogGenericException ( e ) ;
return null ;
2016-11-24 07:32:16 +01:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return new XmlResponse ( response , xmlDocument ) ;
2016-11-24 07:32:16 +01:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal async Task < BasicResponse > UrlHeadRetry ( string request , string referer = null ) {
2016-11-24 07:32:16 +01:00
if ( string . IsNullOrEmpty ( request ) ) {
ArchiLogger . LogNullError ( nameof ( request ) ) ;
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
BasicResponse response = null ;
for ( byte i = 0 ; ( i < MaxTries ) & & ( response = = null ) ; i + + ) {
response = await UrlHead ( request , referer ) . ConfigureAwait ( false ) ;
2016-11-24 07:32:16 +01:00
}
2018-03-09 15:43:25 +01:00
if ( response = = null ) {
ArchiLogger . LogGenericWarning ( string . Format ( Strings . ErrorRequestFailedTooManyTimes , MaxTries ) ) ;
ArchiLogger . LogGenericDebug ( string . Format ( Strings . ErrorFailingRequest , request ) ) ;
return null ;
2016-11-24 07:32:16 +01:00
}
2018-03-09 15:43:25 +01:00
return response ;
2016-11-24 07:32:16 +01:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal async Task < BasicResponse > UrlPost ( string request , IReadOnlyCollection < KeyValuePair < string , string > > data = null , string referer = null ) {
2016-12-04 01:07:37 +01:00
if ( string . IsNullOrEmpty ( request ) ) {
ArchiLogger . LogNullError ( nameof ( request ) ) ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-12-04 01:07:37 +01:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
using ( HttpResponseMessage response = await UrlPostToHttp ( request , data , referer ) . ConfigureAwait ( false ) ) {
return response ! = null ? new BasicResponse ( response ) : null ;
2016-12-04 01:07:37 +01:00
}
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal async Task < BasicResponse > UrlPostRetry ( string request , IReadOnlyCollection < KeyValuePair < string , string > > data = null , string referer = null ) {
2016-05-30 01:57:06 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-05-30 01:57:06 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
BasicResponse response = null ;
for ( byte i = 0 ; ( i < MaxTries ) & & ( response = = null ) ; i + + ) {
response = await UrlPost ( request , data , referer ) . ConfigureAwait ( false ) ;
2016-05-30 01:57:06 +02:00
}
2018-03-09 15:43:25 +01:00
if ( response = = null ) {
ArchiLogger . LogGenericWarning ( string . Format ( Strings . ErrorRequestFailedTooManyTimes , MaxTries ) ) ;
ArchiLogger . LogGenericDebug ( string . Format ( Strings . ErrorFailingRequest , request ) ) ;
return null ;
2016-05-30 01:57:06 +02:00
}
2018-03-09 15:43:25 +01:00
return response ;
2016-05-30 01:57:06 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal async Task < HtmlDocumentResponse > UrlPostToHtmlDocumentRetry ( string request , IReadOnlyCollection < KeyValuePair < string , string > > data = null , string referer = null ) {
2016-11-17 21:30:17 +01:00
if ( string . IsNullOrEmpty ( request ) ) {
ArchiLogger . LogNullError ( nameof ( request ) ) ;
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
StringResponse response = await UrlPostToStringRetry ( request , data , referer ) . ConfigureAwait ( false ) ;
return response ! = null ? new HtmlDocumentResponse ( response ) : null ;
2016-11-17 21:30:17 +01:00
}
2018-03-09 14:26:20 +01:00
internal async Task < ObjectResponse < T > > UrlPostToJsonObjectRetry < T > ( string request , IReadOnlyCollection < KeyValuePair < string , string > > data = null , string referer = null ) {
2016-07-16 21:03:39 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-07-16 21:03:39 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
StringResponse response = await UrlPostToStringRetry ( request , data , referer ) . ConfigureAwait ( false ) ;
2018-03-09 18:02:39 +01:00
if ( string . IsNullOrEmpty ( response ? . Content ) ) {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-07-16 21:03:39 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
T obj ;
2016-08-22 00:10:29 +02:00
try {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
obj = JsonConvert . DeserializeObject < T > ( response . Content ) ;
2016-08-22 00:10:29 +02:00
} catch ( JsonException e ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogGenericException ( e ) ;
2017-04-05 14:16:47 +02:00
if ( Debugging . IsUserDebugging ) {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
ArchiLogger . LogGenericDebug ( string . Format ( Strings . Content , response . Content ) ) ;
2017-04-05 14:16:47 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-07-16 21:03:39 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return new ObjectResponse < T > ( response , obj ) ;
2016-07-16 21:03:39 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < BinaryResponse > UrlGetToBinaryWithProgress ( string request , string referer = null ) {
2016-05-30 01:57:06 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2015-11-25 16:31:39 +01:00
return null ;
}
2017-12-16 11:34:04 +01:00
const byte printPercentage = 10 ;
2017-12-19 12:40:54 +01:00
const byte maxBatches = 99 / printPercentage ;
2017-12-16 11:34:04 +01:00
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
using ( HttpResponseMessage response = await UrlGetToHttp ( request , referer , HttpCompletionOption . ResponseHeadersRead ) . ConfigureAwait ( false ) ) {
if ( response = = null ) {
2016-04-14 22:23:37 +02:00
return null ;
}
2015-11-25 16:31:39 +01:00
2017-12-16 11:40:38 +01:00
ArchiLogger . LogGenericDebug ( "0%..." ) ;
2017-12-16 11:34:04 +01:00
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
uint contentLength = ( uint ) response . Content . Headers . ContentLength . GetValueOrDefault ( ) ;
2017-12-19 12:40:54 +01:00
using ( MemoryStream ms = new MemoryStream ( ( int ) contentLength ) ) {
2017-12-16 11:40:38 +01:00
try {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
using ( Stream contentStream = await response . Content . ReadAsStreamAsync ( ) . ConfigureAwait ( false ) ) {
2017-12-16 11:40:38 +01:00
byte batch = 0 ;
uint readThisBatch = 0 ;
byte [ ] buffer = new byte [ 8192 ] ; // This is HttpClient's buffer, using more doesn't make sense
2017-12-16 11:34:04 +01:00
2017-12-16 11:40:38 +01:00
while ( contentStream . CanRead ) {
int read = await contentStream . ReadAsync ( buffer , 0 , buffer . Length ) . ConfigureAwait ( false ) ;
if ( read = = 0 ) {
break ;
}
2017-12-16 11:34:04 +01:00
2017-12-16 11:40:38 +01:00
await ms . WriteAsync ( buffer , 0 , read ) . ConfigureAwait ( false ) ;
2017-12-16 11:34:04 +01:00
2017-12-19 12:40:54 +01:00
if ( ( contentLength = = 0 ) | | ( batch > = maxBatches ) ) {
2017-12-16 11:40:38 +01:00
continue ;
}
2017-12-16 11:34:04 +01:00
2017-12-16 11:40:38 +01:00
readThisBatch + = ( uint ) read ;
2017-12-16 11:34:04 +01:00
2017-12-16 11:40:38 +01:00
if ( readThisBatch < contentLength / printPercentage ) {
continue ;
}
2017-12-19 12:40:54 +01:00
readThisBatch - = contentLength / printPercentage ;
2017-12-16 11:40:38 +01:00
ArchiLogger . LogGenericDebug ( + + batch * printPercentage + "%..." ) ;
}
2017-12-16 11:34:04 +01:00
}
2017-12-16 11:40:38 +01:00
} catch ( Exception e ) {
ArchiLogger . LogGenericDebuggingException ( e ) ;
return null ;
2017-12-16 11:34:04 +01:00
}
2017-12-16 11:40:38 +01:00
ArchiLogger . LogGenericDebug ( "100%" ) ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return new BinaryResponse ( response , ms . ToArray ( ) ) ;
2017-12-16 11:34:04 +01:00
}
2015-11-25 16:31:39 +01:00
}
2016-04-12 07:40:02 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < HttpResponseMessage > UrlGetToHttp ( string request , string referer = null , HttpCompletionOption httpCompletionOptions = HttpCompletionOption . ResponseContentRead ) {
2016-04-12 07:40:02 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2015-11-25 16:31:39 +01:00
return null ;
}
2018-03-09 15:43:25 +01:00
return await UrlRequest ( new Uri ( request ) , HttpMethod . Get , null , referer , httpCompletionOptions ) . ConfigureAwait ( false ) ;
2015-11-25 16:31:39 +01:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < StringResponse > UrlGetToString ( string request , string referer = null ) {
2016-08-22 00:10:29 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2016-08-22 00:10:29 +02:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
using ( HttpResponseMessage response = await UrlGetToHttp ( request , referer ) . ConfigureAwait ( false ) ) {
return response ! = null ? new StringResponse ( response , await response . Content . ReadAsStringAsync ( ) . ConfigureAwait ( false ) ) : null ;
2016-08-22 00:10:29 +02:00
}
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < StringResponse > UrlGetToStringRetry ( string request , string referer = null ) {
2015-11-25 16:31:39 +01:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2015-11-25 16:31:39 +01:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
StringResponse response = null ;
2015-11-25 16:31:39 +01:00
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
for ( byte i = 0 ; ( i < MaxTries ) & & ( response = = null ) ; i + + ) {
response = await UrlGetToString ( request , referer ) . ConfigureAwait ( false ) ;
2016-05-30 01:57:06 +02:00
}
2018-03-09 15:43:25 +01:00
if ( response = = null ) {
ArchiLogger . LogGenericWarning ( string . Format ( Strings . ErrorRequestFailedTooManyTimes , MaxTries ) ) ;
ArchiLogger . LogGenericDebug ( string . Format ( Strings . ErrorFailingRequest , request ) ) ;
return null ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
}
2018-03-09 15:43:25 +01:00
return response ;
2016-05-30 01:57:06 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < BasicResponse > UrlHead ( string request , string referer = null ) {
2016-03-15 04:20:28 +01:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2016-03-15 04:20:28 +01:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
using ( HttpResponseMessage response = await UrlHeadToHttp ( request , referer ) . ConfigureAwait ( false ) ) {
return response ! = null ? new BasicResponse ( response ) : null ;
2016-03-15 04:20:28 +01:00
}
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < HttpResponseMessage > UrlHeadToHttp ( string request , string referer = null ) {
2016-04-29 16:37:42 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
return null ;
2016-05-30 01:57:06 +02:00
}
2018-03-09 15:43:25 +01:00
return await UrlRequest ( new Uri ( request ) , HttpMethod . Head , null , referer ) . ConfigureAwait ( false ) ;
2016-05-30 01:57:06 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < HttpResponseMessage > UrlPostToHttp ( string request , IReadOnlyCollection < KeyValuePair < string , string > > data = null , string referer = null ) {
2016-04-14 22:23:37 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2016-04-14 22:23:37 +02:00
return null ;
}
2018-03-09 15:43:25 +01:00
return await UrlRequest ( new Uri ( request ) , HttpMethod . Post , data , referer ) . ConfigureAwait ( false ) ;
2016-04-14 22:23:37 +02:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < StringResponse > UrlPostToString ( string request , IReadOnlyCollection < KeyValuePair < string , string > > data = null , string referer = null ) {
2016-07-16 21:03:39 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2016-07-16 21:03:39 +02:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
using ( HttpResponseMessage response = await UrlPostToHttp ( request , data , referer ) . ConfigureAwait ( false ) ) {
return response ! = null ? new StringResponse ( response , await response . Content . ReadAsStringAsync ( ) . ConfigureAwait ( false ) ) : null ;
2016-07-16 21:03:39 +02:00
}
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
private async Task < StringResponse > UrlPostToStringRetry ( string request , IReadOnlyCollection < KeyValuePair < string , string > > data = null , string referer = null ) {
2016-08-22 00:10:29 +02:00
if ( string . IsNullOrEmpty ( request ) ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogNullError ( nameof ( request ) ) ;
2016-08-22 00:10:29 +02:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
StringResponse response = null ;
for ( byte i = 0 ; ( i < MaxTries ) & & ( response = = null ) ; i + + ) {
response = await UrlPostToString ( request , data , referer ) . ConfigureAwait ( false ) ;
2016-08-22 00:10:29 +02:00
}
2018-03-09 15:43:25 +01:00
if ( response = = null ) {
ArchiLogger . LogGenericWarning ( string . Format ( Strings . ErrorRequestFailedTooManyTimes , MaxTries ) ) ;
ArchiLogger . LogGenericDebug ( string . Format ( Strings . ErrorFailingRequest , request ) ) ;
return null ;
2016-08-22 00:10:29 +02:00
}
2018-03-09 15:43:25 +01:00
return response ;
2016-08-22 00:10:29 +02:00
}
2017-12-16 11:34:04 +01:00
private async Task < HttpResponseMessage > UrlRequest ( Uri requestUri , HttpMethod httpMethod , IReadOnlyCollection < KeyValuePair < string , string > > data = null , string referer = null , HttpCompletionOption httpCompletionOption = HttpCompletionOption . ResponseContentRead , byte maxRedirections = MaxTries ) {
2017-06-26 04:02:11 +02:00
if ( ( requestUri = = null ) | | ( httpMethod = = null ) ) {
ArchiLogger . LogNullError ( nameof ( requestUri ) + " || " + nameof ( httpMethod ) ) ;
2015-11-25 16:31:39 +01:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
HttpResponseMessage response ;
using ( HttpRequestMessage request = new HttpRequestMessage ( httpMethod , requestUri ) ) {
2016-07-16 21:03:39 +02:00
if ( data ! = null ) {
2016-02-22 18:34:45 +01:00
try {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
request . Content = new FormUrlEncodedContent ( data ) ;
2016-02-22 18:34:45 +01:00
} catch ( UriFormatException e ) {
2016-11-06 12:06:02 +01:00
ArchiLogger . LogGenericException ( e ) ;
2016-02-22 18:34:45 +01:00
return null ;
}
}
2015-11-25 16:31:39 +01:00
2016-03-09 03:10:33 +01:00
if ( ! string . IsNullOrEmpty ( referer ) ) {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
request . Headers . Referrer = new Uri ( referer ) ;
2016-02-22 18:34:45 +01:00
}
2015-11-25 16:31:39 +01:00
2016-02-22 18:34:45 +01:00
try {
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
response = await HttpClient . SendAsync ( request , httpCompletionOption ) . ConfigureAwait ( false ) ;
2016-06-11 03:39:25 +02:00
} catch ( Exception e ) {
2017-11-26 19:08:48 +01:00
ArchiLogger . LogGenericDebuggingException ( e ) ;
2016-02-22 18:34:45 +01:00
return null ;
}
2015-11-25 16:31:39 +01:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
if ( response = = null ) {
2016-04-22 17:50:01 +02:00
return null ;
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
if ( response . IsSuccessStatusCode ) {
return response ;
2016-05-13 06:32:42 +02:00
}
2018-02-17 03:57:09 +01:00
// WARNING: We still have undisposed response by now, make sure to dispose it ASAP if we're not returning it!
2018-02-17 04:07:26 +01:00
if ( ( response . StatusCode > = HttpStatusCode . Ambiguous ) & & ( response . StatusCode < HttpStatusCode . BadRequest ) & & ( maxRedirections > 0 ) ) {
2018-02-17 03:57:09 +01:00
Uri redirectUri = response . Headers . Location ;
if ( redirectUri . IsAbsoluteUri ) {
switch ( redirectUri . Scheme ) {
case "http" :
case "https" :
break ;
case "steammobile" :
// Those redirections are invalid, but we're aware of that and we have extra logic for them
return response ;
default :
// We have no clue about those, but maybe HttpClient can handle them for us
ASF . ArchiLogger . LogGenericError ( string . Format ( Strings . WarningUnknownValuePleaseReport , nameof ( redirectUri . Scheme ) , redirectUri . Scheme ) ) ;
break ;
2017-06-26 04:02:11 +02:00
}
} else {
2018-02-17 03:57:09 +01:00
redirectUri = new Uri ( requestUri . GetLeftPart ( UriPartial . Authority ) + redirectUri ) ;
}
2017-06-26 04:02:11 +02:00
2018-02-17 03:57:09 +01:00
response . Dispose ( ) ;
return await UrlRequest ( redirectUri , httpMethod , data , referer , httpCompletionOption , - - maxRedirections ) . ConfigureAwait ( false ) ;
}
using ( response ) {
2018-03-09 15:43:25 +01:00
if ( Debugging . IsDebugBuild ) {
ArchiLogger . LogGenericDebug ( string . Format ( Strings . ErrorFailingRequest , requestUri ) ) ;
ArchiLogger . LogGenericDebug ( string . Format ( Strings . StatusCode , response . StatusCode ) ) ;
ArchiLogger . LogGenericDebug ( string . Format ( Strings . Content , await response . Content . ReadAsStringAsync ( ) . ConfigureAwait ( false ) ) ) ;
2017-06-26 04:02:11 +02:00
}
2015-11-25 16:31:39 +01:00
2018-02-17 03:57:09 +01:00
return null ;
}
2015-11-25 16:31:39 +01:00
}
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal class BasicResponse {
2018-02-17 03:57:09 +01:00
internal readonly Uri FinalUri ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
internal BasicResponse ( HttpResponseMessage httpResponseMessage ) {
if ( httpResponseMessage = = null ) {
throw new ArgumentNullException ( nameof ( httpResponseMessage ) ) ;
}
2018-02-17 03:57:09 +01:00
FinalUri = httpResponseMessage . Headers . Location ? ? httpResponseMessage . RequestMessage . RequestUri ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
}
internal BasicResponse ( BasicResponse basicResponse ) {
if ( basicResponse = = null ) {
throw new ArgumentNullException ( nameof ( basicResponse ) ) ;
}
2018-02-17 03:57:09 +01:00
FinalUri = basicResponse . FinalUri ;
Rewrite entire ASF HTTP stack
Previous implementation was quite naive and assumed a lot of non-guaranteed premises. Checking if our session is valid before doing each request is very stupid, but it was needed for multi-user sessions. Next, even if we checked that our session is valid (or revalidated it if needed), we then assumed it's valid for at least X seconds, which is once again entirely false. Moreover, on top of those two issues, refreshing our session could do absolutely nothing as there is no guarantee that once-refreshes session stays like that even for our very next request.
Get rid of all of this shit and rewrite it with proper mechanism. We're making a request, if that request results in redirection to session refresh, refresh session, then repeat the same request again. Add failsafes for infinite loops, make it enough thread-safe and optimized for concurrent usage.
This commit won't only improve previously half-valid implementation, but will also greatly optimize number of requests being sent, as we won't need to check our session before each request. The entire thing should work like that since beginning.
2018-02-16 15:49:18 +01:00
}
}
internal sealed class BinaryResponse : BasicResponse {
internal readonly byte [ ] Content ;
internal BinaryResponse ( HttpResponseMessage httpResponseMessage , byte [ ] content ) : base ( httpResponseMessage ) {
if ( ( httpResponseMessage = = null ) | | ( content = = null ) ) {
throw new ArgumentNullException ( nameof ( httpResponseMessage ) + " || " + nameof ( content ) ) ;
}
Content = content ;
}
}
internal sealed class HtmlDocumentResponse : BasicResponse {
internal readonly HtmlDocument Content ;
internal HtmlDocumentResponse ( StringResponse stringResponse ) : base ( stringResponse ) {
if ( stringResponse = = null ) {
throw new ArgumentNullException ( nameof ( stringResponse ) ) ;
}
Content = StringToHtmlDocument ( stringResponse . Content ) ;
}
}
internal sealed class ObjectResponse < T > : BasicResponse {
internal readonly T Content ;
internal ObjectResponse ( StringResponse stringResponse , T content ) : base ( stringResponse ) {
if ( stringResponse = = null ) {
throw new ArgumentNullException ( nameof ( stringResponse ) ) ;
}
Content = content ;
}
}
internal sealed class StringResponse : BasicResponse {
internal readonly string Content ;
internal StringResponse ( HttpResponseMessage httpResponseMessage , string content ) : base ( httpResponseMessage ) {
if ( ( httpResponseMessage = = null ) | | ( content = = null ) ) {
throw new ArgumentNullException ( nameof ( httpResponseMessage ) + " || " + nameof ( content ) ) ;
}
Content = content ;
}
}
internal sealed class XmlResponse : BasicResponse {
internal readonly XmlDocument Content ;
internal XmlResponse ( StringResponse stringResponse , XmlDocument content ) : base ( stringResponse ) {
if ( stringResponse = = null ) {
throw new ArgumentNullException ( nameof ( stringResponse ) ) ;
}
Content = content ;
}
}
2015-11-25 16:31:39 +01:00
}
2016-11-24 07:32:16 +01:00
}