1313using System . Runtime . InteropServices ;
1414using System . Security ;
1515using System . Threading ;
16+ #if NETFRAMEWORK
17+ using System . Threading . Tasks ;
18+ #endif
1619
1720namespace ShareFile . Api . Powershell
1821{
@@ -24,6 +27,16 @@ namespace ShareFile.Api.Powershell
2427 /// </summary>
2528 public class PSShareFileClient
2629 {
30+ private static readonly HttpClient HttpClient =
31+ #if NETFRAMEWORK
32+ new HttpClient ( ) ;
33+ #else
34+ new HttpClient ( new SocketsHttpHandler
35+ {
36+ PooledConnectionLifetime = TimeSpan . FromMinutes ( 15 )
37+ } ) ;
38+ #endif
39+
2740 public string Path { get ; set ; }
2841
2942 public ShareFileClient Client { get ; set ; }
@@ -109,30 +122,23 @@ public AuthenticationDomain AuthenticateUsernamePassword(string account, string
109122 AuthenticationDomain authDomain = null ;
110123 var accountAndDomain = string . IsNullOrEmpty ( account ) ? domain : string . Format ( "{0}.{1}" , account , domain ) ;
111124 var uri = string . Format ( "https://{0}/oauth/token" , accountAndDomain ) ;
112- var request = HttpWebRequest . CreateHttp ( uri ) ;
113- request . Method = "POST" ;
114- request . ContentType = "application/x-www-form-urlencoded" ;
115- using ( var body = new StreamWriter ( request . GetRequestStream ( ) ) )
116- {
117125
118- body . Write (
119- Uri . EscapeDataString ( string . Format ( "grant_type=password&client_id={0}&client_secret={1}&username={2}&password={3}" ,
120- Resources . ClientId ,
121- Resources . ClientSecret ,
122- username ,
123- password ) ) ) ;
124- }
125- var response = ( HttpWebResponse ) request . GetResponse ( ) ;
126- using ( var body = new StreamReader ( response . GetResponseStream ( ) ) )
126+ using var request = new HttpRequestMessage ( HttpMethod . Post , uri ) ;
127+ request . Content = new FormUrlEncodedContent ( CreatePasswordForm ( username , password ) ) ;
128+
129+ using var response = SendHttpRequest ( request ) ;
130+ response . EnsureSuccessStatusCode ( ) ;
131+
132+ using ( var body = new StreamReader ( GetResponseContentStream ( response ) ) )
127133 {
128134 var jobj = JsonConvert . DeserializeObject < JObject > ( body . ReadToEnd ( ) ) ;
129135 authDomain = new AuthenticationDomain ( ) ;
130- authDomain . OAuthToken = jobj [ "access_token" ] != null ? jobj [ "access_token" ] . ToString ( ) : null ;
131- uri = string . Format ( "https://{0 }/{1 }/{2}" , accountAndDomain , Resources . ShareFileProvider , Resources . DefaultApiVersion ) ;
132- authDomain . Uri = uri ;
133- if ( Domains . ContainsKey ( authDomain . Uri ) ) Domains . Remove ( authDomain . Uri ) ;
134- Domains . Add ( authDomain . Uri , authDomain ) ;
135- if ( Client == null ) Client = CreateClient ( authDomain ) ;
136+ authDomain . OAuthToken = jobj [ "access_token" ] ? . ToString ( ) ;
137+ authDomain . Uri = $ "https://{ accountAndDomain } /{ Resources . ShareFileProvider } /{ Resources . DefaultApiVersion } " ; ;
138+ Domains [ authDomain . Uri ] = authDomain ;
139+
140+ Client ??= CreateClient ( authDomain ) ;
141+
136142 var session = Client . Sessions . Get ( ) . Execute ( ) ;
137143 authDomain . AuthID = session . Id ;
138144 this . Save ( ) ;
@@ -246,10 +252,9 @@ private EventHandlerResponse OnException(HttpResponseMessage response, int retry
246252 if ( ! string . IsNullOrEmpty ( Domains [ id ] . OAuthRefreshToken ) )
247253 {
248254 var token = GetTokenResponse (
249- "POST" ,
250- string . Format ( "https://{0}.{1}/oauth/token" , Domains [ id ] . Account , Domains [ id ] . Domain ) ,
251- string . Format ( "grant_type=refresh_token&redirect_uri={0}&refresh_token={1}&client_id={2}&client_secret={3}" ,
252- Resources . RedirectURL , Domains [ id ] . OAuthRefreshToken , Resources . ClientId , Resources . ClientSecret ) ) ;
255+ HttpMethod . Post ,
256+ $ "https://{ Domains [ id ] . Account } .{ Domains [ id ] . Domain } /oauth/token",
257+ CreateRefreshTokenForm ( Domains [ id ] . OAuthRefreshToken ) ) ;
253258 Domains [ id ] . OAuthToken = token . AccessToken ;
254259 Domains [ id ] . OAuthRefreshToken = token . RefreshToken ;
255260 Client . AddOAuthCredentials ( new Uri ( Domains [ id ] . Uri ) , token . AccessToken ) ;
@@ -406,25 +411,76 @@ private ShareFileClient CreateClient(AuthenticationDomain domain)
406411 return client ;
407412 }
408413
409- private OAuthToken GetTokenResponse ( string method , string uri , string body )
414+ private OAuthToken GetTokenResponse ( HttpMethod method , string uri , Dictionary < string , string > formBody )
410415 {
411- var request = HttpWebRequest . CreateHttp ( uri ) ;
412- request . Method = method ;
413- if ( body != null )
416+ using var request = new HttpRequestMessage ( method , uri ) ;
417+
418+ if ( formBody ? . Count > 0 )
414419 {
415- request . ContentType = "application/x-www-form-urlencoded" ;
416- using ( var writer = new StreamWriter ( request . GetRequestStream ( ) ) )
417- {
418- writer . Write ( body ) ;
419- }
420+ request . Content = new FormUrlEncodedContent ( formBody ) ;
420421 }
421- var response = ( HttpWebResponse ) request . GetResponse ( ) ;
422- using ( var reader = new StreamReader ( response . GetResponseStream ( ) ) )
422+
423+ using var response = SendHttpRequest ( request ) ;
424+ response . EnsureSuccessStatusCode ( ) ;
425+ using ( var reader = new StreamReader ( GetResponseContentStream ( response ) ) )
423426 {
424427 return JsonConvert . DeserializeObject < OAuthToken > ( reader . ReadToEnd ( ) ) ;
425428 }
426429 }
427430
431+ private static HttpResponseMessage SendHttpRequest ( HttpRequestMessage request )
432+ {
433+ #if NETFRAMEWORK
434+ return Task . Run ( ( ) => HttpClient . SendAsync ( request ) ) . GetAwaiter ( ) . GetResult ( ) ;
435+ #else
436+ return HttpClient . Send ( request ) ;
437+ #endif
438+ }
439+
440+ private static Stream GetResponseContentStream ( HttpResponseMessage response )
441+ {
442+ #if NETFRAMEWORK
443+ return response . Content . ReadAsStreamAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
444+ #else
445+ return response . Content . ReadAsStream ( ) ;
446+ #endif
447+ }
448+
449+ private static Dictionary < string , string > CreateBaseFormDictionary ( string grantType )
450+ => new Dictionary < string , string >
451+ {
452+ { "grant_type" , grantType } ,
453+ { "client_id" , Resources . ClientId } ,
454+ { "client_secret" , Resources . ClientSecret } ,
455+ } ;
456+
457+ private static Dictionary < string , string > CreatePasswordForm ( string userName , string password )
458+ {
459+ var retVal = CreateBaseFormDictionary ( "password" ) ;
460+ retVal [ "username" ] = userName ;
461+ retVal [ "password" ] = password ;
462+
463+ return retVal ;
464+ }
465+
466+ private static Dictionary < string , string > CreateRefreshTokenForm ( string refreshToken )
467+ {
468+ var retVal = CreateBaseFormDictionary ( "refresh_token" ) ;
469+ retVal [ "redirect_uri" ] = Resources . RedirectURL ;
470+ retVal [ "refresh_token" ] = refreshToken ;
471+
472+ return retVal ;
473+ }
474+
475+ private static Dictionary < string , string > CreateAuthorizationCodeForm ( string code )
476+ {
477+ var retVal = CreateBaseFormDictionary ( "authorization_code" ) ;
478+ retVal [ "code" ] = code ;
479+ retVal [ "requirev3" ] = "true" ;
480+
481+ return retVal ;
482+ }
483+
428484 private class WebDialogThread
429485 {
430486 public AuthenticationDomain Result
@@ -436,13 +492,13 @@ public AuthenticationDomain Result
436492 }
437493 }
438494 private AuthenticationDomain _result = null ;
439- private AutoResetEvent _waitHandle = new AutoResetEvent ( false ) ;
495+ private readonly AutoResetEvent _waitHandle = new AutoResetEvent ( false ) ;
440496
441- private PSShareFileClient _psClient ;
442- private AuthenticationDomain _requestDomain ;
443- private Uri _formUri ;
444- private Uri _tokenUri ;
445- private string _root ;
497+ private readonly PSShareFileClient _psClient ;
498+ private readonly AuthenticationDomain _requestDomain ;
499+ private readonly Uri _formUri ;
500+ private readonly Uri _tokenUri ;
501+ private readonly string _root ;
446502
447503 public WebDialogThread ( PSShareFileClient psClient , AuthenticationDomain domain , Uri formUri = null , Uri tokenUri = null , string root = null )
448504 {
@@ -487,10 +543,9 @@ public void Run()
487543 var appCP = query [ "appcp" ] ;
488544
489545 token = _psClient . GetTokenResponse (
490- "POST" ,
491- string . Format ( "https://{0}.{1}/oauth/token" , subdomain , appCP ) ,
492- string . Format ( "grant_type=authorization_code&code={0}&client_id={1}&client_secret={2}&requirev3=true" , query [ "code" ] ,
493- Resources . ClientId , Resources . ClientSecret ) ) ;
546+ HttpMethod . Post ,
547+ $ "https://{ subdomain } .{ appCP } /oauth/token",
548+ CreateAuthorizationCodeForm ( query [ "code" ] ) ) ;
494549
495550 authDomain = new AuthenticationDomain ( ) ;
496551 authDomain . OAuthToken = token . AccessToken ;
@@ -522,10 +577,12 @@ public void Run()
522577 var kvpSplit = kvp . Split ( '=' ) ;
523578 if ( kvpSplit . Length == 2 ) query . Add ( kvpSplit [ 0 ] , kvpSplit [ 1 ] ) ;
524579 }
525- var request = HttpWebRequest . CreateHttp ( _tokenUri . ToString ( ) + string . Format ( "?root={0}&code={1}" , _root , query [ "code" ] ) ) ;
526- var response = ( HttpWebResponse ) request . GetResponse ( ) ;
580+ using var request = new HttpRequestMessage ( HttpMethod . Get , $ "{ _tokenUri } ?root={ _root } &code={ query [ "code" ] } ") ;
581+ using var response = SendHttpRequest ( request ) ;
582+ response . EnsureSuccessStatusCode ( ) ;
583+
527584 Session session = null ;
528- using ( var reader = new StreamReader ( response . GetResponseStream ( ) ) )
585+ using ( var reader = new StreamReader ( GetResponseContentStream ( response ) ) )
529586 {
530587 session = JsonConvert . DeserializeObject < Session > ( reader . ReadToEnd ( ) ) ;
531588 }
0 commit comments