@@ -77,6 +77,11 @@ public class GxHttpClient : IGxHttpClient, IDisposable
7777 NameValueCollection _headers ;
7878 NameValueCollection _formVars ;
7979 MultiPartTemplate _multipartTemplate ;
80+ bool _isChunkedResponse ;
81+ HttpResponseMessage _response ;
82+ bool _eof ;
83+ bool _encodingFound ;
84+ string _charset ;
8085
8186
8287 string _scheme = "http://" ;
@@ -135,6 +140,7 @@ internal byte[] ReceiveData
135140 {
136141 get
137142 {
143+ ReadResponseData ( ) ;
138144 return _receiveData ;
139145 }
140146 }
@@ -703,58 +709,40 @@ HttpResponseMessage ExecuteRequest(string method, string requestUrl, CookieConta
703709 reqStream . Seek ( 0 , SeekOrigin . Begin ) ;
704710 request . Content = new ByteArrayContent ( reqStream . ToArray ( ) ) ;
705711 setHeaders ( request , handler . CookieContainer ) ;
706- response = client . SendAsync ( request ) . GetAwaiter ( ) . GetResult ( ) ;
712+ response = client . SendAsync ( request , HttpCompletionOption . ResponseHeadersRead ) . GetAwaiter ( ) . GetResult ( ) ;
707713 }
708714 }
709715 return response ;
710- }
711- void ReadReponseContent ( HttpResponseMessage response )
716+ }
717+ void ReadResponseData ( )
712718 {
713- _receiveData = Array . Empty < byte > ( ) ;
714- try
719+ if ( _receiveData == null && _response != null )
715720 {
716- Stream stream = response . Content . ReadAsStreamAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
717- string charset ;
718- if ( response . Content . Headers . ContentType == null )
719- charset = null ;
720- else
721- charset = response . Content . Headers . ContentType . CharSet ;
722- bool encodingFound = false ;
723- if ( ! string . IsNullOrEmpty ( charset ) )
721+ _receiveData = Array . Empty < byte > ( ) ;
722+ try
724723 {
725- int idx = charset . IndexOf ( "charset=" ) ;
726- if ( idx > 0 )
724+ Stream stream = _response . Content . ReadAsStreamAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
725+
726+ using ( MemoryStream ms = new MemoryStream ( ) )
727727 {
728- idx += 8 ;
729- charset = charset . Substring ( idx , charset . Length - idx ) ;
730- _encoding = GetEncoding ( charset ) ;
731- if ( _encoding != null )
732- encodingFound = true ;
728+ stream . CopyTo ( ms ) ;
729+ _receiveData = ms . ToArray ( ) ;
733730 }
734- else
731+ _eof = true ;
732+ int bytesRead = _receiveData . Length ;
733+ GXLogging . Debug ( log , "BytesRead " + _receiveData . Length ) ;
734+ if ( bytesRead > 0 && ! _encodingFound )
735735 {
736- charset = String . Empty ;
736+ _encoding = DetectEncoding ( _charset , out _encodingFound , _receiveData , bytesRead ) ;
737737 }
738738 }
739-
740- using ( MemoryStream ms = new MemoryStream ( ) )
739+ catch ( IOException ioEx )
741740 {
742- stream . CopyTo ( ms ) ;
743- _receiveData = ms . ToArray ( ) ;
741+ if ( _errCode == 1 )
742+ GXLogging . Warn ( log , "Could not read response" , ioEx ) ;
743+ else
744+ throw ioEx ;
744745 }
745- int bytesRead = _receiveData . Length ;
746- GXLogging . Debug ( log , "BytesRead " + _receiveData . Length ) ;
747- if ( bytesRead > 0 && ! encodingFound )
748- {
749- _encoding = DetectEncoding ( charset , out encodingFound , _receiveData , bytesRead ) ;
750- }
751- }
752- catch ( IOException ioEx )
753- {
754- if ( _errCode == 1 )
755- GXLogging . Warn ( log , "Could not read response" , ioEx ) ;
756- else
757- throw ioEx ;
758746 }
759747 }
760748 bool UseOldHttpClient ( string name )
@@ -790,10 +778,22 @@ public void Execute(string method, string name)
790778 HttpClientExecute ( method , name ) ;
791779 }
792780 }
793-
781+ internal void ProcessResponse ( HttpResponseMessage httpResponse )
782+ {
783+ _response = httpResponse ;
784+ LoadResponseHeaders ( _response ) ;
785+ _statusCode = ( ( short ) _response . StatusCode ) ;
786+ _statusDescription = GetStatusCodeDescrption ( _response ) ;
787+ if ( ( _statusCode >= 400 && _statusCode < 600 ) && _errCode != 1 )
788+ {
789+ _errCode = 1 ;
790+ _errDescription = "The remote server returned an error: (" + _statusCode + ") " + _statusDescription + "." ;
791+ }
792+ }
794793 public void HttpClientExecute ( string method , string name )
795794 {
796- HttpResponseMessage response = null ;
795+ _receiveData = null ;
796+ _response = null ;
797797 Byte [ ] Buffer = new Byte [ 1024 ] ;
798798 _errCode = 0 ;
799799 _errDescription = string . Empty ;
@@ -803,7 +803,7 @@ public void HttpClientExecute(string method, string name)
803803 string requestUrl = GetRequestURL ( name ) ;
804804 bool contextCookies = _context != null && ! String . IsNullOrEmpty ( requestUrl ) ;
805805 CookieContainer cookies = contextCookies ? _context . GetCookieContainer ( requestUrl , IncludeCookies ) : new CookieContainer ( ) ;
806- response = ExecuteRequest ( method , requestUrl , cookies ) ;
806+ _response = ExecuteRequest ( method , requestUrl , cookies ) ;
807807
808808 if ( contextCookies )
809809 _context . UpdateSessionCookieContainer ( ) ;
@@ -819,9 +819,9 @@ public void HttpClientExecute(string method, string name)
819819 _errDescription = aex . InnerException . Message ;
820820 else
821821 _errDescription = aex . Message ;
822- response = new HttpResponseMessage ( ) ;
823- response . Content = new StringContent ( HttpHelper . StatusCodeToTitle ( HttpStatusCode . InternalServerError ) ) ;
824- response . StatusCode = HttpStatusCode . InternalServerError ;
822+ _response = new HttpResponseMessage ( ) ;
823+ _response . Content = new StringContent ( HttpHelper . StatusCodeToTitle ( HttpStatusCode . InternalServerError ) ) ;
824+ _response . StatusCode = HttpStatusCode . InternalServerError ;
825825 }
826826#endif
827827 catch ( HttpRequestException e )
@@ -832,22 +832,22 @@ public void HttpClientExecute(string method, string name)
832832 _errDescription = e . Message + " " + e . InnerException . Message ;
833833 else
834834 _errDescription = e . Message ;
835- response = new HttpResponseMessage ( ) ;
836- response . Content = new StringContent ( HttpHelper . StatusCodeToTitle ( HttpStatusCode . InternalServerError ) ) ;
835+ _response = new HttpResponseMessage ( ) ;
836+ _response . Content = new StringContent ( HttpHelper . StatusCodeToTitle ( HttpStatusCode . InternalServerError ) ) ;
837837#if NETCORE
838- response . StatusCode = ( HttpStatusCode ) ( e . StatusCode != null ? e . StatusCode : HttpStatusCode . InternalServerError ) ;
838+ _response . StatusCode = ( HttpStatusCode ) ( e . StatusCode != null ? e . StatusCode : HttpStatusCode . InternalServerError ) ;
839839#else
840- response . StatusCode = HttpStatusCode . InternalServerError ;
840+ _response . StatusCode = HttpStatusCode . InternalServerError ;
841841#endif
842842 }
843843 catch ( TaskCanceledException e )
844844 {
845845 GXLogging . Warn ( log , "Error Execute" , e ) ;
846846 _errCode = 1 ;
847847 _errDescription = "The request has timed out. " + e . Message ;
848- response = new HttpResponseMessage ( ) ;
849- response . StatusCode = 0 ;
850- response . Content = new StringContent ( String . Empty ) ;
848+ _response = new HttpResponseMessage ( ) ;
849+ _response . StatusCode = 0 ;
850+ _response . Content = new StringContent ( String . Empty ) ;
851851 }
852852 catch ( Exception e )
853853 {
@@ -857,29 +857,20 @@ public void HttpClientExecute(string method, string name)
857857 _errDescription = e . Message + " " + e . InnerException . Message ;
858858 else
859859 _errDescription = e . Message ;
860- response = new HttpResponseMessage ( ) ;
861- response . Content = new StringContent ( HttpHelper . StatusCodeToTitle ( HttpStatusCode . InternalServerError ) ) ;
862- response . StatusCode = HttpStatusCode . InternalServerError ;
860+ _response = new HttpResponseMessage ( ) ;
861+ _response . Content = new StringContent ( HttpHelper . StatusCodeToTitle ( HttpStatusCode . InternalServerError ) ) ;
862+ _response . StatusCode = HttpStatusCode . InternalServerError ;
863863 }
864864 GXLogging . Debug ( log , "Reading response..." ) ;
865- if ( response == null )
865+ if ( _response == null )
866866 return ;
867- LoadResponseHeaders ( response ) ;
868- ReadReponseContent ( response ) ;
869- _statusCode = ( ( short ) response . StatusCode ) ;
870- _statusDescription = GetStatusCodeDescrption ( response ) ;
871- if ( ( _statusCode >= 400 && _statusCode < 600 ) && _errCode != 1 )
872- {
873- _errCode = 1 ;
874- _errDescription = "The remote server returned an error: (" + _statusCode + ") " + _statusDescription + "." ;
875- }
867+ ProcessResponse ( _response ) ;
876868 ClearSendStream ( ) ;
877- GXLogging . DebugSanitized ( log , "_responseString " + ToString ( ) ) ;
878869 }
879870 NameValueCollection _respHeaders ;
880871 private bool disposedValue ;
881872
882- void LoadResponseHeaders ( HttpResponseMessage resp )
873+ internal void LoadResponseHeaders ( HttpResponseMessage resp )
883874 {
884875 _respHeaders = new NameValueCollection ( ) ;
885876 foreach ( KeyValuePair < string , IEnumerable < string > > header in resp . Headers )
@@ -890,6 +881,29 @@ void LoadResponseHeaders(HttpResponseMessage resp)
890881 {
891882 _respHeaders . Add ( header . Key , String . Join ( "," , header . Value ) ) ;
892883 }
884+ _isChunkedResponse = resp . Headers . TransferEncodingChunked . HasValue && resp . Headers . TransferEncodingChunked . Value ;
885+
886+ if ( _response . Content . Headers . ContentType == null )
887+ _charset = null ;
888+ else
889+ _charset = _response . Content . Headers . ContentType . CharSet ;
890+ _encodingFound = false ;
891+ if ( ! string . IsNullOrEmpty ( _charset ) )
892+ {
893+ int idx = _charset . IndexOf ( "charset=" ) ;
894+ if ( idx > 0 )
895+ {
896+ idx += 8 ;
897+ _charset = _charset . Substring ( idx , _charset . Length - idx ) ;
898+ _encoding = GetEncoding ( _charset ) ;
899+ if ( _encoding != null )
900+ _encodingFound = true ;
901+ }
902+ else
903+ {
904+ _charset = String . Empty ;
905+ }
906+ }
893907 }
894908
895909 private string GetStatusCodeDescrption ( HttpResponseMessage message )
@@ -1366,14 +1380,54 @@ private Encoding ExtractEncodingFromCharset(string responseText, string regExpP,
13661380 }
13671381 return enc ;
13681382 }
1383+ public bool Eof
1384+ {
1385+ get
1386+ {
1387+ return _eof ;
1388+
1389+ }
1390+ }
1391+ StreamReader _receivedChunkedStream ;
1392+ public string ReadChunk ( )
1393+ {
1394+ if ( ! _isChunkedResponse )
1395+ return ToString ( ) ;
1396+
1397+ if ( _response == null )
1398+ return string . Empty ;
1399+ try
1400+ {
1401+ if ( _receivedChunkedStream == null )
1402+ {
1403+ _receivedChunkedStream = new StreamReader ( _response . Content . ReadAsStreamAsync ( ) . GetAwaiter ( ) . GetResult ( ) ) ;
1404+ }
1405+ _eof = _receivedChunkedStream . EndOfStream ;
1406+ if ( ! _eof )
1407+ {
1408+ string line = _receivedChunkedStream . ReadLine ( ) ;
1409+ if ( line != null )
1410+ {
1411+ return line ;
1412+ }
1413+ }
1414+ }
1415+ catch ( Exception ex )
1416+ {
1417+ GXLogging . Error ( log , String . Format ( "Error reading chunk" , ex ) ) ;
1418+ }
1419+ return string . Empty ;
13691420
1421+ }
13701422 public override string ToString ( )
13711423 {
1424+ if ( ReceiveData == null )
1425+ return string . Empty ;
13721426 if ( _encoding == null )
13731427 _encoding = Encoding . UTF8 ;
1374- if ( _receiveData == null )
1375- return string . Empty ;
1376- return _encoding . GetString ( _receiveData ) ;
1428+ string responseString = _encoding . GetString ( ReceiveData ) ;
1429+ GXLogging . DebugSanitized ( log , "_responseString " + responseString ) ;
1430+ return responseString ;
13771431 }
13781432 public void ToFile ( string fileName )
13791433 {
@@ -1385,9 +1439,9 @@ public void ToFile(string fileName)
13851439 if ( fileName . IndexOfAny ( new char [ ] { '\\ ' , ':' } ) == - 1 )
13861440 pathName = Path . Combine ( GxContext . StaticPhysicalPath ( ) , fileName ) ;
13871441
1388- if ( _receiveData != null )
1442+ if ( ReceiveData != null )
13891443 {
1390- File . WriteAllBytes ( pathName , _receiveData ) ;
1444+ File . WriteAllBytes ( pathName , ReceiveData ) ;
13911445 }
13921446 }
13931447
@@ -1463,6 +1517,7 @@ protected virtual void Dispose(bool disposing)
14631517 {
14641518 _receiveData = null ;
14651519 _sendStream ? . Dispose ( ) ;
1520+ _receivedChunkedStream ? . Dispose ( ) ;
14661521 }
14671522 disposedValue = true ;
14681523 }
0 commit comments