44
55using System . Collections . Specialized ;
66using System . Net ;
7+ using System . Net . Http . Handlers ;
78using System . Text ;
89using SnapX . Core . Upload . OAuth ;
910using SnapX . Core . Upload . Utils ;
1011using SnapX . Core . Utils ;
1112using SnapX . Core . Utils . Extensions ;
12- using SnapX . Core . Utils . Miscellaneous ;
1313using Math = System . Math ;
1414
1515namespace SnapX . Core . Upload . BaseUploaders ;
@@ -112,18 +112,63 @@ protected bool SendRequestDownload(HttpMethod method, string? url, Stream downlo
112112 {
113113 if ( method == null ) method = HttpMethod . Post ;
114114
115- var boundary = RequestHelpers . CreateBoundary ( ) ;
116- var contentType = headers . Get ( "Content-Type" ) ?? RequestHelpers . ContentTypeMultipartFormData + "; boundary=" + boundary ;
117115
118- // Create multipart/form-data body
119- var data = RequestHelpers . MakeInputContent ( boundary , args ) ;
116+ var multipartContent = GetMultipartFormDataContent ( args , null , null , null , null ) ;
120117
121- using var stream = new MemoryStream ( data ) ;
118+ var requestMessage = new HttpRequestMessage ( method , url )
119+ {
120+ Content = multipartContent
121+ } ;
122+
123+ if ( headers != null )
124+ {
125+ foreach ( var key in headers . AllKeys )
126+ {
127+ requestMessage . Headers . TryAddWithoutValidation ( key , headers [ key ] ) ;
128+ }
129+ }
122130
123- using var response = GetResponse ( method , url , stream , contentType , args , headers , cookies ) ;
131+ if ( cookies != null )
132+ {
133+ var cookieHeader = string . Join ( "; " , cookies . Select ( c => $ "{ c . Name } ={ c . Value } ") ) ;
134+ requestMessage . Headers . Add ( "Cookie" , cookieHeader ) ;
135+ }
136+ var client = HttpClientFactory . Get ( ) ;
137+ var response = client . SendAsync ( requestMessage ) . GetAwaiter ( ) . GetResult ( ) ;
138+ response . EnsureSuccessStatusCode ( ) ;
124139 return ProcessWebResponseText ( response ) ;
125140 }
126141
142+ protected MultipartFormDataContent GetMultipartFormDataContent ( Dictionary < string , string ? > ? args , Stream ? data , string ? fileName , string ? fileFormName , string ? relatedData = null )
143+ {
144+ var multipartContent = new MultipartFormDataContent ( ) ;
145+
146+ if ( args != null )
147+ {
148+ foreach ( var arg in args )
149+ {
150+ multipartContent . Add ( new StringContent ( arg . Value ) , arg . Key ) ;
151+ }
152+ }
153+
154+ if ( relatedData != null )
155+ {
156+ multipartContent . Add (
157+ new StringContent ( relatedData , Encoding . UTF8 , "application/json" ) ,
158+ "file" ,
159+ fileName
160+ ) ;
161+ }
162+ else if ( data is not null )
163+ {
164+ var fileContent = new StreamContent ( data ) ;
165+ var mimeType = MimeTypes . GetMimeType ( fileName ) ;
166+
167+ fileContent . Headers . ContentType = new System . Net . Http . Headers . MediaTypeHeaderValue ( mimeType ) ;
168+ multipartContent . Add ( fileContent , fileFormName , fileName ) ;
169+ }
170+ return multipartContent ;
171+ }
127172 protected UploadResult SendRequestFile ( string ? url , Stream data , string ? fileName , string fileFormName ,
128173 Dictionary < string , string ? > args = null , NameValueCollection headers = null , CookieCollection cookies = null ,
129174 HttpMethod ? method = null , string contentType = null , string relatedData = null )
@@ -133,36 +178,12 @@ protected UploadResult SendRequestFile(string? url, Stream data, string? fileNam
133178 var result = new UploadResult ( ) ;
134179 IsUploading = true ;
135180 StopUploadRequested = false ;
181+ EventHandler < HttpProgressEventArgs > ? handler = null ;
136182
137183 try
138184 {
139185 var client = HttpClientFactory . Get ( ) ;
140- var multipartContent = new MultipartFormDataContent ( ) ;
141-
142- if ( args != null )
143- {
144- foreach ( var arg in args )
145- {
146- multipartContent . Add ( new StringContent ( arg . Value ) , arg . Key ) ;
147- }
148- }
149-
150- if ( relatedData != null )
151- {
152- multipartContent . Add (
153- new StringContent ( relatedData , Encoding . UTF8 , "application/json" ) ,
154- "file" ,
155- fileName
156- ) ;
157- }
158- else
159- {
160- var fileContent = new StreamContent ( data ) ;
161- var mimeType = MimeTypes . GetMimeType ( fileName ) ;
162-
163- fileContent . Headers . ContentType = new System . Net . Http . Headers . MediaTypeHeaderValue ( mimeType ) ;
164- multipartContent . Add ( fileContent , fileFormName , fileName ) ;
165- }
186+ var multipartContent = GetMultipartFormDataContent ( args , data , fileName , fileFormName , relatedData ) ;
166187
167188 var requestMessage = new HttpRequestMessage ( method , url )
168189 {
@@ -176,13 +197,27 @@ protected UploadResult SendRequestFile(string? url, Stream data, string? fileNam
176197 requestMessage . Headers . TryAddWithoutValidation ( key , headers [ key ] ) ;
177198 }
178199 }
179-
200+ requestMessage . Headers . TransferEncodingChunked = true ;
201+ requestMessage . Content . Headers . ContentLength = null ;
180202 if ( cookies != null )
181203 {
182204 var cookieHeader = string . Join ( "; " , cookies . Select ( c => $ "{ c . Name } ={ c . Value } ") ) ;
183205 requestMessage . Headers . Add ( "Cookie" , cookieHeader ) ;
184206 }
185207
208+ var ph = HttpClientFactory . _ph ! ;
209+ var requestLength = data . Length ;
210+ var progress = new ProgressManager ( requestLength ) ;
211+
212+ handler = ( _ , args ) =>
213+ {
214+ progress . Length = new [ ] { requestLength , args . TotalBytes ?? 0 , args . BytesTransferred } . Max ( ) ;
215+
216+ if ( AllowReportProgress && progress . UpdateAbsoluteProgress ( args . BytesTransferred ) )
217+ OnProgressChanged ( progress ) ;
218+ } ;
219+
220+ ph . HttpSendProgress += handler ;
186221 var response = client . SendAsync ( requestMessage ) . GetAwaiter ( ) . GetResult ( ) ;
187222
188223 if ( response . IsSuccessStatusCode )
@@ -214,6 +249,7 @@ protected UploadResult SendRequestFile(string? url, Stream data, string? fileNam
214249 finally
215250 {
216251 IsUploading = false ;
252+ HttpClientFactory . _ph ! . HttpSendProgress -= handler ; // prevent dangling event ref
217253 }
218254
219255 return result ;
@@ -353,16 +389,34 @@ public override int Read(byte[] buffer, int offset, int count)
353389 {
354390 contentLength = data . Length ;
355391 }
356- var request = RequestHelpers . CreateHttpRequest ( method , url , headers , cookies , contentType , contentLength ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) ;
392+
393+ StreamContent ? requestContent = null ;
357394
358395 if ( data != null && ( method == HttpMethod . Post || method == HttpMethod . Put ) )
359396 {
360- using var requestStream = request . Content ? . ReadAsStreamAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
361- if ( requestStream is not null ) data . CopyTo ( requestStream ) ;
397+ requestContent = new StreamContent ( data ) ;
398+ }
399+ var requestMessage = new HttpRequestMessage ( method , url )
400+ {
401+ Content = requestContent
402+ } ;
403+
404+ if ( headers != null )
405+ {
406+ foreach ( var key in headers . AllKeys )
407+ {
408+ requestMessage . Headers . TryAddWithoutValidation ( key , headers [ key ] ) ;
409+ }
410+ }
411+
412+ if ( cookies != null )
413+ {
414+ var cookieHeader = string . Join ( "; " , cookies . Select ( c => $ "{ c . Name } ={ c . Value } ") ) ;
415+ requestMessage . Headers . Add ( "Cookie" , cookieHeader ) ;
362416 }
363417
364418 var client = HttpClientFactory . Get ( ) ;
365- var response = client . SendAsync ( request ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) ;
419+ var response = client . SendAsync ( requestMessage ) . ConfigureAwait ( false ) . GetAwaiter ( ) . GetResult ( ) ;
366420 if ( ! response . IsSuccessStatusCode && ! allowNon2xxResponses )
367421 {
368422 response . EnsureSuccessStatusCode ( ) ;
@@ -505,13 +559,6 @@ protected bool TransferData(Stream dataStream, Stream requestStream, long dataPo
505559 return responseText ;
506560 }
507561
508- private HttpRequestMessage CreateHttpRequest ( HttpMethod method , string ? url , NameValueCollection headers = null , CookieCollection cookies = null ,
509- string contentType = null , long contentLength = 0 )
510- {
511- LastResponseInfo = null ;
512-
513- return RequestHelpers . CreateHttpRequest ( method , url , headers , cookies , contentType , contentLength ) . GetAwaiter ( ) . GetResult ( ) ;
514- }
515562 private Dictionary < string , string > ConvertHeadersToDictionary ( HttpResponseMessage response )
516563 {
517564 var headersDictionary = new Dictionary < string , string > ( StringComparer . OrdinalIgnoreCase ) ;
@@ -556,7 +603,7 @@ private ResponseInfo ProcessWebResponse(HttpResponseMessage response)
556603 ResponseText = response . Content . ReadAsStringAsync ( ) . GetAwaiter ( ) . GetResult ( )
557604 } ;
558605
559- DebugHelper . WriteLine ( $ "ResponseInfo: StatusCode={ responseInfo . StatusCode } StatusDescription={ responseInfo . StatusDescription } ResponseText={ responseInfo . ResponseText } ResponseURL={ responseInfo . ResponseURL } ") ;
606+ // DebugHelper.WriteLine($"ResponseInfo: StatusCode={responseInfo.StatusCode} StatusDescription={responseInfo.StatusDescription} ResponseText={responseInfo.ResponseText} ResponseURL={responseInfo.ResponseURL}");
560607
561608 LastResponseInfo = responseInfo ;
562609 return responseInfo ;
0 commit comments