@@ -38,29 +38,27 @@ public UniversalWebClient() : this(new BCLWebClient { }) { }
3838 public UniversalWebClient ( BCLWebClient client ) => Client = client ;
3939
4040 BCLWebClient Client { get ; set ; }
41-
4241 public async Task < Tuple < HttpStatusCode , string > > ExecuteAsync (
43- WebRequest httpRequest ,
44- IProgress < IDataTransferLevel > uploadProgress ,
45- IProgress < IDataTransferLevel > downloadProgress ,
46- CancellationToken cancellationToken )
42+ WebRequest httpRequest ,
43+ IProgress < IDataTransferLevel > uploadProgress ,
44+ IProgress < IDataTransferLevel > downloadProgress ,
45+ CancellationToken cancellationToken )
4746 {
48- uploadProgress ??= new Progress < IDataTransferLevel > ( ) ;
49- downloadProgress ??= new Progress < IDataTransferLevel > ( ) ;
47+ uploadProgress ??= new Progress < IDataTransferLevel > { } ;
48+ downloadProgress ??= new Progress < IDataTransferLevel > { } ;
5049
51- using HttpRequestMessage message = new ( new HttpMethod ( httpRequest . Method ) , httpRequest . Target ) ;
50+ HttpRequestMessage message = new HttpRequestMessage ( new HttpMethod ( httpRequest . Method ) , httpRequest . Target ) ;
5251
53- Stream data = httpRequest . Data ;
54- if ( data != null || httpRequest . Method . Equals ( "POST" , StringComparison . OrdinalIgnoreCase ) )
52+ if ( ( httpRequest . Data is null && httpRequest . Method . ToLower ( ) . Equals ( "post" )
53+ ? new MemoryStream ( new byte [ 0 ] )
54+ : httpRequest . Data ) is Stream { } data )
5555 {
56- message . Content = new StreamContent ( data ?? new MemoryStream ( new byte [ 0 ] ) ) ;
56+ message . Content = new StreamContent ( data ) ;
5757 }
5858
59-
60- // Add headers to the message
6159 if ( httpRequest . Headers != null )
6260 {
63- foreach ( var header in httpRequest . Headers )
61+ foreach ( KeyValuePair < string , string > header in httpRequest . Headers )
6462 {
6563 if ( ContentHeaders . Contains ( header . Key ) )
6664 {
@@ -73,102 +71,62 @@ public async Task<Tuple<HttpStatusCode, string>> ExecuteAsync(
7371 }
7472 }
7573
76- // Avoid aggressive caching
74+ // Avoid aggressive caching on Windows Phone 8.1.
7775 message . Headers . Add ( "Cache-Control" , "no-cache" ) ;
78-
7976 message . Headers . IfModifiedSince = DateTimeOffset . UtcNow ;
80- using var cts = new CancellationTokenSource ( TimeSpan . FromSeconds ( 30 ) ) ; // Timeout after 30 seconds
8177
82- if ( message . RequestUri . AbsoluteUri . EndsWith ( "/logout" , StringComparison . OrdinalIgnoreCase ) )
83- {
84- var handler = new HttpClientHandler
85- {
86- AllowAutoRedirect = true ,
87- UseCookies = false // Avoid unwanted cookies.
88- } ;
78+ uploadProgress . Report ( new DataTransferLevel { Amount = 0 } ) ;
8979
90- using var client = new HttpClient ( handler )
91- {
92- Timeout = TimeSpan . FromSeconds ( 15 ) // Ensure timeout is respected.
93- } ;
94- using var response = await client . SendAsync ( message , cancellationToken ) . ConfigureAwait ( false ) ;
80+ HttpResponseMessage response = await Client . SendAsync ( message , HttpCompletionOption . ResponseHeadersRead , cancellationToken ) ;
81+ uploadProgress . Report ( new DataTransferLevel { Amount = 1 } ) ;
9582
96- // Read response content as a string
97- string responseContent = await response . Content . ReadAsStringAsync ( ) ;
83+ Stream responseStream = await response . Content . ReadAsStreamAsync ( cancellationToken ) ;
9884
99- // Check if the status code indicates success
100- if ( response . IsSuccessStatusCode )
101- {
102- Debug . WriteLine ( $ "Logout succeeded. Status: { response . StatusCode } ") ;
103- }
104- else
105- {
106- // Log failure details for debugging
107- Debug . WriteLine ( $ "Logout failed. Status: { response . StatusCode } , Error: { responseContent } ") ;
108- }
10985
110- // Return the status code and response content
111- return new Tuple < HttpStatusCode , string > ( response . StatusCode , responseContent ) ;
11286
87+ MemoryStream resultStream = new MemoryStream { } ;
88+ int bufferSize = 4096 , bytesRead = 0 ;
89+ byte [ ] buffer = new byte [ bufferSize ] ;
90+ long totalLength = - 1 , readSoFar = 0 ;
91+
92+ try
93+ {
94+ totalLength = responseStream . Length ;
11395 }
114- else
96+ catch
11597 {
98+ Console . WriteLine ( "Unsupported length..." ) ;
99+ } ;
116100
117- using var response = await Client
118- . SendAsync ( message , HttpCompletionOption . ResponseHeadersRead , cancellationToken ) . ConfigureAwait ( false ) ;
119-
120- // Check if the status code indicates success
121- if ( response . IsSuccessStatusCode )
122- {
123101
102+ while ( ( bytesRead = await responseStream . ReadAsync ( buffer , 0 , buffer . Length , cancellationToken ) ) > 0 )
103+ {
104+ cancellationToken . ThrowIfCancellationRequested ( ) ;
124105
125- }
126- else
127- {
128- // Log failure details for debugging
129- var error = await response . Content . ReadAsStringAsync ( cancellationToken ) ;
130- Debug . WriteLine ( $ "Logout failed. Status: { response . StatusCode } , Error: { error } ") ;
106+ await resultStream . WriteAsync ( buffer , 0 , bytesRead , cancellationToken ) ;
107+ cancellationToken . ThrowIfCancellationRequested ( ) ;
108+ readSoFar += bytesRead ;
131109
110+ if ( totalLength > - 1 )
111+ {
112+ downloadProgress . Report ( new DataTransferLevel { Amount = ( double ) readSoFar / totalLength } ) ;
132113 }
133- using var responseStream = await response . Content . ReadAsStreamAsync ( ) ;
134- using var resultStream = new MemoryStream ( ) ;
114+ }
135115
136- var buffer = new byte [ 4096 ] ;
137- int bytesRead ;
138- long totalLength = response . Content . Headers . ContentLength ?? - 1 ;
139- long readSoFar = 0 ;
116+ responseStream . Dispose ( ) ;
140117
141- // Read response stream and report progress
142- while ( ( bytesRead = await responseStream . ReadAsync ( buffer , 0 , buffer . Length , cancellationToken ) ) > 0 )
143- {
144- await resultStream . WriteAsync ( buffer , 0 , bytesRead , cancellationToken ) ;
145- readSoFar += bytesRead ;
146-
147- if ( totalLength > 0 )
148- {
149- downloadProgress . Report ( new DataTransferLevel { Amount = 1.0 * readSoFar / totalLength } ) ;
150- }
151- }
118+ if ( totalLength == - 1 )
119+ {
120+ downloadProgress . Report ( new DataTransferLevel { Amount = 1.0 } ) ;
121+ }
152122
153- // Report final progress if total length was unknown
154- if ( totalLength == - 1 )
155- {
156- downloadProgress . Report ( new DataTransferLevel { Amount = 1.0 } ) ;
157- }
158- var encoding = response . Content . Headers . ContentType ? . CharSet switch
159- {
160- "utf-8" => Encoding . UTF8 ,
161- "ascii" => Encoding . ASCII ,
162- _ => Encoding . Default
163- } ;
164- // Convert response to string (assuming UTF-8 encoding)
165- var resultAsArray = resultStream . ToArray ( ) ;
166- string responseContent = Encoding . UTF8 . GetString ( resultAsArray ) ;
123+ byte [ ] resultAsArray = resultStream . ToArray ( ) ;
124+ resultStream . Dispose ( ) ;
167125
168- return new Tuple < HttpStatusCode , string > ( response . StatusCode , responseContent ) ;
169-
126+ // Assume UTF-8 encoding.
127+ string resultString = Encoding . UTF8 . GetString ( resultAsArray , 0 , resultAsArray . Length ) ;
170128
171- }
129+ return new Tuple < HttpStatusCode , string > ( response . StatusCode , resultString ) ;
172130 }
173131
174132}
0 commit comments