19
19
using CURLcode = Interop . libcurl . CURLcode ;
20
20
using CURLMcode = Interop . libcurl . CURLMcode ;
21
21
using CURLINFO = Interop . libcurl . CURLINFO ;
22
+ using CurlVersionInfoData = Interop . libcurl . curl_version_info_data ;
23
+ using CurlFeatures = Interop . libcurl . CURL_VERSION_Features ;
22
24
using CURLProxyType = Interop . libcurl . curl_proxytype ;
23
25
using size_t = System . IntPtr ;
24
26
27
+
25
28
namespace System . Net . Http
26
29
{
27
30
internal partial class CurlHandler : HttpMessageHandler
@@ -34,13 +37,19 @@ internal partial class CurlHandler : HttpMessageHandler
34
37
private const string EncodingNameDeflate = "deflate" ;
35
38
private readonly static string [ ] AuthenticationSchemes = { "Negotiate" , "Digest" , "Basic" } ; // the order in which libcurl goes over authentication schemes
36
39
private static readonly string [ ] s_headerDelimiters = new string [ ] { "\r \n " } ;
40
+
37
41
private const int s_requestBufferSize = 16384 ; // Default used by libcurl
38
42
private const string NoTransferEncoding = HttpKnownHeaderNames . TransferEncoding + ":" ;
43
+ private readonly static CurlVersionInfoData curlVersionInfoData ;
44
+ private const int CurlAge = 5 ;
45
+ private const int MinCurlAge = 3 ;
39
46
40
47
#endregion
41
48
42
49
#region Fields
43
-
50
+
51
+ private static readonly bool _supportsAutomaticDecompression ;
52
+ private static readonly bool _supportsSSL ;
44
53
private volatile bool _anyOperationStarted ;
45
54
private volatile bool _disposed ;
46
55
private IWebProxy _proxy = null ;
@@ -63,6 +72,13 @@ static CurlHandler()
63
72
{
64
73
throw new InvalidOperationException ( "Cannot use libcurl in this process" ) ;
65
74
}
75
+ curlVersionInfoData = Marshal . PtrToStructure < CurlVersionInfoData > ( Interop . libcurl . curl_version_info ( CurlAge ) ) ;
76
+ if ( curlVersionInfoData . age < MinCurlAge )
77
+ {
78
+ throw new InvalidOperationException ( SR . net_http_unix_https_libcurl_too_old ) ;
79
+ }
80
+ _supportsSSL = ( CurlFeatures . CURL_VERSION_SSL & curlVersionInfoData . features ) != 0 ;
81
+ _supportsAutomaticDecompression = ( CurlFeatures . CURL_VERSION_LIBZ & curlVersionInfoData . features ) != 0 ;
66
82
}
67
83
68
84
internal CurlHandler ( )
@@ -168,7 +184,7 @@ internal bool SupportsAutomaticDecompression
168
184
{
169
185
get
170
186
{
171
- return true ;
187
+ return _supportsAutomaticDecompression ;
172
188
}
173
189
}
174
190
@@ -267,6 +283,11 @@ protected internal override Task<HttpResponseMessage> SendAsync(
267
283
throw NotImplemented . ByDesignWithMessage ( SR . net_http_client_http_baseaddress_required ) ;
268
284
}
269
285
286
+ if ( request . RequestUri . Scheme == UriSchemeHttps && ! _supportsSSL )
287
+ {
288
+ throw new PlatformNotSupportedException ( SR . net_http_unix_https_support_unavailable_libcurl ) ;
289
+ }
290
+
270
291
if ( request . Headers . TransferEncodingChunked . GetValueOrDefault ( ) && ( request . Content == null ) )
271
292
{
272
293
throw new InvalidOperationException ( SR . net_http_chunked_not_allowed_with_empty_content ) ;
@@ -427,7 +448,10 @@ private SafeCurlHandle CreateRequestHandle(RequestCompletionSource state, GCHand
427
448
428
449
SetCurlCallbacks ( requestHandle , state . RequestMessage , statePtr ) ;
429
450
430
- SetRequestHandleDecompressionOptions ( requestHandle ) ;
451
+ if ( _supportsAutomaticDecompression )
452
+ {
453
+ SetRequestHandleDecompressionOptions ( requestHandle ) ;
454
+ }
431
455
432
456
SetProxyOptions ( requestHandle , state . RequestMessage . RequestUri ) ;
433
457
0 commit comments