Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Köplinger <alex.koeplinger@outlook.com>2019-03-29 21:27:07 +0300
committerGitHub <noreply@github.com>2019-03-29 21:27:07 +0300
commit15a0b97b1069e0f07c66e0fe875a58597d971201 (patch)
tree876b258304e42e07d6dddff3b03e5a36c254508c /mcs/class/System.Net.Http
parent9ebf3a834c47a2d5a73523a6b85c11327dd5adaf (diff)
[System.Net.Http] Move Mac/iOS specific HttpMessageHandler's to Xamarin.*.dll (#13746)
* Revert "[System.Net.Http] Move NSUrlSessionHandler from xamarin-macios to mono (#13229)" This reverts commit 5bf74a995465dd54ceb4a2311c2d6041258e8fe0. * [System.Net.Http] Move Mac/iOS specific HttpMessageHandler's to Xamarin.*.dll We decided to move these types into Xamarin products since they can't be used without the underlying infrastructure anyway. * Bump API snapshot submodule * [csproj] Update project files
Diffstat (limited to 'mcs/class/System.Net.Http')
-rw-r--r--mcs/class/System.Net.Http/Assembly/AssemblyInfo.cs6
-rw-r--r--mcs/class/System.Net.Http/CFContentStream.cs156
-rw-r--r--mcs/class/System.Net.Http/CFNetworkHandler.cs389
-rw-r--r--mcs/class/System.Net.Http/HttpClientEx.cs229
-rw-r--r--mcs/class/System.Net.Http/Makefile18
-rw-r--r--mcs/class/System.Net.Http/NSUrlSessionHandler.cs896
-rw-r--r--mcs/class/System.Net.Http/RuntimeOptions.cs98
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.csproj42
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http/HttpClient.mac.cs23
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http/HttpClient.macios.cs17
-rw-r--r--mcs/class/System.Net.Http/monotouch_System.Net.Http.dll.sources6
-rw-r--r--mcs/class/System.Net.Http/monotouch_runtime_System.Net.Http.dll.sources1
-rw-r--r--mcs/class/System.Net.Http/monotouch_tv_System.Net.Http.dll.sources6
-rw-r--r--mcs/class/System.Net.Http/monotouch_watch_System.Net.Http.dll.sources4
-rw-r--r--mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources2
-rw-r--r--mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources2
16 files changed, 66 insertions, 1829 deletions
diff --git a/mcs/class/System.Net.Http/Assembly/AssemblyInfo.cs b/mcs/class/System.Net.Http/Assembly/AssemblyInfo.cs
index 7cd48a91baa..0e3386fdc81 100644
--- a/mcs/class/System.Net.Http/Assembly/AssemblyInfo.cs
+++ b/mcs/class/System.Net.Http/Assembly/AssemblyInfo.cs
@@ -66,3 +66,9 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo ("System.Net.Http.WebRequest, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
+#if MONOTOUCH || XAMMAC || XAMMAC_4_5
+[assembly: TypeForwardedToAttribute (typeof(System.Net.Http.NSUrlSessionHandler))]
+#if !MONOTOUCH_WATCH
+[assembly: TypeForwardedToAttribute (typeof(System.Net.Http.CFNetworkHandler))]
+#endif
+#endif
diff --git a/mcs/class/System.Net.Http/CFContentStream.cs b/mcs/class/System.Net.Http/CFContentStream.cs
deleted file mode 100644
index d8bba8f0f9a..00000000000
--- a/mcs/class/System.Net.Http/CFContentStream.cs
+++ /dev/null
@@ -1,156 +0,0 @@
-//
-// CFContentStream.cs
-//
-// Authors:
-// Marek Safar <marek.safar@gmail.com>
-//
-// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Threading;
-using System.Threading.Tasks;
-using System.IO;
-using System.Net;
-using System.Runtime.ExceptionServices;
-
-#if XAMCORE_4_0
-using CFNetwork;
-using CoreFoundation;
-#elif XAMCORE_2_0
-using CoreServices;
-using CoreFoundation;
-#else
-using MonoTouch.CoreServices;
-using MonoTouch.CoreFoundation;
-#endif
-
-namespace System.Net.Http
-{
- class BufferData
- {
- public byte[] Buffer;
- public int Length;
- }
-
- class CFContentStream : HttpContent
- {
- readonly CFHTTPStream http_stream;
- BufferData data;
- Mutex data_mutex;
- AutoResetEvent data_event;
- AutoResetEvent data_read_event;
- ExceptionDispatchInfo http_exception;
-
- // The requirements are:
- // * We must read at least one byte from the stream every time
- // we get a HasBytesAvailable event.
- // * SerializeToStreamAsync is executed on a separate thread,
- // so reads must somehow be synchronized with that thread.
- //
- // Current implementation:
- // * We read data in ReadStreamData (on the same thread
- // we got the HasBytesAvailable event, i.e. inside the
- // HasBytesAvailable event handler).
- // * Data is stored in a class-level buffer.
- // * SerializeToStreamAsync blocks while waiting for
- // data from ReadStreamData.
- // * ReadStreamData will only read more data once SerializeToStreamAsync
- // has consumed any existing data. This means we'll be
- // blocking in the HasBytesAvailable event handler until
- // any previously read data has been processed (this prevents
- // any unbound memory growth).
-
- public CFContentStream (CFHTTPStream stream)
- {
- this.http_stream = stream;
- this.http_stream.ErrorEvent += HandleErrorEvent;
- data = new BufferData () {
- Buffer = new byte [4096],
- };
- data_event = new AutoResetEvent (false);
- data_read_event = new AutoResetEvent (true);
- data_mutex = new Mutex ();
- }
-
- void HandleErrorEvent (object sender, CFStream.StreamEventArgs e)
- {
- var gotMutex = data_mutex.WaitOne ();
- if (gotMutex) {
- var stream = (CFHTTPStream)sender;
- if (e.EventType == CFStreamEventType.ErrorOccurred)
- Volatile.Write (ref http_exception, ExceptionDispatchInfo.Capture (stream.GetError ()));
- data_mutex.ReleaseMutex ();
- }
- }
-
- public void ReadStreamData ()
- {
- data_read_event.WaitOne (); // make sure there's no pending data.
-
- data_mutex.WaitOne ();
- data.Length = (int) http_stream.Read (data.Buffer, 0, data.Buffer.Length);
- data_mutex.ReleaseMutex ();
-
- data_event.Set ();
- }
-
- public void Close ()
- {
- data_read_event.WaitOne (); // make sure there's no pending data
-
- data_mutex.WaitOne ();
- data = null;
- this.http_stream.ErrorEvent -= HandleErrorEvent;
- data_mutex.ReleaseMutex ();
-
- data_event.Set ();
- }
-
- protected internal override async Task SerializeToStreamAsync (Stream stream, TransportContext context)
- {
- while (data_event.WaitOne ()) {
- data_mutex.WaitOne ();
- if (http_exception != null) {
- http_exception.Throw ();
- data_mutex.ReleaseMutex ();
- break;
- }
- if (data == null || data.Length <= 0) {
- data_mutex.ReleaseMutex ();
- data_read_event.Set ();
- break;
- }
-
- await stream.WriteAsync (data.Buffer, 0, data.Length).ConfigureAwait (false);
- data_mutex.ReleaseMutex ();
-
- data_read_event.Set ();
- }
- }
-
- protected internal override bool TryComputeLength (out long length)
- {
- length = 0;
- return false;
- }
- }
-}
diff --git a/mcs/class/System.Net.Http/CFNetworkHandler.cs b/mcs/class/System.Net.Http/CFNetworkHandler.cs
deleted file mode 100644
index 617d572592c..00000000000
--- a/mcs/class/System.Net.Http/CFNetworkHandler.cs
+++ /dev/null
@@ -1,389 +0,0 @@
-//
-// CFNetworkHandler.cs
-//
-// Authors:
-// Marek Safar <marek.safar@gmail.com>
-//
-// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Threading;
-using System.Net.Http.Headers;
-using System.Threading.Tasks;
-using System.IO;
-using System.Collections.Generic;
-using System.Net;
-
-#if XAMCORE_4_0
-using CFNetwork;
-using CoreFoundation;
-using CF=CoreFoundation;
-#elif XAMCORE_2_0
-using CoreServices;
-using CoreFoundation;
-using CF=CoreFoundation;
-#else
-using MonoTouch.CoreServices;
-using MonoTouch.CoreFoundation;
-using CF=MonoTouch.CoreFoundation;
-#endif
-
-namespace System.Net.Http
-{
- public class CFNetworkHandler : HttpMessageHandler
- {
- class StreamBucket
- {
- public TaskCompletionSource<HttpResponseMessage> Response;
- public HttpRequestMessage Request;
- public CancellationTokenRegistration CancellationTokenRegistration;
- public CFContentStream ContentStream;
- public bool StreamCanBeDisposed;
-
- public void Close ()
- {
- CancellationTokenRegistration.Dispose ();
- if (ContentStream != null) {
- // The Close method of the CFContentStream blocks as you can see:
- // public void Close ()
- // {
- // data_read_event.WaitOne (); // make sure there's no pending data
- //
- // data_mutex.WaitOne ();
- // data = null;
- // this.http_stream.ErrorEvent -= HandleErrorEvent;
- // data_mutex.ReleaseMutex ();
- //
- // data_event.Set ();
- // }
- // This means. that when we want to ignore the data of the content, which happens
- // in the first request of a redirect, if we want to close, ignoring the content
- // we will have a deadlock.
- // Dispose will clean all the data, without waiting for the read, which by design in the
- // CFContentStream, blocks the thread. This happens ONLY after the first request that gets
- // a redirect status code. All other cases should call close.
- if (StreamCanBeDisposed)
- ContentStream.Dispose ();
- else
- ContentStream.Close ();
- }
- }
- }
-
- bool allowAutoRedirect;
- bool sentRequest;
- bool useSystemProxy;
- CookieContainer cookies;
-
- Dictionary<IntPtr, StreamBucket> streamBuckets;
-
- public CFNetworkHandler ()
- {
- allowAutoRedirect = true;
- streamBuckets = new Dictionary<IntPtr, StreamBucket> ();
- }
-
- void EnsureModifiability ()
- {
- if (sentRequest)
- throw new InvalidOperationException (
- "This instance has already started one or more requests. " +
- "Properties can only be modified before sending the first request.");
- }
-
- public bool AllowAutoRedirect {
- get {
- return allowAutoRedirect;
- }
- set {
- EnsureModifiability ();
- allowAutoRedirect = value;
- }
- }
-
- public CookieContainer CookieContainer {
- get {
- return cookies ?? (cookies = new CookieContainer ());
- }
- set {
- EnsureModifiability ();
- cookies = value;
- }
- }
-
- public bool UseSystemProxy {
- get {
- return useSystemProxy;
- }
- set {
- EnsureModifiability ();
- useSystemProxy = value;
- }
- }
-
- // TODO: Add more properties
-
- protected override void Dispose (bool disposing)
- {
- // TODO: CloseStream remaining stream buckets if there are any
-
- base.Dispose (disposing);
- }
-
- CFHTTPMessage CreateWebRequestAsync (HttpRequestMessage request)
- {
- var req = CFHTTPMessage.CreateRequest (request.RequestUri, request.Method.Method, request.Version);
-
- // TODO:
-/*
- if (wr.ProtocolVersion == HttpVersion.Version10) {
- wr.KeepAlive = request.Headers.ConnectionKeepAlive;
- } else {
- wr.KeepAlive = request.Headers.ConnectionClose != true;
- }
-
- if (useDefaultCredentials) {
- wr.UseDefaultCredentials = true;
- } else {
- wr.Credentials = credentials;
- }
-
- if (useProxy) {
- wr.Proxy = proxy;
- }
-*/
- if (cookies != null) {
- string cookieHeader = cookies.GetCookieHeader (request.RequestUri);
- if (cookieHeader != "")
- req.SetHeaderFieldValue ("Cookie", cookieHeader);
- }
-
- foreach (var header in request.Headers) {
- foreach (var value in header.Value) {
- req.SetHeaderFieldValue (header.Key, value);
- }
- }
-
- if (request.Content != null) {
- foreach (var header in request.Content.Headers) {
- foreach (var value in header.Value) {
- req.SetHeaderFieldValue (header.Key, value);
- }
- }
- }
-
- return req;
- }
-
- protected internal override async Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
- {
- return await SendAsync (request, cancellationToken, true).ConfigureAwait (false);
- }
-
- internal async Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken, bool isFirstRequest)
- {
- sentRequest = true;
-
- CFHTTPStream stream;
- using (var message = CreateWebRequestAsync (request))
- {
- if (request.Content != null) {
- var data = await request.Content.ReadAsByteArrayAsync ().ConfigureAwait (false);
- message.SetBody (data);
- }
-
- stream = CFHTTPStream.CreateForHTTPRequest (message);
- }
-
- if (useSystemProxy) {
- var proxies = CF.CFNetwork.GetSystemProxySettings ();
- if (proxies.HTTPEnable) {
- stream.SetProxy (proxies);
- }
- }
-
- if (!isFirstRequest && allowAutoRedirect)
- stream.ShouldAutoredirect = allowAutoRedirect;
- stream.HasBytesAvailableEvent += HandleHasBytesAvailableEvent;
- stream.ErrorEvent += HandleErrorEvent;
- stream.ClosedEvent += HandleClosedEvent;
-
- var response = new TaskCompletionSource<HttpResponseMessage> ();
-
- if (cancellationToken.IsCancellationRequested) {
- response.SetCanceled ();
- return await response.Task;
- }
-
- var bucket = new StreamBucket () {
- Request = request,
- Response = response,
- };
-
- streamBuckets.Add (stream.Handle, bucket);
-
- //
- // Always schedule stream events handling on main-loop. Due to ConfigureAwait (false) we may end up
- // on any thread-pool thread which may not have run-loop running
- //
-#if XAMCORE_2_0
- stream.EnableEvents (CF.CFRunLoop.Main, CF.CFRunLoop.ModeCommon);
-#else
- stream.EnableEvents (CF.CFRunLoop.Main, CF.CFRunLoop.CFRunLoopCommonModes);
-#endif
-
- stream.Open ();
-
- bucket.CancellationTokenRegistration = cancellationToken.Register (() => {
- StreamBucket bucket2;
- if (!streamBuckets.TryGetValue (stream.Handle, out bucket2))
- return;
-
- bucket2.Response.TrySetCanceled ();
- CloseStream (stream);
- });
-
- if (isFirstRequest) {
- var initialRequest = await response.Task;
- var status = initialRequest.StatusCode;
- if (IsRedirect (status) && allowAutoRedirect) {
- bucket.StreamCanBeDisposed = true;
- // remove headers in a redirect for Authentication.
- request.Headers.Authorization = null;
- return await SendAsync (request, cancellationToken, false).ConfigureAwait (false);
- }
- return initialRequest;
- }
- return await response.Task;
- }
-
- // Decide if we redirect or not, similar to what is done in the managed handler
- // https://github.com/mono/mono/blob/eca15996c7163f331c9f2cd0a17b63e8f92b1d55/mcs/class/referencesource/System/net/System/Net/HttpWebRequest.cs#L5681
- static bool IsRedirect (HttpStatusCode status)
- {
- return status == HttpStatusCode.Ambiguous || // 300
- status == HttpStatusCode.Moved || // 301
- status == HttpStatusCode.Redirect || // 302
- status == HttpStatusCode.RedirectMethod || // 303
- status == HttpStatusCode.RedirectKeepVerb; // 307
- }
-
- void HandleErrorEvent (object sender, CFStream.StreamEventArgs e)
- {
- var stream = (CFHTTPStream)sender;
-
- StreamBucket bucket;
- if (!streamBuckets.TryGetValue (stream.Handle, out bucket))
- return;
-
- bucket.Response.TrySetException (stream.GetError ());
- CloseStream (stream);
- }
-
- void HandleClosedEvent (object sender, CFStream.StreamEventArgs e)
- {
- var stream = (CFHTTPStream)sender;
- // might not have been called (e.g. no data) but initialize critical data
- HandleHasBytesAvailableEvent (sender, e);
- CloseStream (stream);
- }
-
- void CloseStream (CFHTTPStream stream)
- {
- lock (streamBuckets) {
- if (streamBuckets.TryGetValue (stream.Handle, out var bucket)) {
- bucket.Close ();
- streamBuckets.Remove (stream.Handle);
- }
- }
- stream.Close ();
- }
-
- void HandleHasBytesAvailableEvent (object sender, CFStream.StreamEventArgs e)
- {
- var stream = (CFHTTPStream) sender;
-
- StreamBucket bucket;
- if (!streamBuckets.TryGetValue (stream.Handle, out bucket))
- return;
-
- if (bucket.Response.Task.IsCompleted) {
- bucket.ContentStream.ReadStreamData ();
- return;
- }
-
- var header = stream.GetResponseHeader ();
-
- // Is this possible?
- if (!header.IsHeaderComplete)
- throw new NotImplementedException ();
-
- bucket.ContentStream = new CFContentStream (stream);
-
- var response_msg = new HttpResponseMessage (header.ResponseStatusCode);
- response_msg.RequestMessage = bucket.Request;
- response_msg.ReasonPhrase = header.ResponseStatusLine;
- response_msg.Content = bucket.ContentStream;
-
- var fields = header.GetAllHeaderFields ();
- if (fields != null) {
- foreach (var entry in fields) {
- if (entry.Key == null)
- continue;
-
- var key = entry.Key.ToString ();
- var value = entry.Value == null ? string.Empty : entry.Value.ToString ();
- HttpHeaders item_headers;
- if (HttpHeaders.GetKnownHeaderKind (key) == Headers.HttpHeaderKind.Content) {
- item_headers = response_msg.Content.Headers;
- } else {
- item_headers = response_msg.Headers;
-
- if (cookies != null && (key == "Set-Cookie" || key == "Set-Cookie2"))
- AddCookie (value, bucket.Request.RequestUri, key);
- }
-
- item_headers.TryAddWithoutValidation (key, value);
- }
- }
-
- // cancellation (CancellationTokenRegistration) can happen in parallel
- if (!bucket.Response.Task.IsCanceled) {
- bucket.Response.TrySetResult (response_msg);
-
- bucket.ContentStream.ReadStreamData ();
- }
- }
-
- void AddCookie (string value, Uri uri, string header)
- {
- CookieCollection cookies1 = null;
- try {
- cookies1 = cookies.CookieCutter (uri, header, value, false);
- } catch {
- }
-
- if (cookies1 != null && cookies1.Count != 0)
- cookies.Add (cookies1);
- }
- }
-}
diff --git a/mcs/class/System.Net.Http/HttpClientEx.cs b/mcs/class/System.Net.Http/HttpClientEx.cs
deleted file mode 100644
index fd5621c22e3..00000000000
--- a/mcs/class/System.Net.Http/HttpClientEx.cs
+++ /dev/null
@@ -1,229 +0,0 @@
-using System;
-using System.IO;
-using System.Net;
-#if XAMCORE_2_0
-using CoreFoundation;
-using Foundation;
-using ObjCRuntime;
-#elif MONOMAC
-using MonoMac.CoreFoundation;
-using MonoMac.Foundation;
-using MonoMac.ObjCRuntime;
-#else
-using MonoTouch.CoreFoundation;
-using MonoTouch.Foundation;
-using MonoTouch.ObjCRuntime;
-#endif
-
-#if SYSTEM_NET_HTTP && !MONOMAC
-namespace System.Net.Http {
-
- public partial class HttpClient {
-
- public HttpClient ()
- : this (GetDefaultHandler (), true)
- {
- }
-
- // note: the linker will re-write this to only reference the selected handler
- // but we want this to work "as expected" even if the application is not being linked
- static HttpMessageHandler GetDefaultHandler ()
- {
-#if MONOTOUCH_WATCH
- // There's only one valid handler type for watchOS
- return new NSUrlSessionHandler ();
-#else
- return RuntimeOptions.GetHttpMessageHandler ();
-#endif
- }
- }
-#else
-// due to historical reasons (around CFNetwork) Xamarin.Mac includes this inside it's profile assembly
-// and not a custom System.Net.Http assembly
-namespace Foundation {
-#endif
-
- partial class NSUrlSessionHandler {
-
- bool allowAutoRedirect;
- ICredentials credentials;
- bool sentRequest;
-
- public bool AllowAutoRedirect {
- get {
- return allowAutoRedirect;
- }
- set {
- EnsureModifiability ();
- allowAutoRedirect = value;
- }
- }
-
- public ICredentials Credentials {
- get {
- return credentials;
- }
- set {
- EnsureModifiability ();
- credentials = value;
- }
- }
-
- internal void EnsureModifiability ()
- {
- if (sentRequest)
- throw new InvalidOperationException (
- "This instance has already started one or more requests. " +
- "Properties can only be modified before sending the first request.");
- }
-
- // almost identical to ModernHttpClient version but it uses the constants from monotouch.dll | Xamarin.[iOS|WatchOS|TVOS].dll
- static Exception createExceptionForNSError(NSError error)
- {
- // var webExceptionStatus = WebExceptionStatus.UnknownError;
-
- var innerException = new NSErrorException(error);
-
- // errors that exists in both share the same error code, so we can use a single switch/case
- // this also ease watchOS integration as if does not expose CFNetwork but (I would not be
- // surprised if it)could return some of it's error codes
-#if MONOTOUCH_WATCH
- if (error.Domain == NSError.NSUrlErrorDomain) {
-#else
- if ((error.Domain == NSError.NSUrlErrorDomain) || (error.Domain == NSError.CFNetworkErrorDomain)) {
-#endif
- // Parse the enum into a web exception status or exception. Some
- // of these values don't necessarily translate completely to
- // what WebExceptionStatus supports, so made some best guesses
- // here. For your reading pleasure, compare these:
- //
- // Apple docs: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Constants/index.html#//apple_ref/doc/constant_group/URL_Loading_System_Error_Codes
- // .NET docs: http://msdn.microsoft.com/en-us/library/system.net.webexceptionstatus(v=vs.110).aspx
- switch ((NSUrlError) (long) error.Code) {
- case NSUrlError.Cancelled:
- case NSUrlError.UserCancelledAuthentication:
-#if !MONOTOUCH_WATCH
- case (NSUrlError) NSNetServicesStatus.CancelledError:
-#endif
- // No more processing is required so just return.
- return new OperationCanceledException(error.LocalizedDescription, innerException);
-// case NSUrlError.BadURL:
-// case NSUrlError.UnsupportedURL:
-// case NSUrlError.CannotConnectToHost:
-// case NSUrlError.ResourceUnavailable:
-// case NSUrlError.NotConnectedToInternet:
-// case NSUrlError.UserAuthenticationRequired:
-// case NSUrlError.InternationalRoamingOff:
-// case NSUrlError.CallIsActive:
-// case NSUrlError.DataNotAllowed:
-// #if !MONOTOUCH_WATCH
-// case (NSUrlError) CFNetworkErrors.Socks5BadCredentials:
-// case (NSUrlError) CFNetworkErrors.Socks5UnsupportedNegotiationMethod:
-// case (NSUrlError) CFNetworkErrors.Socks5NoAcceptableMethod:
-// case (NSUrlError) CFNetworkErrors.HttpAuthenticationTypeUnsupported:
-// case (NSUrlError) CFNetworkErrors.HttpBadCredentials:
-// case (NSUrlError) CFNetworkErrors.HttpBadURL:
-// #endif
-// webExceptionStatus = WebExceptionStatus.ConnectFailure;
-// break;
-// case NSUrlError.TimedOut:
-// #if !MONOTOUCH_WATCH
-// case (NSUrlError) CFNetworkErrors.NetServiceTimeout:
-// #endif
-// webExceptionStatus = WebExceptionStatus.Timeout;
-// break;
-// case NSUrlError.CannotFindHost:
-// case NSUrlError.DNSLookupFailed:
-// #if !MONOTOUCH_WATCH
-// case (NSUrlError) CFNetworkErrors.HostNotFound:
-// case (NSUrlError) CFNetworkErrors.NetServiceDnsServiceFailure:
-// #endif
-// webExceptionStatus = WebExceptionStatus.NameResolutionFailure;
-// break;
-// case NSUrlError.DataLengthExceedsMaximum:
-// webExceptionStatus = WebExceptionStatus.MessageLengthLimitExceeded;
-// break;
-// case NSUrlError.NetworkConnectionLost:
-// #if !MONOTOUCH_WATCH
-// case (NSUrlError) CFNetworkErrors.HttpConnectionLost:
-// #endif
-// webExceptionStatus = WebExceptionStatus.ConnectionClosed;
-// break;
-// case NSUrlError.HTTPTooManyRedirects:
-// case NSUrlError.RedirectToNonExistentLocation:
-// #if !MONOTOUCH_WATCH
-// case (NSUrlError) CFNetworkErrors.HttpRedirectionLoopDetected:
-// #endif
-// webExceptionStatus = WebExceptionStatus.ProtocolError;
-// break;
-// case NSUrlError.RequestBodyStreamExhausted:
-// #if !MONOTOUCH_WATCH
-// case (NSUrlError) CFNetworkErrors.SocksUnknownClientVersion:
-// case (NSUrlError) CFNetworkErrors.SocksUnsupportedServerVersion:
-// case (NSUrlError) CFNetworkErrors.HttpParseFailure:
-// #endif
-// webExceptionStatus = WebExceptionStatus.SendFailure;
-// break;
-// case NSUrlError.BadServerResponse:
-// case NSUrlError.ZeroByteResource:
-// case NSUrlError.CannotDecodeRawData:
-// case NSUrlError.CannotDecodeContentData:
-// case NSUrlError.CannotParseResponse:
-// case NSUrlError.FileDoesNotExist:
-// case NSUrlError.FileIsDirectory:
-// case NSUrlError.NoPermissionsToReadFile:
-// case NSUrlError.CannotLoadFromNetwork:
-// case NSUrlError.CannotCreateFile:
-// case NSUrlError.CannotOpenFile:
-// case NSUrlError.CannotCloseFile:
-// case NSUrlError.CannotWriteToFile:
-// case NSUrlError.CannotRemoveFile:
-// case NSUrlError.CannotMoveFile:
-// case NSUrlError.DownloadDecodingFailedMidStream:
-// case NSUrlError.DownloadDecodingFailedToComplete:
-// #if !MONOTOUCH_WATCH
-// case (NSUrlError) CFNetworkErrors.Socks4RequestFailed:
-// case (NSUrlError) CFNetworkErrors.Socks4IdentdFailed:
-// case (NSUrlError) CFNetworkErrors.Socks4IdConflict:
-// case (NSUrlError) CFNetworkErrors.Socks4UnknownStatusCode:
-// case (NSUrlError) CFNetworkErrors.Socks5BadState:
-// case (NSUrlError) CFNetworkErrors.Socks5BadResponseAddr:
-// case (NSUrlError) CFNetworkErrors.CannotParseCookieFile:
-// case (NSUrlError) CFNetworkErrors.NetServiceUnknown:
-// case (NSUrlError) CFNetworkErrors.NetServiceCollision:
-// case (NSUrlError) CFNetworkErrors.NetServiceNotFound:
-// case (NSUrlError) CFNetworkErrors.NetServiceInProgress:
-// case (NSUrlError) CFNetworkErrors.NetServiceBadArgument:
-// case (NSUrlError) CFNetworkErrors.NetServiceInvalid:
-// #endif
-// webExceptionStatus = WebExceptionStatus.ReceiveFailure;
-// break;
-// case NSUrlError.SecureConnectionFailed:
-// webExceptionStatus = WebExceptionStatus.SecureChannelFailure;
-// break;
-// case NSUrlError.ServerCertificateHasBadDate:
-// case NSUrlError.ServerCertificateHasUnknownRoot:
-// case NSUrlError.ServerCertificateNotYetValid:
-// case NSUrlError.ServerCertificateUntrusted:
-// case NSUrlError.ClientCertificateRejected:
-// case NSUrlError.ClientCertificateRequired:
-// webExceptionStatus = WebExceptionStatus.TrustFailure;
-// break;
-// #if !MONOTOUCH_WATCH
-// case (NSUrlError) CFNetworkErrors.HttpProxyConnectionFailure:
-// case (NSUrlError) CFNetworkErrors.HttpBadProxyCredentials:
-// case (NSUrlError) CFNetworkErrors.PacFileError:
-// case (NSUrlError) CFNetworkErrors.PacFileAuth:
-// case (NSUrlError) CFNetworkErrors.HttpsProxyConnectionFailure:
-// case (NSUrlError) CFNetworkErrors.HttpsProxyFailureUnexpectedResponseToConnectMethod:
-// webExceptionStatus = WebExceptionStatus.RequestProhibitedByProxy;
-// break;
-// #endif
- }
- }
-
- // Always create a WebException so that it can be handled by the client.
- return new WebException(error.LocalizedDescription, innerException); //, webExceptionStatus, response: null);
- }
- }
-}
diff --git a/mcs/class/System.Net.Http/Makefile b/mcs/class/System.Net.Http/Makefile
index 88f80d2e8a2..3eef96a6b2f 100644
--- a/mcs/class/System.Net.Http/Makefile
+++ b/mcs/class/System.Net.Http/Makefile
@@ -11,20 +11,30 @@ ifeq (monodroid,$(PROFILE))
LIB_MCS_FLAGS += -d:XAMARIN_MODERN
endif
-ifneq (,$(filter monotouch monotouch_tv monotouch_watch,$(PROFILE)))
-LIB_MCS_FLAGS += -D:XAMCORE_2_0 -D:XAMARIN_MODERN -D:SYSTEM_NET_HTTP -D:UNIFIED -D:__UNIFIED__
-endif
-
ifeq (monotouch,$(PROFILE))
API_BIN_REFS := Xamarin.iOS
+LIB_MCS_FLAGS += -d:XAMARIN_MODERN
endif
ifeq (monotouch_tv,$(PROFILE))
API_BIN_REFS := Xamarin.TVOS
+LIB_MCS_FLAGS += -d:XAMARIN_MODERN
endif
ifeq (monotouch_watch,$(PROFILE))
API_BIN_REFS := Xamarin.WatchOS
+LIB_MCS_FLAGS += -d:XAMARIN_MODERN
+endif
+
+ifeq (xammac,$(PROFILE))
+API_BIN_REFS := Xamarin.Mac
+LIB_MCS_FLAGS += -d:XAMARIN_MODERN
+endif
+
+ifeq (xammac_net_4_5,$(PROFILE))
+# we can't use API_BIN_REFS for xammac_net_4_5 as it inherits from net_4_x.make
+LIB_MCS_FLAGS += -r:$(topdir)/../external/binary-reference-assemblies/build/monotouch/Xamarin.Mac.dll
+LIB_MCS_FLAGS += -d:XAMARIN_MODERN
endif
TEST_LIB_REFS = System System.Core
diff --git a/mcs/class/System.Net.Http/NSUrlSessionHandler.cs b/mcs/class/System.Net.Http/NSUrlSessionHandler.cs
deleted file mode 100644
index 17835da99f6..00000000000
--- a/mcs/class/System.Net.Http/NSUrlSessionHandler.cs
+++ /dev/null
@@ -1,896 +0,0 @@
-//
-// NSUrlSessionHandler.cs:
-//
-// Authors:
-// Paul Betts <paul@paulbetts.org>
-// Nick Berardi <nick@nickberardi.com>
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Text;
-
-#if UNIFIED
-using CoreFoundation;
-using Foundation;
-using Security;
-#else
-using MonoTouch.CoreFoundation;
-using MonoTouch.Foundation;
-using MonoTouch.Security;
-using System.Globalization;
-using nint = System.Int32;
-using nuint = System.UInt32;
-#endif
-
-#if !MONOMAC
-using UIKit;
-#endif
-
-#if SYSTEM_NET_HTTP
-namespace System.Net.Http {
-#else
-namespace Foundation {
-#endif
-
- // useful extensions for the class in order to set it in a header
- static class NSHttpCookieExtensions
- {
- static void AppendSegment(StringBuilder builder, string name, string value)
- {
- if (builder.Length > 0)
- builder.Append ("; ");
-
- builder.Append (name);
- if (value != null)
- builder.Append ("=").Append (value);
- }
-
- // returns the header for a cookie
- public static string GetHeaderValue (this NSHttpCookie cookie)
- {
- var header = new StringBuilder();
- AppendSegment (header, cookie.Name, cookie.Value);
- AppendSegment (header, NSHttpCookie.KeyPath.ToString (), cookie.Path.ToString ());
- AppendSegment (header, NSHttpCookie.KeyDomain.ToString (), cookie.Domain.ToString ());
- AppendSegment (header, NSHttpCookie.KeyVersion.ToString (), cookie.Version.ToString ());
-
- if (cookie.Comment != null)
- AppendSegment (header, NSHttpCookie.KeyComment.ToString (), cookie.Comment.ToString());
-
- if (cookie.CommentUrl != null)
- AppendSegment (header, NSHttpCookie.KeyCommentUrl.ToString (), cookie.CommentUrl.ToString());
-
- if (cookie.Properties.ContainsKey (NSHttpCookie.KeyDiscard))
- AppendSegment (header, NSHttpCookie.KeyDiscard.ToString (), null);
-
- if (cookie.ExpiresDate != null) {
- // Format according to RFC1123; 'r' uses invariant info (DateTimeFormatInfo.InvariantInfo)
- var dateStr = ((DateTime) cookie.ExpiresDate).ToUniversalTime ().ToString("r", CultureInfo.InvariantCulture);
- AppendSegment (header, NSHttpCookie.KeyExpires.ToString (), dateStr);
- }
-
- if (cookie.Properties.ContainsKey (NSHttpCookie.KeyMaximumAge)) {
- var timeStampString = (NSString) cookie.Properties[NSHttpCookie.KeyMaximumAge];
- AppendSegment (header, NSHttpCookie.KeyMaximumAge.ToString (), timeStampString);
- }
-
- if (cookie.IsSecure)
- AppendSegment (header, NSHttpCookie.KeySecure.ToString(), null);
-
- if (cookie.IsHttpOnly)
- AppendSegment (header, "httponly", null); // Apple does not show the key for the httponly
-
- return header.ToString ();
- }
- }
-
- public partial class NSUrlSessionHandler : HttpMessageHandler
- {
- private const string SetCookie = "Set-Cookie";
- readonly Dictionary<string, string> headerSeparators = new Dictionary<string, string> {
- ["User-Agent"] = " ",
- ["Server"] = " "
- };
-
- readonly NSUrlSession session;
- readonly Dictionary<NSUrlSessionTask, InflightData> inflightRequests;
- readonly object inflightRequestsLock = new object ();
-#if !MONOMAC && !MONOTOUCH_WATCH
- readonly bool isBackgroundSession = false;
- NSObject notificationToken; // needed to make sure we do not hang if not using a background session
-#endif
-
- static NSUrlSessionConfiguration CreateConfig ()
- {
- // modifying the configuration does not affect future calls
- var config = NSUrlSessionConfiguration.DefaultSessionConfiguration;
- // but we want, by default, the timeout from HttpClient to have precedence over the one from NSUrlSession
- // Double.MaxValue does not work, so default to 24 hours
- config.TimeoutIntervalForRequest = 24 * 60 * 60;
- config.TimeoutIntervalForResource = 24 * 60 * 60;
- return config;
- }
-
- public NSUrlSessionHandler () : this (CreateConfig ())
- {
- }
-
- [CLSCompliant (false)]
- public NSUrlSessionHandler (NSUrlSessionConfiguration configuration)
- {
- if (configuration == null)
- throw new ArgumentNullException (nameof (configuration));
-
-#if !MONOMAC && !MONOTOUCH_WATCH
- // if the configuration has an identifier, we are dealing with a background session,
- // therefore, we do not have to listen to the notifications.
- isBackgroundSession = !string.IsNullOrEmpty (configuration.Identifier);
-#endif
-
- AllowAutoRedirect = true;
-
- // we cannot do a bitmask but we can set the minimum based on ServicePointManager.SecurityProtocol minimum
- var sp = ServicePointManager.SecurityProtocol;
- if ((sp & SecurityProtocolType.Ssl3) != 0)
- configuration.TLSMinimumSupportedProtocol = SslProtocol.Ssl_3_0;
- else if ((sp & SecurityProtocolType.Tls) != 0)
- configuration.TLSMinimumSupportedProtocol = SslProtocol.Tls_1_0;
- else if ((sp & SecurityProtocolType.Tls11) != 0)
- configuration.TLSMinimumSupportedProtocol = SslProtocol.Tls_1_1;
- else if ((sp & SecurityProtocolType.Tls12) != 0)
- configuration.TLSMinimumSupportedProtocol = SslProtocol.Tls_1_2;
-
- session = NSUrlSession.FromConfiguration (configuration, (INSUrlSessionDelegate) new NSUrlSessionHandlerDelegate (this), null);
- inflightRequests = new Dictionary<NSUrlSessionTask, InflightData> ();
- }
-
-#if !MONOMAC && !MONOTOUCH_WATCH
-
- void AddNotification ()
- {
- if (!isBackgroundSession && notificationToken == null)
- notificationToken = NSNotificationCenter.DefaultCenter.AddObserver (UIApplication.WillResignActiveNotification, BackgroundNotificationCb);
- }
-
- void RemoveNotification ()
- {
- if (notificationToken != null) {
- NSNotificationCenter.DefaultCenter.RemoveObserver (notificationToken);
- notificationToken = null;
- }
- }
-
- void BackgroundNotificationCb (NSNotification obj)
- {
- // we do not need to call the lock, we call cancel on the source, that will trigger all the needed code to
- // clean the resources and such
- foreach (var r in inflightRequests.Values) {
- r.CompletionSource.TrySetCanceled ();
- }
- }
-#endif
-
- public long MaxInputInMemory { get; set; } = long.MaxValue;
-
- void RemoveInflightData (NSUrlSessionTask task, bool cancel = true)
- {
- lock (inflightRequestsLock) {
- if (inflightRequests.TryGetValue (task, out var data)) {
- if (cancel)
- data.CancellationTokenSource.Cancel ();
- data.Dispose ();
- inflightRequests.Remove (task);
- }
-#if !MONOMAC && !MONOTOUCH_WATCH
- // do we need to be notified? If we have not inflightData, we do not
- if (inflightRequests.Count == 0)
- RemoveNotification ();
-#endif
- }
-
- if (cancel)
- task?.Cancel ();
-
- task?.Dispose ();
- }
-
- protected override void Dispose (bool disposing)
- {
-#if !MONOMAC && !MONOTOUCH_WATCH
- // remove the notification if present, method checks against null
- RemoveNotification ();
-#endif
- lock (inflightRequestsLock) {
- foreach (var pair in inflightRequests) {
- pair.Key?.Cancel ();
- pair.Key?.Dispose ();
- pair.Value?.Dispose ();
- }
-
- inflightRequests.Clear ();
- }
- base.Dispose (disposing);
- }
-
- bool disableCaching;
-
- public bool DisableCaching {
- get {
- return disableCaching;
- }
- set {
- EnsureModifiability ();
- disableCaching = value;
- }
- }
-
- string GetHeaderSeparator (string name)
- {
- string value;
- if (!headerSeparators.TryGetValue (name, out value))
- value = ",";
- return value;
- }
-
- async Task<NSUrlRequest> CreateRequest (HttpRequestMessage request)
- {
- var stream = Stream.Null;
- var headers = request.Headers as IEnumerable<KeyValuePair<string, IEnumerable<string>>>;
-
- if (request.Content != null) {
- stream = await request.Content.ReadAsStreamAsync ().ConfigureAwait (false);
- headers = System.Linq.Enumerable.ToArray(headers.Union (request.Content.Headers));
- }
-
- var nsrequest = new NSMutableUrlRequest {
- AllowsCellularAccess = true,
- CachePolicy = DisableCaching ? NSUrlRequestCachePolicy.ReloadIgnoringCacheData : NSUrlRequestCachePolicy.UseProtocolCachePolicy,
- HttpMethod = request.Method.ToString ().ToUpperInvariant (),
- Url = NSUrl.FromString (request.RequestUri.AbsoluteUri),
- Headers = headers.Aggregate (new NSMutableDictionary (), (acc, x) => {
- acc.Add (new NSString (x.Key), new NSString (string.Join (GetHeaderSeparator (x.Key), x.Value)));
- return acc;
- })
- };
- if (stream != Stream.Null) {
- // HttpContent.TryComputeLength is `protected internal` :-( but it's indirectly called by headers
- var length = request.Content.Headers.ContentLength;
- if (length.HasValue && (length <= MaxInputInMemory))
- nsrequest.Body = NSData.FromStream (stream);
- else
- nsrequest.BodyStream = new WrappedNSInputStream (stream);
- }
- return nsrequest;
- }
-
-#if SYSTEM_NET_HTTP || MONOMAC
- internal
-#endif
- protected override async Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
- {
- Volatile.Write (ref sentRequest, true);
-
- var nsrequest = await CreateRequest (request).ConfigureAwait(false);
- var dataTask = session.CreateDataTask (nsrequest);
-
- var tcs = new TaskCompletionSource<HttpResponseMessage> ();
-
- lock (inflightRequestsLock) {
-#if !MONOMAC && !MONOTOUCH_WATCH
- // Add the notification whenever needed
- AddNotification ();
-#endif
- inflightRequests.Add (dataTask, new InflightData {
- RequestUrl = request.RequestUri.AbsoluteUri,
- CompletionSource = tcs,
- CancellationToken = cancellationToken,
- CancellationTokenSource = new CancellationTokenSource (),
- Stream = new NSUrlSessionDataTaskStream (),
- Request = request
- });
- }
-
- if (dataTask.State == NSUrlSessionTaskState.Suspended)
- dataTask.Resume ();
-
- // as per documentation:
- // If this token is already in the canceled state, the
- // delegate will be run immediately and synchronously.
- // Any exception the delegate generates will be
- // propagated out of this method call.
- //
- // The execution of the register ensures that if we
- // receive a already cancelled token or it is cancelled
- // just before this call, we will cancel the task.
- // Other approaches are harder, since querying the state
- // of the token does not guarantee that in the next
- // execution a threads cancels it.
- cancellationToken.Register (() => {
- RemoveInflightData (dataTask);
- tcs.TrySetCanceled ();
- });
-
- return await tcs.Task.ConfigureAwait (false);
- }
-
-#if MONOMAC
- // Needed since we strip during linking since we're inside a product assembly.
- [Preserve (AllMembers = true)]
-#endif
- partial class NSUrlSessionHandlerDelegate : NSUrlSessionDataDelegate
- {
- readonly NSUrlSessionHandler sessionHandler;
-
- public NSUrlSessionHandlerDelegate (NSUrlSessionHandler handler)
- {
- sessionHandler = handler;
- }
-
- InflightData GetInflightData (NSUrlSessionTask task)
- {
- var inflight = default (InflightData);
-
- lock (sessionHandler.inflightRequestsLock)
- if (sessionHandler.inflightRequests.TryGetValue (task, out inflight)) {
- // ensure that we did not cancel the request, if we did, do cancel the task
- if (inflight.CancellationToken.IsCancellationRequested)
- task?.Cancel ();
- return inflight;
- }
-
- // if we did not manage to get the inflight data, we either got an error or have been canceled, lets cancel the task, that will execute DidCompleteWithError
- task?.Cancel ();
- return null;
- }
-
- public override void DidReceiveResponse (NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler)
- {
- var inflight = GetInflightData (dataTask);
-
- if (inflight == null)
- return;
-
- try {
- var urlResponse = (NSHttpUrlResponse)response;
- var status = (int)urlResponse.StatusCode;
-
- var content = new NSUrlSessionDataTaskStreamContent (inflight.Stream, () => {
- if (!inflight.Completed) {
- dataTask.Cancel ();
- }
-
- inflight.Disposed = true;
- inflight.Stream.TrySetException (new ObjectDisposedException ("The content stream was disposed."));
-
- sessionHandler.RemoveInflightData (dataTask);
- }, inflight.CancellationTokenSource.Token);
-
- // NB: The double cast is because of a Xamarin compiler bug
- var httpResponse = new HttpResponseMessage ((HttpStatusCode)status) {
- Content = content,
- RequestMessage = inflight.Request
- };
- httpResponse.RequestMessage.RequestUri = new Uri (urlResponse.Url.AbsoluteString);
-
- foreach (var v in urlResponse.AllHeaderFields) {
- // NB: Cocoa trolling us so hard by giving us back dummy dictionary entries
- if (v.Key == null || v.Value == null) continue;
- // NSUrlSession tries to be smart with cookies, we will not use the raw value but the ones provided by the cookie storage
- if (v.Key.ToString () == SetCookie) continue;
-
- httpResponse.Headers.TryAddWithoutValidation (v.Key.ToString (), v.Value.ToString ());
- httpResponse.Content.Headers.TryAddWithoutValidation (v.Key.ToString (), v.Value.ToString ());
- }
-
- var cookies = session.Configuration.HttpCookieStorage.CookiesForUrl (response.Url);
- for (var index = 0; index < cookies.Length; index++) {
- httpResponse.Headers.TryAddWithoutValidation (SetCookie, cookies [index].GetHeaderValue ());
- }
-
- inflight.Response = httpResponse;
-
- // We don't want to send the response back to the task just yet. Because we want to mimic .NET behavior
- // as much as possible. When the response is sent back in .NET, the content stream is ready to read or the
- // request has completed, because of this we want to send back the response in DidReceiveData or DidCompleteWithError
- if (dataTask.State == NSUrlSessionTaskState.Suspended)
- dataTask.Resume ();
-
- } catch (Exception ex) {
- inflight.CompletionSource.TrySetException (ex);
- inflight.Stream.TrySetException (ex);
-
- sessionHandler.RemoveInflightData (dataTask);
- }
-
- completionHandler (NSUrlSessionResponseDisposition.Allow);
- }
-
- public override void DidReceiveData (NSUrlSession session, NSUrlSessionDataTask dataTask, NSData data)
- {
- var inflight = GetInflightData (dataTask);
-
- if (inflight == null)
- return;
-
- inflight.Stream.Add (data);
- SetResponse (inflight);
- }
-
- public override void DidCompleteWithError (NSUrlSession session, NSUrlSessionTask task, NSError error)
- {
- var inflight = GetInflightData (task);
-
- // this can happen if the HTTP request times out and it is removed as part of the cancellation process
- if (inflight != null) {
- // set the stream as finished
- inflight.Stream.TrySetReceivedAllData ();
-
- // send the error or send the response back
- if (error != null) {
- // got an error, cancel the stream operatios before we do anything
- inflight.CancellationTokenSource.Cancel ();
- inflight.Errored = true;
-
- var exc = createExceptionForNSError (error);
- inflight.CompletionSource.TrySetException (exc);
- inflight.Stream.TrySetException (exc);
- } else {
- inflight.Completed = true;
- SetResponse (inflight);
- }
-
- sessionHandler.RemoveInflightData (task, cancel: false);
- }
- }
-
- void SetResponse (InflightData inflight)
- {
- lock (inflight.Lock) {
- if (inflight.ResponseSent)
- return;
-
- if (inflight.CancellationTokenSource.Token.IsCancellationRequested)
- return;
-
- if (inflight.CompletionSource.Task.IsCompleted)
- return;
-
- var httpResponse = inflight.Response;
-
- inflight.ResponseSent = true;
-
- // EVIL HACK: having TrySetResult inline was blocking the request from completing
- Task.Run (() => inflight.CompletionSource.TrySetResult (httpResponse));
- }
- }
-
- public override void WillCacheResponse (NSUrlSession session, NSUrlSessionDataTask dataTask, NSCachedUrlResponse proposedResponse, Action<NSCachedUrlResponse> completionHandler)
- {
- completionHandler (sessionHandler.DisableCaching ? null : proposedResponse);
- }
-
- public override void WillPerformHttpRedirection (NSUrlSession session, NSUrlSessionTask task, NSHttpUrlResponse response, NSUrlRequest newRequest, Action<NSUrlRequest> completionHandler)
- {
- completionHandler (sessionHandler.AllowAutoRedirect ? newRequest : null);
- }
-
- public override void DidReceiveChallenge (NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
- {
- var inflight = GetInflightData (task);
-
- if (inflight == null)
- return;
-
- // case for the basic auth failing up front. As per apple documentation:
- // The URL Loading System is designed to handle various aspects of the HTTP protocol for you. As a result, you should not modify the following headers using
- // the addValue(_:forHTTPHeaderField:) or setValue(_:forHTTPHeaderField:) methods:
- // Authorization
- // Connection
- // Host
- // Proxy-Authenticate
- // Proxy-Authorization
- // WWW-Authenticate
- // but we are hiding such a situation from our users, we can nevertheless know if the header was added and deal with it. The idea is as follows,
- // check if we are in the first attempt, if we are (PreviousFailureCount == 0), we check the headers of the request and if we do have the Auth
- // header, it means that we do not have the correct credentials, in any other case just do what it is expected.
-
- if (challenge.PreviousFailureCount == 0) {
- var authHeader = inflight.Request?.Headers?.Authorization;
- if (!(string.IsNullOrEmpty (authHeader?.Scheme) && string.IsNullOrEmpty (authHeader?.Parameter))) {
- completionHandler (NSUrlSessionAuthChallengeDisposition.RejectProtectionSpace, null);
- return;
- }
- }
-
- if (sessionHandler.Credentials != null && TryGetAuthenticationType (challenge.ProtectionSpace, out string authType)) {
- NetworkCredential credentialsToUse = null;
- if (authType != RejectProtectionSpaceAuthType) {
- var uri = inflight.Request.RequestUri;
- credentialsToUse = sessionHandler.Credentials.GetCredential (uri, authType);
- }
-
- if (credentialsToUse != null) {
- var credential = new NSUrlCredential (credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession);
- completionHandler (NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
- } else {
- // Rejecting the challenge allows the next authentication method in the request to be delivered to
- // the DidReceiveChallenge method. Another authentication method may have credentials available.
- completionHandler (NSUrlSessionAuthChallengeDisposition.RejectProtectionSpace, null);
- }
- } else {
- completionHandler (NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential);
- }
- }
-
- static readonly string RejectProtectionSpaceAuthType = "reject";
-
- static bool TryGetAuthenticationType (NSUrlProtectionSpace protectionSpace, out string authenticationType)
- {
- if (protectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM) {
- authenticationType = "NTLM";
- } else if (protectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodHTTPBasic) {
- authenticationType = "basic";
- } else if (protectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNegotiate ||
- protectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodHTMLForm ||
- protectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodHTTPDigest) {
- // Want to reject this authentication type to allow the next authentication method in the request to
- // be used.
- authenticationType = RejectProtectionSpaceAuthType;
- } else {
- // ServerTrust, ClientCertificate or Default.
- authenticationType = null;
- return false;
- }
- return true;
- }
- }
-
-#if MONOMAC
- // Needed since we strip during linking since we're inside a product assembly.
- [Preserve (AllMembers = true)]
-#endif
- class InflightData : IDisposable
- {
- public readonly object Lock = new object ();
- public string RequestUrl { get; set; }
-
- public TaskCompletionSource<HttpResponseMessage> CompletionSource { get; set; }
- public CancellationToken CancellationToken { get; set; }
- public CancellationTokenSource CancellationTokenSource { get; set; }
- public NSUrlSessionDataTaskStream Stream { get; set; }
- public HttpRequestMessage Request { get; set; }
- public HttpResponseMessage Response { get; set; }
-
- public bool ResponseSent { get; set; }
- public bool Errored { get; set; }
- public bool Disposed { get; set; }
- public bool Completed { get; set; }
- public bool Done { get { return Errored || Disposed || Completed || CancellationToken.IsCancellationRequested; } }
-
- public void Dispose()
- {
- Dispose (true);
- GC.SuppressFinalize(this);
- }
-
- // The bulk of the clean-up code is implemented in Dispose(bool)
- protected virtual void Dispose (bool disposing)
- {
- if (disposing) {
- if (CancellationTokenSource != null) {
- CancellationTokenSource.Dispose ();
- CancellationTokenSource = null;
- }
- }
- }
-
- }
-
-#if MONOMAC
- // Needed since we strip during linking since we're inside a product assembly.
- [Preserve (AllMembers = true)]
-#endif
- class NSUrlSessionDataTaskStreamContent : StreamContent
- {
- Action disposed;
-
- public NSUrlSessionDataTaskStreamContent (NSUrlSessionDataTaskStream source, Action onDisposed, CancellationToken token) : base (source, token)
- {
- disposed = onDisposed;
- }
-
- protected override void Dispose (bool disposing)
- {
- var action = Interlocked.Exchange (ref disposed, null);
- action?.Invoke ();
-
- base.Dispose (disposing);
- }
- }
-
-#if MONOMAC
- // Needed since we strip during linking since we're inside a product assembly.
- [Preserve (AllMembers = true)]
-#endif
- class NSUrlSessionDataTaskStream : Stream
- {
- readonly Queue<NSData> data;
- readonly object dataLock = new object ();
-
- long position;
- long length;
-
- bool receivedAllData;
- Exception exc;
-
- NSData current;
- Stream currentStream;
-
- public NSUrlSessionDataTaskStream ()
- {
- data = new Queue<NSData> ();
- }
-
- public void Add (NSData d)
- {
- lock (dataLock) {
- data.Enqueue (d);
- length += (int)d.Length;
- }
- }
-
- public void TrySetReceivedAllData ()
- {
- receivedAllData = true;
- }
-
- public void TrySetException (Exception e)
- {
- exc = e;
- TrySetReceivedAllData ();
- }
-
- void ThrowIfNeeded (CancellationToken cancellationToken)
- {
- if (exc != null)
- throw exc;
-
- cancellationToken.ThrowIfCancellationRequested ();
- }
-
- public override int Read (byte [] buffer, int offset, int count)
- {
- return ReadAsync (buffer, offset, count).Result;
- }
-
- public override async Task<int> ReadAsync (byte [] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- // try to throw on enter
- ThrowIfNeeded (cancellationToken);
-
- while (current == null) {
- lock (dataLock) {
- if (data.Count == 0 && receivedAllData && position == length)
- return 0;
-
- if (data.Count > 0 && current == null) {
- current = data.Peek ();
- currentStream = current.AsStream ();
- break;
- }
- }
-
- try {
- await Task.Delay (50, cancellationToken).ConfigureAwait (false);
- } catch (TaskCanceledException ex) {
- // add a nicer exception for the user to catch, add the cancelation exception
- // to have a decent stack
- throw new TimeoutException ("The request timed out.", ex);
- }
- }
-
- // try to throw again before read
- ThrowIfNeeded (cancellationToken);
-
- var d = currentStream;
- var bufferCount = Math.Min (count, (int)(d.Length - d.Position));
- var bytesRead = await d.ReadAsync (buffer, offset, bufferCount, cancellationToken).ConfigureAwait (false);
-
- // add the bytes read from the pointer to the position
- position += bytesRead;
-
- // remove the current primary reference if the current position has reached the end of the bytes
- if (d.Position == d.Length) {
- lock (dataLock) {
- // this is the same object, it was done to make the cleanup
- data.Dequeue ();
- currentStream?.Dispose ();
- // We cannot use current?.Dispose. The reason is the following one:
- // In the DidReceiveResponse, if iOS realizes that a buffer can be reused,
- // because the data is the same, it will do so. Such a situation does happen
- // between requests, that is, request A and request B will get the same NSData
- // (buffer) in the delegate. In this case, we cannot dispose the NSData because
- // it might be that a different request received it and it is present in
- // its NSUrlSessionDataTaskStream stream. We can only trust the gc to do the job
- // which is better than copying the data over.
- current = null;
- currentStream = null;
- }
- }
-
- return bytesRead;
- }
-
- public override bool CanRead => true;
-
- public override bool CanSeek => false;
-
- public override bool CanWrite => false;
-
- public override bool CanTimeout => false;
-
- public override long Length => length;
-
- public override void SetLength (long value)
- {
- throw new InvalidOperationException ();
- }
-
- public override long Position {
- get { return position; }
- set { throw new InvalidOperationException (); }
- }
-
- public override long Seek (long offset, SeekOrigin origin)
- {
- throw new InvalidOperationException ();
- }
-
- public override void Flush ()
- {
- throw new InvalidOperationException ();
- }
-
- public override void Write (byte [] buffer, int offset, int count)
- {
- throw new InvalidOperationException ();
- }
- }
-
-#if MONOMAC
- // Needed since we strip during linking since we're inside a product assembly.
- [Preserve (AllMembers = true)]
-#endif
- class WrappedNSInputStream : NSInputStream
- {
- NSStreamStatus status;
- CFRunLoopSource source;
- readonly Stream stream;
- bool notifying;
-
- public WrappedNSInputStream (Stream inputStream)
- {
- status = NSStreamStatus.NotOpen;
- stream = inputStream;
- source = new CFRunLoopSource (Handle);
- }
-
- public override NSStreamStatus Status => status;
-
- public override void Open ()
- {
- status = NSStreamStatus.Open;
- Notify (CFStreamEventType.OpenCompleted);
- }
-
- public override void Close ()
- {
- status = NSStreamStatus.Closed;
- }
-
- public override nint Read (IntPtr buffer, nuint len)
- {
- var sourceBytes = new byte [len];
- var read = stream.Read (sourceBytes, 0, (int)len);
- Marshal.Copy (sourceBytes, 0, buffer, (int)len);
-
- if (notifying)
- return read;
-
- notifying = true;
- if (stream.CanSeek && stream.Position == stream.Length) {
- Notify (CFStreamEventType.EndEncountered);
- status = NSStreamStatus.AtEnd;
- }
- notifying = false;
-
- return read;
- }
-
- public override bool HasBytesAvailable ()
- {
- return true;
- }
-
- protected override bool GetBuffer (out IntPtr buffer, out nuint len)
- {
- // Just call the base implemention (which will return false)
- return base.GetBuffer (out buffer, out len);
- }
-
- // NSInvalidArgumentException Reason: *** -propertyForKey: only defined for abstract class. Define -[System_Net_Http_NSUrlSessionHandler_WrappedNSInputStream propertyForKey:]!
- protected override NSObject GetProperty (NSString key)
- {
- return null;
- }
-
- protected override bool SetProperty (NSObject property, NSString key)
- {
- return false;
- }
-
- protected override bool SetCFClientFlags (CFStreamEventType inFlags, IntPtr inCallback, IntPtr inContextPtr)
- {
- // Just call the base implementation, which knows how to handle everything.
- return base.SetCFClientFlags (inFlags, inCallback, inContextPtr);
- }
-
- public override void Schedule (NSRunLoop aRunLoop, string mode)
- {
- var cfRunLoop = aRunLoop.GetCFRunLoop ();
- var nsMode = new NSString (mode);
-
- cfRunLoop.AddSource (source, nsMode);
-
- if (notifying)
- return;
-
- notifying = true;
- Notify (CFStreamEventType.HasBytesAvailable);
- notifying = false;
- }
-
- public override void Unschedule (NSRunLoop aRunLoop, string mode)
- {
- var cfRunLoop = aRunLoop.GetCFRunLoop ();
- var nsMode = new NSString (mode);
-
- cfRunLoop.RemoveSource (source, nsMode);
- }
-
- protected override void Dispose (bool disposing)
- {
- stream?.Dispose ();
- }
- }
- }
-}
diff --git a/mcs/class/System.Net.Http/RuntimeOptions.cs b/mcs/class/System.Net.Http/RuntimeOptions.cs
deleted file mode 100644
index 6e4c152ca0e..00000000000
--- a/mcs/class/System.Net.Http/RuntimeOptions.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-using System;
-using System.IO;
-using System.Text;
-using System.Net.Http;
-
-#if XAMCORE_2_0
-using Foundation;
-using ObjCRuntime;
-#elif MONOMAC
-using MonoMac.Foundation;
-using MonoMac.ObjCRuntime;
-#else
-#error Unknown platform
-#endif
-
-namespace System.Net.Http {
- class RuntimeOptions
- {
- const string HttpClientHandlerValue = "HttpClientHandler";
- const string CFNetworkHandlerValue = "CFNetworkHandler";
- const string NSUrlSessionHandlerValue = "NSUrlSessionHandler";
-
- const string DefaultTlsProviderValue = "default";
- const string LegacyTlsProviderValue = "legacy";
- const string AppleTlsProviderValue = "appletls";
-
- string http_message_handler;
-
-
- internal static RuntimeOptions Read ()
- {
- // for iOS NSBundle.ResourcePath returns the path to the root of the app bundle
- // for macOS apps NSBundle.ResourcePath returns foo.app/Contents/Resources
- // for macOS frameworks NSBundle.ResourcePath returns foo.app/Versions/Current/Resources
- Class bundle_finder = new Class (typeof (NSObject.NSObject_Disposer));
- var resource_dir = NSBundle.FromClass (bundle_finder).ResourcePath;
- var plist_path = GetFileName (resource_dir);
-
- if (!File.Exists (plist_path))
- return null;
-
- using (var plist = NSDictionary.FromFile (plist_path)) {
- var options = new RuntimeOptions ();
- options.http_message_handler = (NSString) plist ["HttpMessageHandler"];
- return options;
- }
- }
-
-#if MONOMAC
- [Preserve]
-#endif
- internal static HttpMessageHandler GetHttpMessageHandler ()
- {
- RuntimeOptions options = null;
-
- try {
- options = RuntimeOptions.Read ();
- } catch (FileNotFoundException){
- // this happens on the Mono SDKs since we don't have a real Xamarin.iOS.dll so we can't resolve NSObject
- }
-
- if (options == null) {
-#if MONOTOUCH_WATCH
- return new NSUrlSessionHandler ();
-#else
- return new HttpClientHandler ();
-#endif
- }
-
- // all types will be present as this is executed only when the linker is not enabled
- var handler_name = options.http_message_handler;
- var t = Type.GetType (handler_name, false);
-
- HttpMessageHandler handler = null;
- if (t != null)
- handler = Activator.CreateInstance (t) as HttpMessageHandler;
- if (handler != null)
- return handler;
-#if MONOTOUCH_WATCH
- Console.WriteLine ("{0} is not a valid HttpMessageHandler, defaulting to NSUrlSessionHandler", handler_name);
- return new NSUrlSessionHandler ();
-#else
- Console.WriteLine ("{0} is not a valid HttpMessageHandler, defaulting to System.Net.Http.HttpClientHandler", handler_name);
- return new HttpClientHandler ();
-#endif
- }
-
- // Use either Create() or Read().
- RuntimeOptions ()
- {
- }
-
- static string GetFileName (string resource_dir)
- {
- return Path.Combine (resource_dir, "runtime-options.plist");
- }
- }
-}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.csproj b/mcs/class/System.Net.Http/System.Net.Http.csproj
index 911e9419817..3fa5bd74f60 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.csproj
+++ b/mcs/class/System.Net.Http/System.Net.Http.csproj
@@ -39,17 +39,17 @@
<PropertyGroup Condition=" '$(Platform)' == 'monotouch' ">
<OutputPath>./../../class/lib/monotouch</OutputPath>
<IntermediateOutputPath>./../../class/obj/$(AssemblyName)-monotouch</IntermediateOutputPath>
- <DefineConstants>NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_REMOTING;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;XAMCORE_2_0;XAMARIN_MODERN;SYSTEM_NET_HTTP;UNIFIED;__UNIFIED__</DefineConstants>
+ <DefineConstants>NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_REMOTING;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;XAMARIN_MODERN</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'monotouch_watch' ">
<OutputPath>./../../class/lib/monotouch_watch</OutputPath>
<IntermediateOutputPath>./../../class/obj/$(AssemblyName)-monotouch_watch</IntermediateOutputPath>
- <DefineConstants>NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_REMOTING;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;FEATURE_NO_BSD_SOCKETS;MONOTOUCH_WATCH;XAMCORE_2_0;XAMARIN_MODERN;SYSTEM_NET_HTTP;UNIFIED;__UNIFIED__</DefineConstants>
+ <DefineConstants>NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_REMOTING;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;FEATURE_NO_BSD_SOCKETS;MONOTOUCH_WATCH;XAMARIN_MODERN</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'monotouch_tv' ">
<OutputPath>./../../class/lib/monotouch_tv</OutputPath>
<IntermediateOutputPath>./../../class/obj/$(AssemblyName)-monotouch_tv</IntermediateOutputPath>
- <DefineConstants>NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_REMOTING;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;MONOTOUCH_TV;XAMCORE_2_0;XAMARIN_MODERN;SYSTEM_NET_HTTP;UNIFIED;__UNIFIED__</DefineConstants>
+ <DefineConstants>NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MOBILE;MOBILE_LEGACY;MONO;MONOTOUCH;DISABLE_REMOTING;DISABLE_COM;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;FULL_AOT_RUNTIME;MONOTOUCH_TV;XAMARIN_MODERN</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'testing_aot_full_interp' ">
<OutputPath>./../../class/lib/testing_aot_full_interp</OutputPath>
@@ -74,12 +74,12 @@
<PropertyGroup Condition=" '$(Platform)' == 'xammac' ">
<OutputPath>./../../class/lib/xammac</OutputPath>
<IntermediateOutputPath>./../../class/obj/$(AssemblyName)-xammac</IntermediateOutputPath>
- <DefineConstants>NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_DYNAMIC;XAMMAC;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;XAMARIN_MODERN</DefineConstants>
+ <DefineConstants>NET_1_1;NET_2_0;NET_2_1;NET_3_5;NET_4_0;NET_4_5;MONO;MOBILE;MOBILE_DYNAMIC;XAMMAC;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;XAMARIN_MODERN;XAMARIN_MODERN</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'xammac_net_4_5' ">
<OutputPath>./../../class/lib/xammac_net_4_5</OutputPath>
<IntermediateOutputPath>./../../class/obj/$(AssemblyName)-xammac_net_4_5</IntermediateOutputPath>
- <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;NO_SYSTEM_DRAWING_DEPENDENCY;NO_WINFORMS_DEPENDENCY;NO_SYSTEM_WEB_DEPENDENCY;XAMMAC_4_5;XAMARIN_MODERN</DefineConstants>
+ <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK;NO_SYSTEM_DRAWING_DEPENDENCY;NO_WINFORMS_DEPENDENCY;NO_SYSTEM_WEB_DEPENDENCY;XAMMAC_4_5;XAMARIN_MODERN;XAMARIN_MODERN</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'orbis' ">
<OutputPath>./../../class/lib/orbis</OutputPath>
@@ -164,7 +164,7 @@
<Compile Include="System.Net.Http\DelegatingHandler.cs" />
<Compile Include="System.Net.Http\FormUrlEncodedContent.cs" />
<Compile Include="System.Net.Http\HttpClient.cs" />
- <Compile Include="System.Net.Http\HttpClient.mac.cs" />
+ <Compile Include="System.Net.Http\HttpClient.macios.cs" />
<Compile Include="System.Net.Http\HttpCompletionOption.cs" />
<Compile Include="System.Net.Http\HttpContent.cs" />
<Compile Include="System.Net.Http\HttpMessageHandler.cs" />
@@ -873,10 +873,7 @@
</When>
<When Condition="'$(Platform)' == 'monotouch_watch'">
<ItemGroup>
- <Compile Include="HttpClientEx.cs" />
- <Compile Include="NSUrlSessionHandler.cs" />
<Compile Include="PlatformHelper.Legacy.cs" />
- <Compile Include="RuntimeOptions.cs" />
<Compile Include="System.Net.Http.Headers\AuthenticationHeaderValue.cs" />
<Compile Include="System.Net.Http.Headers\CacheControlHeaderValue.cs" />
<Compile Include="System.Net.Http.Headers\CollectionExtensions.cs" />
@@ -915,6 +912,7 @@
<Compile Include="System.Net.Http\DelegatingHandler.cs" />
<Compile Include="System.Net.Http\FormUrlEncodedContent.cs" />
<Compile Include="System.Net.Http\HttpClient.cs" />
+ <Compile Include="System.Net.Http\HttpClient.macios.cs" />
<Compile Include="System.Net.Http\HttpClientHandler.platformnotsupported.cs" />
<Compile Include="System.Net.Http\HttpCompletionOption.cs" />
<Compile Include="System.Net.Http\HttpContent.cs" />
@@ -936,16 +934,11 @@
<ItemGroup>
<Compile Include="..\..\..\external\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\CancellationHelper.cs" />
<Compile Include="..\..\..\external\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\ConnectHelper.cs" />
- <Compile Include="CFContentStream.cs" />
- <Compile Include="CFNetworkHandler.cs" />
- <Compile Include="HttpClientEx.cs" />
<Compile Include="HttpClientHandler.Legacy.cs" />
<Compile Include="HttpClientHandler.cs" />
<Compile Include="IMonoHttpClientHandler.cs" />
<Compile Include="MonoWebRequestHandler.cs" />
- <Compile Include="NSUrlSessionHandler.cs" />
<Compile Include="PlatformHelper.Legacy.cs" />
- <Compile Include="RuntimeOptions.cs" />
<Compile Include="System.Net.Http.Headers\AuthenticationHeaderValue.cs" />
<Compile Include="System.Net.Http.Headers\CacheControlHeaderValue.cs" />
<Compile Include="System.Net.Http.Headers\CollectionExtensions.cs" />
@@ -984,6 +977,7 @@
<Compile Include="System.Net.Http\DelegatingHandler.cs" />
<Compile Include="System.Net.Http\FormUrlEncodedContent.cs" />
<Compile Include="System.Net.Http\HttpClient.cs" />
+ <Compile Include="System.Net.Http\HttpClient.macios.cs" />
<Compile Include="System.Net.Http\HttpCompletionOption.cs" />
<Compile Include="System.Net.Http\HttpContent.cs" />
<Compile Include="System.Net.Http\HttpMessageHandler.cs" />
@@ -1004,16 +998,11 @@
<ItemGroup>
<Compile Include="..\..\..\external\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\CancellationHelper.cs" />
<Compile Include="..\..\..\external\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\ConnectHelper.cs" />
- <Compile Include="CFContentStream.cs" />
- <Compile Include="CFNetworkHandler.cs" />
- <Compile Include="HttpClientEx.cs" />
<Compile Include="HttpClientHandler.Legacy.cs" />
<Compile Include="HttpClientHandler.cs" />
<Compile Include="IMonoHttpClientHandler.cs" />
<Compile Include="MonoWebRequestHandler.cs" />
- <Compile Include="NSUrlSessionHandler.cs" />
<Compile Include="PlatformHelper.Legacy.cs" />
- <Compile Include="RuntimeOptions.cs" />
<Compile Include="System.Net.Http.Headers\AuthenticationHeaderValue.cs" />
<Compile Include="System.Net.Http.Headers\CacheControlHeaderValue.cs" />
<Compile Include="System.Net.Http.Headers\CollectionExtensions.cs" />
@@ -1052,6 +1041,7 @@
<Compile Include="System.Net.Http\DelegatingHandler.cs" />
<Compile Include="System.Net.Http\FormUrlEncodedContent.cs" />
<Compile Include="System.Net.Http\HttpClient.cs" />
+ <Compile Include="System.Net.Http\HttpClient.macios.cs" />
<Compile Include="System.Net.Http\HttpCompletionOption.cs" />
<Compile Include="System.Net.Http\HttpContent.cs" />
<Compile Include="System.Net.Http\HttpMessageHandler.cs" />
@@ -1231,6 +1221,20 @@
<Private>False</Private>
</Reference>
</ItemGroup>
+ <ItemGroup Condition=" '$(Platform)' == 'xammac' ">
+ <Reference Include="./../../../external/binary-reference-assemblies/build/monotouch/Xamarin.Mac.dll">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>./../../../external/binary-reference-assemblies/build/monotouch/Xamarin.Mac.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup Condition=" '$(Platform)' == 'xammac_net_4_5' ">
+ <Reference Include="./../../../external/binary-reference-assemblies/build/monotouch/Xamarin.Mac.dll">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>./../../../external/binary-reference-assemblies/build/monotouch/Xamarin.Mac.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
+ </ItemGroup>
<!-- @ALL_REFERENCES@ -->
<!-- @ALL_RESOURCES@ -->
<PropertyGroup>
diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClient.mac.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.mac.cs
deleted file mode 100644
index 42f664c0ed3..00000000000
--- a/mcs/class/System.Net.Http/System.Net.Http/HttpClient.mac.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Reflection;
-
-[assembly:System.Runtime.CompilerServices.InternalsVisibleTo ("Xamarin.Mac, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")]
-
-namespace System.Net.Http {
- public partial class HttpClient {
-
- public HttpClient ()
- : this (GetDefaultHandler (), true)
- {
- }
-
- // note: the linker will re-write ObjCRuntime.RuntimeOptions.GetHttpMessageHandler to return the correct type
- // unlike, XI where this method itself gets rewritten during linking
- static HttpMessageHandler GetDefaultHandler ()
- {
- Type type = Type.GetType("ObjCRuntime.RuntimeOptions, Xamarin.Mac");
- var method = type.GetMethod ("GetHttpMessageHandler", BindingFlags.Static | BindingFlags.NonPublic);
- return (HttpMessageHandler)method.Invoke (null, null);
- }
- }
-}
diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClient.macios.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.macios.cs
new file mode 100644
index 00000000000..a60a7941b23
--- /dev/null
+++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.macios.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Reflection;
+
+namespace System.Net.Http {
+ public partial class HttpClient {
+
+ public HttpClient ()
+ : this (CreateDefaultHandler ())
+ {
+ }
+
+ static HttpMessageHandler CreateDefaultHandler ()
+ {
+ return ObjCRuntime.RuntimeOptions.GetHttpMessageHandler ();
+ }
+ }
+}
diff --git a/mcs/class/System.Net.Http/monotouch_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/monotouch_System.Net.Http.dll.sources
index 64cdbb68748..f4de7b4ea31 100644
--- a/mcs/class/System.Net.Http/monotouch_System.Net.Http.dll.sources
+++ b/mcs/class/System.Net.Http/monotouch_System.Net.Http.dll.sources
@@ -1,6 +1,2 @@
#include legacy.sources
-CFContentStream.cs
-CFNetworkHandler.cs
-HttpClientEx.cs
-NSUrlSessionHandler.cs
-RuntimeOptions.cs
+System.Net.Http/HttpClient.macios.cs
diff --git a/mcs/class/System.Net.Http/monotouch_runtime_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/monotouch_runtime_System.Net.Http.dll.sources
index 704cd9f69ab..f4de7b4ea31 100644
--- a/mcs/class/System.Net.Http/monotouch_runtime_System.Net.Http.dll.sources
+++ b/mcs/class/System.Net.Http/monotouch_runtime_System.Net.Http.dll.sources
@@ -1 +1,2 @@
#include legacy.sources
+System.Net.Http/HttpClient.macios.cs
diff --git a/mcs/class/System.Net.Http/monotouch_tv_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/monotouch_tv_System.Net.Http.dll.sources
index 64cdbb68748..f4de7b4ea31 100644
--- a/mcs/class/System.Net.Http/monotouch_tv_System.Net.Http.dll.sources
+++ b/mcs/class/System.Net.Http/monotouch_tv_System.Net.Http.dll.sources
@@ -1,6 +1,2 @@
#include legacy.sources
-CFContentStream.cs
-CFNetworkHandler.cs
-HttpClientEx.cs
-NSUrlSessionHandler.cs
-RuntimeOptions.cs
+System.Net.Http/HttpClient.macios.cs
diff --git a/mcs/class/System.Net.Http/monotouch_watch_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/monotouch_watch_System.Net.Http.dll.sources
index c8cb6acafb1..8f6e9ebbc19 100644
--- a/mcs/class/System.Net.Http/monotouch_watch_System.Net.Http.dll.sources
+++ b/mcs/class/System.Net.Http/monotouch_watch_System.Net.Http.dll.sources
@@ -1,5 +1,3 @@
#include legacy.sources
System.Net.Http/HttpClientHandler.platformnotsupported.cs
-HttpClientEx.cs
-NSUrlSessionHandler.cs
-RuntimeOptions.cs
+System.Net.Http/HttpClient.macios.cs
diff --git a/mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources
index c2f4a641674..f4de7b4ea31 100644
--- a/mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources
+++ b/mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources
@@ -1,2 +1,2 @@
#include legacy.sources
-System.Net.Http/HttpClient.mac.cs
+System.Net.Http/HttpClient.macios.cs
diff --git a/mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources
index c2f4a641674..f4de7b4ea31 100644
--- a/mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources
+++ b/mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources
@@ -1,2 +1,2 @@
#include legacy.sources
-System.Net.Http/HttpClient.mac.cs
+System.Net.Http/HttpClient.macios.cs