Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 195e53c

Browse files
committed
Merge pull request #2597 from vijaykota/_feature
HttpClient xplat: Basic request and response processing
2 parents 21bf9a8 + 3c24f2c commit 195e53c

File tree

9 files changed

+1352
-100
lines changed

9 files changed

+1352
-100
lines changed

src/Common/src/Interop/Unix/libcurl/Interop.SafeCurlHandle.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,66 @@ protected override bool ReleaseHandle()
3434
return true;
3535
}
3636
}
37+
38+
internal sealed class SafeCurlMultiHandle : SafeHandle
39+
{
40+
public SafeCurlMultiHandle()
41+
: base(IntPtr.Zero, true)
42+
{
43+
}
44+
45+
public override bool IsInvalid
46+
{
47+
get { return this.handle == IntPtr.Zero; }
48+
}
49+
50+
public static void DisposeAndClearHandle(ref SafeCurlMultiHandle curlHandle)
51+
{
52+
if (curlHandle != null)
53+
{
54+
curlHandle.Dispose();
55+
curlHandle = null;
56+
}
57+
}
58+
59+
protected override bool ReleaseHandle()
60+
{
61+
Interop.libcurl.curl_multi_cleanup(this.handle);
62+
return true;
63+
}
64+
}
65+
66+
internal sealed class SafeCurlSlistHandle : SafeHandle
67+
{
68+
public SafeCurlSlistHandle()
69+
: base(IntPtr.Zero, true)
70+
{
71+
}
72+
73+
public override bool IsInvalid
74+
{
75+
get { return this.handle == IntPtr.Zero; }
76+
}
77+
78+
public new void SetHandle(IntPtr handle)
79+
{
80+
base.SetHandle(handle);
81+
}
82+
83+
public static void DisposeAndClearHandle(ref SafeCurlSlistHandle curlHandle)
84+
{
85+
if (curlHandle != null)
86+
{
87+
curlHandle.Dispose();
88+
curlHandle = null;
89+
}
90+
}
91+
92+
protected override bool ReleaseHandle()
93+
{
94+
Interop.libcurl.curl_slist_free_all(this.handle);
95+
return true;
96+
}
97+
}
3798
}
3899
}

src/Common/src/Interop/Unix/libcurl/Interop.libcurl.cs

Lines changed: 104 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,88 @@
44
using System;
55
using System.Runtime.InteropServices;
66

