@@ -10,10 +10,9 @@ namespace Elasticsearch.Net.Connection.HttpClient
1010 /// <summary>
1111 /// IConnection implemented using <see cref="System.Net.Http.HttpClient"/>
1212 /// </summary>
13- public class ElasticsearchHttpClient : IConnection
13+ public class ElasticsearchHttpClient : IConnection , IDisposable
1414 {
1515 private readonly IConnectionConfigurationValues _settings ;
16- private readonly HttpClientHandler _innerHandler ;
1716
1817 static ElasticsearchHttpClient ( )
1918 {
@@ -33,20 +32,24 @@ static ElasticsearchHttpClient()
3332 public ElasticsearchHttpClient ( IConnectionConfigurationValues settings , HttpClientHandler handler = null )
3433 {
3534 _settings = settings ;
36-
37- _innerHandler = handler ?? new WebRequestHandler ( ) ;
38-
3935 DefaultContentType = "application/json" ;
4036
41- if ( _innerHandler . SupportsProxy && ! string . IsNullOrWhiteSpace ( _settings . ProxyAddress ) )
37+ var innerHandler = handler ?? new WebRequestHandler ( ) ;
38+
39+ if ( innerHandler . SupportsProxy && ! string . IsNullOrWhiteSpace ( _settings . ProxyAddress ) )
4240 {
43- _innerHandler . Proxy = new WebProxy ( _settings . ProxyAddress )
41+ innerHandler . Proxy = new WebProxy ( _settings . ProxyAddress )
4442 {
4543 Credentials = new NetworkCredential ( _settings . ProxyUsername , _settings . ProxyPassword ) ,
4644 } ;
4745
48- _innerHandler . UseProxy = true ;
46+ innerHandler . UseProxy = true ;
4947 }
48+
49+ Client = new System . Net . Http . HttpClient ( new ElasticsearchHttpMessageHandler ( innerHandler ) , false )
50+ {
51+ Timeout = TimeSpan . FromMilliseconds ( _settings . Timeout )
52+ } ;
5053 }
5154
5255 /// <summary>
@@ -55,6 +58,18 @@ public ElasticsearchHttpClient(IConnectionConfigurationValues settings, HttpClie
5558 /// <value>The default type of the content.</value>
5659 public string DefaultContentType { get ; set ; }
5760
61+ /// <summary>
62+ /// Gets a value indicating whether this instance is disposed.
63+ /// </summary>
64+ /// <value><c>true</c> if this instance is disposed; otherwise, <c>false</c>.</value>
65+ public bool IsDisposed { get ; private set ; }
66+
67+ /// <summary>
68+ /// Gets the client.
69+ /// </summary>
70+ /// <value>The client.</value>
71+ public System . Net . Http . HttpClient Client { get ; private set ; }
72+
5873 /// <summary>
5974 /// Wraps the DoRequest to run synchronously
6075 /// </summary>
@@ -65,6 +80,8 @@ public ElasticsearchHttpClient(IConnectionConfigurationValues settings, HttpClie
6580 /// <returns>ElasticsearchResponse<Stream>.</returns>
6681 public ElasticsearchResponse < Stream > DoRequestSync ( HttpMethod method , Uri uri , byte [ ] data = null , IRequestConnectionConfiguration requestSpecificConfig = null )
6782 {
83+ ThrowIfDisposed ( ) ;
84+
6885 var requestTask = DoRequest ( method , uri , data , requestSpecificConfig ) ;
6986
7087 try
@@ -92,6 +109,8 @@ public ElasticsearchResponse<Stream> DoRequestSync(HttpMethod method, Uri uri, b
92109 /// <returns>Task<ElasticsearchResponse<Stream>>.</returns>
93110 public async Task < ElasticsearchResponse < Stream > > DoRequest ( HttpMethod method , Uri uri , byte [ ] data = null , IRequestConnectionConfiguration requestSpecificConfig = null )
94111 {
112+ ThrowIfDisposed ( ) ;
113+
95114 try
96115 {
97116 var request = new HttpRequestMessage ( method , uri ) ;
@@ -102,11 +121,11 @@ public async Task<ElasticsearchResponse<Stream>> DoRequest(HttpMethod method, Ur
102121
103122 if ( requestSpecificConfig != null && ! string . IsNullOrWhiteSpace ( requestSpecificConfig . AcceptsContentType ) )
104123 {
105- request . Content . Headers . Allow . Add ( requestSpecificConfig . AcceptsContentType ) ;
124+ request . Headers . Accept . Add ( new MediaTypeWithQualityHeaderValue ( requestSpecificConfig . AcceptsContentType ) ) ;
106125 }
107126 else if ( ! string . IsNullOrWhiteSpace ( DefaultContentType ) )
108127 {
109- request . Content . Headers . Allow . Add ( DefaultContentType ) ;
128+ request . Headers . Accept . Add ( new MediaTypeWithQualityHeaderValue ( DefaultContentType ) ) ;
110129 }
111130
112131 if ( ! string . IsNullOrWhiteSpace ( DefaultContentType ) )
@@ -115,27 +134,16 @@ public async Task<ElasticsearchResponse<Stream>> DoRequest(HttpMethod method, Ur
115134 }
116135 }
117136
118- using ( var client = new System . Net . Http . HttpClient ( new ElasticsearchHttpMessageHandler ( _innerHandler ) , false ) )
119- {
120- if ( requestSpecificConfig != null && requestSpecificConfig . TimeoutRequest . HasValue )
121- {
122- client . Timeout = TimeSpan . FromMilliseconds ( requestSpecificConfig . TimeoutRequest . Value ) ;
123- }
124- else
125- {
126- client . Timeout = TimeSpan . FromMilliseconds ( _settings . Timeout ) ;
127- }
137+ var response = await Client . SendAsync ( request , HttpCompletionOption . ResponseHeadersRead ) ;
128138
129- var response = await client . SendAsync ( request , HttpCompletionOption . ResponseHeadersRead ) ;
139+ if ( method == HttpMethod . Head || response . Content == null || ! response . Content . Headers . ContentLength . HasValue || response . Content . Headers . ContentLength . Value <= 0 )
140+ {
141+ return ElasticsearchResponse < Stream > . Create ( _settings , ( int ) response . StatusCode , method . ToString ( ) . ToLowerInvariant ( ) , uri . ToString ( ) , data ) ;
142+ }
130143
131- if ( method == HttpMethod . Head || response . Content == null || ! response . Content . Headers . ContentLength . HasValue || response . Content . Headers . ContentLength . Value <= 0 )
132- {
133- return ElasticsearchResponse < Stream > . Create ( _settings , ( int ) response . StatusCode , method . ToString ( ) . ToLowerInvariant ( ) , uri . ToString ( ) , data ) ;
134- }
144+ var responseStream = await response . Content . ReadAsStreamAsync ( ) ;
145+ return ElasticsearchResponse < Stream > . Create ( _settings , ( int ) response . StatusCode , method . ToString ( ) . ToLowerInvariant ( ) , uri . ToString ( ) , data , responseStream ) ;
135146
136- var responseStream = await response . Content . ReadAsStreamAsync ( ) ;
137- return ElasticsearchResponse < Stream > . Create ( _settings , ( int ) response . StatusCode , method . ToString ( ) . ToLowerInvariant ( ) , uri . ToString ( ) , data , responseStream ) ;
138- }
139147 }
140148 catch ( Exception ex )
141149 {
@@ -202,5 +210,41 @@ ElasticsearchResponse<Stream> IConnection.DeleteSync(Uri uri, byte[] data, IRequ
202210 {
203211 return DoRequestSync ( HttpMethod . Delete , uri , data , requestSpecificConfig ) ;
204212 }
213+
214+ private void ThrowIfDisposed ( )
215+ {
216+ if ( IsDisposed )
217+ {
218+ throw new ObjectDisposedException ( GetType ( ) . Name ) ;
219+ }
220+ }
221+
222+ public void Dispose ( )
223+ {
224+ Dispose ( true ) ;
225+ GC . SuppressFinalize ( this ) ;
226+ }
227+
228+ ~ ElasticsearchHttpClient ( )
229+ {
230+ Dispose ( false ) ;
231+ }
232+
233+ protected virtual void Dispose ( bool disposing )
234+ {
235+ if ( IsDisposed )
236+ return ;
237+
238+ if ( disposing )
239+ {
240+ if ( Client != null )
241+ {
242+ Client . Dispose ( ) ;
243+ Client = null ;
244+ }
245+ }
246+
247+ IsDisposed = true ;
248+ }
205249 }
206250}
0 commit comments