11using System ;
2+ using System . Collections ;
3+ using System . Linq ;
4+ using System . Collections . Concurrent ;
25using System . Collections . Generic ;
36using System . Net . Http ;
47using System . Threading . Tasks ;
58using Microsoft . VisualStudio . Services . Operations ;
9+ using Microsoft . VisualStudio . Services . WebApi ;
10+ using TfsCmdlets . Extensions ;
611using TfsCmdlets . HttpClient ;
712using TfsCmdlets . Services ;
813
@@ -11,7 +16,7 @@ namespace TfsCmdlets.Services
1116 public interface IRestApiService : IService
1217 {
1318 Task < HttpResponseMessage > InvokeAsync (
14- Models . Connection connection ,
19+ Models . Connection connection ,
1520 string path ,
1621 string method = "GET" ,
1722 string body = null ,
@@ -23,7 +28,7 @@ Task<HttpResponseMessage> InvokeAsync(
2328 string serviceHostName = null ) ;
2429
2530 Task < T > InvokeAsync < T > (
26- Models . Connection connection ,
31+ Models . Connection connection ,
2732 string path ,
2833 string method = "GET" ,
2934 string body = null ,
@@ -35,7 +40,7 @@ Task<T> InvokeAsync<T>(
3540 string serviceHostName = null ) ;
3641
3742 Task < OperationReference > QueueOperationAsync (
38- Models . Connection connection ,
43+ Models . Connection connection ,
3944 string path ,
4045 string method = "GET" ,
4146 string body = null ,
@@ -46,17 +51,19 @@ Task<OperationReference> QueueOperationAsync(
4651 string apiVersion = "4.1" ,
4752 string serviceHostName = null ) ;
4853
49- Uri Uri { get ; }
54+ Uri Url { get ; }
5055 }
5156
5257 [ Exports ( typeof ( IRestApiService ) ) ]
5358 internal class RestApiServiceImpl : BaseService , IRestApiService
5459 {
5560 private GenericHttpClient _client ;
5661
57- Uri IRestApiService . Uri => _client ? . Uri ;
62+ public Uri Url => _client . Uri ;
5863
59- Task < HttpResponseMessage > IRestApiService . InvokeAsync ( Models . Connection connection , string path ,
64+ Task < HttpResponseMessage > IRestApiService . InvokeAsync (
65+ Models . Connection connection ,
66+ string path ,
6067 string method ,
6168 string body ,
6269 string requestContentType ,
@@ -66,28 +73,10 @@ Task<HttpResponseMessage> IRestApiService.InvokeAsync(Models.Connection connecti
6673 string apiVersion ,
6774 string serviceHostName )
6875 {
69- var conn = connection . InnerConnection ;
70- path = path . TrimStart ( '/' ) ;
71-
72- if ( ! string . IsNullOrEmpty ( serviceHostName ) )
73- {
74- if ( ! serviceHostName . Contains ( "." ) )
75- {
76- Logger . Log ( $ "Converting service prefix { serviceHostName } to { serviceHostName } .dev.azure.com") ;
77- serviceHostName += ".dev.azure.com" ;
78- }
79-
80- Logger . Log ( $ "Using service host { serviceHostName } ") ;
81- GenericHttpClient . UseHost ( serviceHostName ) ;
82- }
83-
84- _client = conn . GetClient < GenericHttpClient > ( ) ;
85-
86- var task = _client . InvokeAsync ( new HttpMethod ( method ) , path , body ,
87- requestContentType , responseContentType , additionalHeaders , queryParameters ,
88- apiVersion ) ;
89-
90- return task ;
76+ return GetClient ( connection , serviceHostName )
77+ . InvokeAsync ( new HttpMethod ( method ) , path . TrimStart ( '/' ) , body ,
78+ requestContentType , responseContentType , additionalHeaders , queryParameters ,
79+ apiVersion ) ;
9180 }
9281
9382 Task < T > IRestApiService . InvokeAsync < T > (
@@ -102,28 +91,10 @@ Task<T> IRestApiService.InvokeAsync<T>(
10291 string apiVersion ,
10392 string serviceHostName )
10493 {
105- var conn = connection . InnerConnection ;
106- path = path . TrimStart ( '/' ) ;
107-
108- if ( ! string . IsNullOrEmpty ( serviceHostName ) )
109- {
110- if ( ! serviceHostName . Contains ( "." ) )
111- {
112- Logger . Log ( $ "Converting service prefix { serviceHostName } to { serviceHostName } .dev.azure.com") ;
113- serviceHostName += ".dev.azure.com" ;
114- }
115-
116- Logger . Log ( $ "Using service host { serviceHostName } ") ;
117- GenericHttpClient . UseHost ( serviceHostName ) ;
118- }
119-
120- _client = conn . GetClient < GenericHttpClient > ( ) ;
121-
122- var task = _client . InvokeAsync < T > ( new HttpMethod ( method ) , path , body ,
123- requestContentType , responseContentType , additionalHeaders , queryParameters ,
124- apiVersion ) ;
125-
126- return task ;
94+ return GetClient ( connection , serviceHostName )
95+ . InvokeAsync < T > ( new HttpMethod ( method ) , path . TrimStart ( '/' ) , body ,
96+ requestContentType , responseContentType , additionalHeaders , queryParameters ,
97+ apiVersion ) ;
12798 }
12899
129100 Task < OperationReference > IRestApiService . QueueOperationAsync (
@@ -138,17 +109,41 @@ Task<OperationReference> IRestApiService.QueueOperationAsync(
138109 string apiVersion ,
139110 string serviceHostName )
140111 {
141- return ( ( IRestApiService ) this ) . InvokeAsync < OperationReference > (
142- connection ,
143- path ,
144- method ,
145- body ,
146- requestContentType ,
147- responseContentType ,
148- additionalHeaders ,
149- queryParameters ,
150- apiVersion ,
151- serviceHostName ) ;
112+ return GetClient ( connection , serviceHostName )
113+ . InvokeAsync < OperationReference > ( new HttpMethod ( method ) , path . TrimStart ( '/' ) , body ,
114+ requestContentType , responseContentType , additionalHeaders ,
115+ queryParameters , apiVersion ) ;
116+ }
117+
118+ private GenericHttpClient GetClient ( Models . Connection connection , string serviceHostName )
119+ {
120+ var conn = connection . InnerConnection ;
121+ var host = serviceHostName ?? conn . Uri . Host ;
122+
123+ if ( ! host . Contains ( "." ) )
124+ {
125+ Logger . Log ( $ "Converting service prefix { serviceHostName } to { serviceHostName } .dev.azure.com") ;
126+ host += ".dev.azure.com" ;
127+ }
128+
129+ Logger . Log ( $ "Using service host { host } ") ;
130+
131+ var client = conn . GetClient < GenericHttpClient > ( ) ;
132+ var uri = ( new UriBuilder ( client . BaseAddress ) { Host = host } ) . Uri ;
133+
134+ if ( client . BaseAddress . Host != uri . Host )
135+ {
136+ var pipeline = conn . GetHiddenField < HttpMessageHandler > ( "m_pipeline" ) ;
137+ client = new GenericHttpClient ( uri , pipeline , false ) ;
138+
139+ #if NETCOREAPP3_1_OR_GREATER
140+ conn . CallHiddenMethod ( "RegisterClientServiceInstance" , typeof ( GenericHttpClient ) , client ) ;
141+ #else
142+ throw new NotImplementedException ( "RegisterClientServiceInstance is not implemented in PS Desktop" ) ;
143+ #endif
144+ }
145+
146+ return _client = client ;
152147 }
153148 }
154149}
0 commit comments