7+
using size_t = System.UInt64;
8+
using curl_socket_t = System.Int32;
9+
710
internal static partial class Interop
811
{
912
internal static partial class libcurl
1013
{
14+
[DllImport(Interop.Libraries.LibCurl)]
15+
public static extern int curl_global_init(
16+
long flags);
17+
18+
[DllImport(Interop.Libraries.LibCurl)]
19+
public static extern void curl_global_cleanup();
20+
21+
[DllImport(Interop.Libraries.LibCurl)]
22+
public static extern SafeCurlMultiHandle curl_multi_init();
23+
24+
[DllImport(Interop.Libraries.LibCurl)]
25+
public static extern void curl_multi_cleanup(
26+
IntPtr handle);
27+
28+
[DllImport(Interop.Libraries.LibCurl, CharSet = CharSet.Ansi)]
29+
public static extern int curl_multi_setopt(
30+
SafeCurlMultiHandle multi_handle,
31+
int option,
32+
curl_socket_callback value);
33+
34+
[DllImport(Interop.Libraries.LibCurl, CharSet = CharSet.Ansi)]
35+
public static extern int curl_multi_setopt(
36+
SafeCurlMultiHandle multi_handle,
37+
int option,
38+
curl_multi_timer_callback value);
39+
40+
[DllImport(Interop.Libraries.LibCurl)]
41+
public static extern int curl_multi_setopt(
42+
SafeCurlMultiHandle multi_handle,
43+
int option,
44+
IntPtr value);
45+
46+
[DllImport(Interop.Libraries.LibCurl)]
47+
public static extern int curl_multi_add_handle(
48+
SafeCurlMultiHandle multi_handle,
49+
SafeCurlHandle easy_handle);
50+
51+
[DllImport(Interop.Libraries.LibCurl)]
52+
public static extern int curl_multi_remove_handle(
53+
SafeCurlMultiHandle multi_handle,
54+
SafeCurlHandle easy_handle);
55+
56+
[DllImport(Interop.Libraries.LibCurl)]
57+
public static extern int curl_multi_assign(
58+
SafeCurlMultiHandle multi_handle,
59+
curl_socket_t sockfd,
60+
IntPtr sockptr);
61+
62+
[DllImport(Interop.Libraries.LibCurl)]
63+
public static extern int curl_multi_socket_action(
64+
SafeCurlMultiHandle multi_handle,
65+
curl_socket_t sockfd,
66+
int ev_bitmask,
67+
out int running_handles);
68+
69+
[DllImport(Interop.Libraries.LibCurl)]
70+
public static extern IntPtr curl_multi_info_read(
71+
SafeCurlMultiHandle multi_handle,
72+
out int msgs_in_queue);
73+
74+
[DllImport(Interop.Libraries.LibCurl)]
75+
public static extern IntPtr curl_multi_strerror(
76+
int code);
77+
1178
[DllImport(Interop.Libraries.LibCurl)]
1279
public static extern SafeCurlHandle curl_easy_init();
1380

1481
[DllImport(Interop.Libraries.LibCurl)]
1582
public static extern void curl_easy_cleanup(
1683
IntPtr handle);
1784

85+
[DllImport(Interop.Libraries.LibCurl)]
86+
public static extern void curl_easy_reset(
87+
SafeCurlHandle curl);
88+
1889
[DllImport(Interop.Libraries.LibCurl, CharSet = CharSet.Ansi)]
1990
public static extern int curl_easy_setopt(
2091
SafeCurlHandle curl,
@@ -28,17 +99,46 @@ public static extern int curl_easy_setopt(
2899
long value);
29100

30101
[DllImport(Interop.Libraries.LibCurl)]
31-
public static extern int curl_easy_perform(
32-
SafeCurlHandle curl);
102+
public static extern int curl_easy_setopt(
103+
SafeCurlHandle curl,
104+
int option,
105+
IntPtr value);
106+
107+
[DllImport(Interop.Libraries.LibCurl)]
108+
public static extern int curl_easy_setopt(
109+
SafeCurlHandle curl,
110+
int option,
111+
curl_readwrite_callback callback);
112+
113+
[DllImport(Interop.Libraries.LibCurl)]
114+
public unsafe static extern int curl_easy_setopt(
115+
SafeCurlHandle curl,
116+
int option,
117+
curl_unsafe_write_callback callback);
118+
119+
[DllImport(Interop.Libraries.LibCurl)]
120+
public static extern int curl_easy_setopt(
121+
SafeCurlHandle curl,
122+
int option,
123+
curl_ioctl_callback callback);
33124

34125
[DllImport(Interop.Libraries.LibCurl)]
35126
public static extern IntPtr curl_easy_strerror(
36127
int code);
37128

38129
[DllImport(Interop.Libraries.LibCurl)]
39130
public static extern int curl_easy_getinfo(
40-
SafeCurlHandle curl,
131+
IntPtr handle,
41132
int info,
42-
ref long value); // Using a ref because it won't be populated on error
133+
out IntPtr value);
134+
135+
[DllImport(Interop.Libraries.LibCurl, CharSet = CharSet.Ansi)]
136+
public static extern IntPtr curl_slist_append(
137+
IntPtr curl_slist,
138+
string headerValue);
139+
140+
[DllImport(Interop.Libraries.LibCurl)]
141+
public static extern void curl_slist_free_all(
142+
IntPtr curl_slist);
43143
}
44144
}

src/Common/src/Interop/Unix/libcurl/Interop.libcurl_types.cs

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,74 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5+
using System.Runtime.InteropServices;
6+
7+
using size_t = System.UInt64;
8+
using curl_socket_t = System.Int32;
59

