1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.Runtime.InteropServices;
7 using Microsoft.Win32.SafeHandles;
8 
9 internal static partial class Interop
10 {
11     internal static partial class Http
12     {
13         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiCreate")]
MultiCreate()14         public static extern SafeCurlMultiHandle MultiCreate();
15 
16         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiDestroy")]
MultiDestroy(IntPtr handle)17         private static extern CURLMcode MultiDestroy(IntPtr handle);
18 
19         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiAddHandle")]
MultiAddHandle(SafeCurlMultiHandle multiHandle, SafeCurlHandle easyHandle)20         public static extern CURLMcode MultiAddHandle(SafeCurlMultiHandle multiHandle, SafeCurlHandle easyHandle);
21 
22         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiRemoveHandle")]
MultiRemoveHandle(SafeCurlMultiHandle multiHandle, SafeCurlHandle easyHandle)23         public static extern CURLMcode MultiRemoveHandle(SafeCurlMultiHandle multiHandle, SafeCurlHandle easyHandle);
24 
25         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiWait")]
MultiWait( SafeCurlMultiHandle multiHandle, SafeFileHandle extraFileDescriptor, out bool isExtraFileDescriptorActive, out bool isTimeout)26         public static extern CURLMcode MultiWait(
27             SafeCurlMultiHandle multiHandle,
28             SafeFileHandle extraFileDescriptor,
29             out bool isExtraFileDescriptorActive,
30             out bool isTimeout);
31 
32         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiPerform")]
MultiPerform(SafeCurlMultiHandle multiHandle)33         public static extern CURLMcode MultiPerform(SafeCurlMultiHandle multiHandle);
34 
35         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiInfoRead")]
MultiInfoRead( SafeCurlMultiHandle multiHandle, out CURLMSG message, out IntPtr easyHandle, out CURLcode result)36         public static extern bool MultiInfoRead(
37             SafeCurlMultiHandle multiHandle,
38             out CURLMSG message,
39             out IntPtr easyHandle,
40             out CURLcode result);
41 
42         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiGetErrorString")]
MultiGetErrorString(int code)43         public static extern IntPtr MultiGetErrorString(int code);
44 
45         [DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_MultiSetOptionLong")]
MultiSetOptionLong(SafeCurlMultiHandle curl, CURLMoption option, long value)46         public static extern CURLMcode MultiSetOptionLong(SafeCurlMultiHandle curl, CURLMoption option, long value);
47 
48         // Enum for constants defined for the enum CURLMcode in multi.h
49         internal enum CURLMcode : int
50         {
51             CURLM_CALL_MULTI_PERFORM = -1,
52             CURLM_OK = 0,
53             CURLM_BAD_HANDLE = 1,
54             CURLM_BAD_EASY_HANDLE = 2,
55             CURLM_OUT_OF_MEMORY = 3,
56             CURLM_INTERNAL_ERROR = 4,
57             CURLM_BAD_SOCKET = 5,
58             CURLM_UNKNOWN_OPTION = 6,
59             CURLM_ADDED_ALREADY = 7,
60         }
61 
62         internal enum CURLMoption : int
63         {
64             CURLMOPT_PIPELINING = 3,
65             CURLMOPT_MAX_HOST_CONNECTIONS = 7,
66         }
67 
68         internal enum CurlPipe : int
69         {
70             CURLPIPE_MULTIPLEX = 2
71         }
72 
73         // Enum for constants defined for the enum CURLMSG in multi.h
74         internal enum CURLMSG : int
75         {
76             CURLMSG_DONE = 1,
77         }
78 
79         internal sealed class SafeCurlMultiHandle : SafeHandle
80         {
SafeCurlMultiHandle()81             public SafeCurlMultiHandle()
82                 : base(IntPtr.Zero, true)
83             {
84             }
85 
86             public override bool IsInvalid
87             {
88                 get { return this.handle == IntPtr.Zero; }
89             }
90 
ReleaseHandle()91             protected override bool ReleaseHandle()
92             {
93                 bool result = MultiDestroy(handle) == CURLMcode.CURLM_OK;
94                 SetHandle(IntPtr.Zero);
95                 return result;
96             }
97         }
98     }
99 }
100