610
internal static partial class Interop
711
{
812
internal static partial class libcurl
913
{
14+
// Class for constants defined for the global flags in curl.h
15+
internal static partial class CurlGlobalFlags
16+
{
17+
internal const long CURL_GLOBAL_SSL = 1L;
18+
internal const long CURL_GLOBAL_WIN32 = 2L;
19+
internal const long CURL_GLOBAL_ALL = (CURL_GLOBAL_SSL | CURL_GLOBAL_WIN32);
20+
}
21+
1022
// Class for constants defined for the enum CURLoption in curl.h
1123
internal static partial class CURLoption
1224
{
1325
// Curl options are of the format <type base> + <n>
1426
private const int CurlOptionLongBase = 0;
1527
private const int CurlOptionObjectPointBase = 10000;
28+
private const int CurlOptionFunctionPointBase = 20000;
1629

17-
internal const int CURLOPT_URL = CurlOptionObjectPointBase + 2;
30+
internal const int CURLOPT_NOBODY = CurlOptionLongBase + 44;
31+
internal const int CURLOPT_UPLOAD = CurlOptionLongBase + 46;
1832
internal const int CURLOPT_FOLLOWLOCATION = CurlOptionLongBase + 52;
1933
internal const int CURLOPT_PROXYPORT = CurlOptionLongBase + 59;
2034
internal const int CURLOPT_PROXYTYPE = CurlOptionLongBase + 101;
2135

2236
internal const int CURLOPT_WRITEDATA = CurlOptionObjectPointBase + 1;
37+
internal const int CURLOPT_URL = CurlOptionObjectPointBase + 2;
2338
internal const int CURLOPT_PROXY = CurlOptionObjectPointBase + 4;
2439
internal const int CURLOPT_PROXYUSERPWD = CurlOptionObjectPointBase + 6;
40+
internal const int CURLOPT_READDATA = CurlOptionObjectPointBase + 9;
41+
internal const int CURLOPT_HTTPHEADER = CurlOptionObjectPointBase + 23;
42+
internal const int CURLOPT_HEADERDATA = CurlOptionObjectPointBase + 29;
2543
internal const int CURLOPT_ACCEPTENCODING = CurlOptionObjectPointBase + 102;
44+
internal const int CURLOPT_PRIVATE = CurlOptionObjectPointBase + 103;
45+
internal const int CURLOPT_IOCTLDATA = CurlOptionObjectPointBase + 131;
46+
47+
internal const int CURLOPT_WRITEFUNCTION = CurlOptionFunctionPointBase + 11;
48+
internal const int CURLOPT_READFUNCTION = CurlOptionFunctionPointBase + 12;
49+
internal const int CURLOPT_HEADERFUNCTION = CurlOptionFunctionPointBase + 79;
50+
internal const int CURLOPT_IOCTLFUNCTION = CurlOptionFunctionPointBase + 130;
51+
}
52+
53+
// Class for constants defined for the enum CURLMoption in multi.h
54+
internal static partial class CURLMoption
55+
{
56+
// Curl options are of the format <type base> + <n>
57+
private const int CurlOptionObjectPointBase = 10000;
58+
private const int CurlOptionFunctionPointBase = 20000;
59+
60+
internal const int CURLMOPT_TIMERDATA = CurlOptionObjectPointBase + 5;
61+
62+
internal const int CURLMOPT_SOCKETFUNCTION = CurlOptionFunctionPointBase + 1;
63+
internal const int CURLMOPT_TIMERFUNCTION = CurlOptionFunctionPointBase + 4;
2664
}
2765

2866
// Class for constants defined for the enum CURLINFO in curl.h
2967
internal static partial class CURLINFO
3068
{
3169
// Curl info are of the format <type base> + <n>
32-
private const int CurlInfoLongBase = 0x200000;
33-
internal const int CURLINFO_RESPONSE_CODE = CurlInfoLongBase + 2;
70+
private const int CurlInfoStringBase = 0x100000;
71+
72+
internal const int CURLINFO_PRIVATE = CurlInfoStringBase + 21;
3473
}
3574

3675
// Class for constants defined for the enum curl_proxytype in curl.h
@@ -44,5 +83,87 @@ internal static partial class CURLcode
4483
{
4584
internal const int CURLE_OK = 0;
4685
}
86+
87+
// Class for constants defined for the enum CURLMcode in multi.h
88+
internal static partial class CURLMcode
89+
{
90+
internal const int CURLM_OK = 0;
91+
}
92+
93+
// Class for constants defined for the enum curlioerr in curl.h
94+
internal static partial class curlioerr
95+
{
96+
internal const int CURLIOE_OK = 0;
97+
internal const int CURLIOE_UNKNOWNCMD = 1;
98+
internal const int CURLIOE_FAILRESTART = 2;
99+
}
100+
101+
// Class for constants defined for the enum curliocmd in curl.h
102+
internal static partial class curliocmd
103+
{
104+
internal const int CURLIOCMD_RESTARTREAD = 1;
105+
}
106+
107+
// Class for CURL_POLL_* macros in multi.h
108+
internal static partial class CurlPoll
109+
{
110+
internal const int CURL_POLL_REMOVE = 4;
111+
}
112+
113+
// Class for CURL_CSELECT_* macros in multi.h
114+
internal static partial class CurlSelect
115+
{
116+
internal const int CURL_CSELECT_IN = 1;
117+
internal const int CURL_CSELECT_OUT = 2;
118+
}
119+
120+
// Class for constants defined for the enum CURLMSG in multi.h
121+
internal static partial class CURLMSG
122+
{
123+
internal const int CURLMSG_DONE = 1;
124+
}
125+
126+
// Type definition of CURLMsg from multi.h
127+
[StructLayout(LayoutKind.Explicit)]
128+
internal struct CURLMsg
129+
{
130+
[FieldOffset(0)]
131+
internal int msg;
132+
[FieldOffset(8)]
133+
internal IntPtr easy_handle;
134+
[FieldOffset(16)]
135+
internal IntPtr data;
136+
[FieldOffset(16)]
137+
internal int result;
138+
}
139+
140+
public delegate int curl_socket_callback(
141+
IntPtr handle,
142+
curl_socket_t sockfd,
143+
int what,
144+
IntPtr context,
145+
IntPtr sockptr);
146+
147+
public delegate int curl_multi_timer_callback(
148+
IntPtr handle,
149+
long timeout_ms,
150+
IntPtr context);
151+
152+
public delegate size_t curl_readwrite_callback(
153+
IntPtr buffer,
154+
size_t size,
155+
size_t nitems,
156+
IntPtr context);
157+
158+
public unsafe delegate size_t curl_unsafe_write_callback(
159+
byte* buffer,
160+
size_t size,
161+
size_t nitems,
162+
IntPtr context);
163+
164+
public delegate int curl_ioctl_callback(
165+
IntPtr handle,
166+
int cmd,
167+
IntPtr context);
47168
}
48169
}

src/System.Net.Http/src/System.Net.Http.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,13 @@
132132
<Compile Include="@(CompileItem)" />
133133
</ItemGroup>
134134

135+
<PropertyGroup Condition=" '$(TargetsUnix)' == 'true' ">
136+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
137+
</PropertyGroup>
135138
<ItemGroup Condition=" '$(TargetsUnix)' == 'true' ">
139+
<Compile Include="System\Net\Http\Unix\CurlCallbacks.cs" />
136140
<Compile Include="System\Net\Http\Unix\CurlHandler.cs" />
141+
<Compile Include="System\Net\Http\Unix\CurlResponseMessage.cs" />
137142
<Compile Include="System\Net\Http\Unix\HttpClientHandler.Unix.cs" />
138143
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
139144
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>

0 commit comments

Comments
 (0)