You've already forked linux-packaging-mono
Imported Upstream version 5.12.0.220
Former-commit-id: c477e03582759447177c6d4bf412cd2355aad476
This commit is contained in:
parent
8bd104cef2
commit
8fc30896db
@@ -20,14 +20,16 @@ RESX_RESOURCE_STRING = \
|
||||
../../../external/corefx/src/System.Buffers/src/Resources/Strings.resx \
|
||||
../../../external/corefx/src/System.Private.Uri/src/Resources/Strings.resx \
|
||||
../../../external/corefx/src/System.IO.Ports/src/Resources/Strings.resx \
|
||||
../../../external/corefx/src/System.Net.HttpListener/src/Resources/Strings.resx
|
||||
../../../external/corefx/src/System.Net.HttpListener/src/Resources/Strings.resx \
|
||||
../../../external/corefx/src/System.Net.Requests/src/Resources/Strings.resx
|
||||
|
||||
TEST_RESOURCES = \
|
||||
Test/System/test-uri-props.txt \
|
||||
Test/System/test-uri-props-manual.txt \
|
||||
Test/System/test-uri-relative-props.txt
|
||||
|
||||
XTEST_LIB_REFS = System System.Core Facades/System.Threading.Tasks Facades/System.Runtime.InteropServices.RuntimeInformation
|
||||
USE_XTEST_REMOTE_EXECUTOR = YES
|
||||
XTEST_LIB_REFS = System System.Core System.Net Facades/System.Threading.Tasks Facades/System.Runtime.InteropServices.RuntimeInformation System.Net.Http
|
||||
LIB_MCS_FLAGS = -d:CONFIGURATION_2_0 $(REFERENCE_SOURCES_FLAGS) -unsafe $(RESOURCE_FILES:%=-resource:%) -nowarn:436
|
||||
|
||||
ifndef NO_MONO_SECURITY
|
||||
|
@@ -226,45 +226,79 @@ namespace Mono.Net.Security
|
||||
providerRegistration = new Dictionary<string,Tuple<Guid,string>> ();
|
||||
providerCache = new Dictionary<Guid,MSI.MonoTlsProvider> ();
|
||||
|
||||
var appleTlsEntry = new Tuple<Guid,String> (AppleTlsId, "Mono.AppleTls.AppleTlsProvider");
|
||||
|
||||
#if ONLY_APPLETLS || MONOTOUCH || XAMMAC
|
||||
providerRegistration.Add ("default", appleTlsEntry);
|
||||
providerRegistration.Add ("apple", appleTlsEntry);
|
||||
#else
|
||||
var legacyEntry = new Tuple<Guid,String> (LegacyId, "Mono.Net.Security.LegacyTlsProvider");
|
||||
providerRegistration.Add ("legacy", legacyEntry);
|
||||
|
||||
Tuple<Guid,String> btlsEntry = null;
|
||||
#if MONO_FEATURE_BTLS
|
||||
if (IsBtlsSupported ()) {
|
||||
btlsEntry = new Tuple<Guid,String> (BtlsId, "Mono.Btls.MonoBtlsProvider");
|
||||
providerRegistration.Add ("btls", btlsEntry);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Platform.IsMacOS)
|
||||
providerRegistration.Add ("default", appleTlsEntry);
|
||||
else if (btlsEntry != null)
|
||||
providerRegistration.Add ("default", btlsEntry);
|
||||
else
|
||||
providerRegistration.Add ("default", legacyEntry);
|
||||
|
||||
providerRegistration.Add ("apple", appleTlsEntry);
|
||||
#endif
|
||||
PopulateProviders ();
|
||||
}
|
||||
}
|
||||
|
||||
#region Platform-Specific code
|
||||
#if ONLY_APPLETLS || MONOTOUCH || XAMMAC
|
||||
// TODO: Should be redundant
|
||||
static void PopulateProviders ()
|
||||
{
|
||||
var appleTlsEntry = new Tuple<Guid,String> (AppleTlsId, typeof (Mono.AppleTls.AppleTlsProvider).FullName);
|
||||
|
||||
providerRegistration.Add ("default", appleTlsEntry);
|
||||
providerRegistration.Add ("apple", appleTlsEntry);
|
||||
}
|
||||
#elif MONODROID
|
||||
// TODO: Should be redundant
|
||||
static void PopulateProviders ()
|
||||
{
|
||||
var legacyEntry = new Tuple<Guid,String> (LegacyId, typeof (Mono.Net.Security.LegacyTlsProvider).FullName);
|
||||
|
||||
providerRegistration.Add ("legacy", legacyEntry);
|
||||
|
||||
#if MONO_FEATURE_BTLS
|
||||
var btlsEntry = new Tuple<Guid,String> (BtlsId, typeof (Mono.Btls.MonoBtlsProvider).FullName);
|
||||
if (btlsEntry != null)
|
||||
providerRegistration.Add ("default", btlsEntry);
|
||||
else
|
||||
#endif
|
||||
providerRegistration.Add ("default", legacyEntry);
|
||||
}
|
||||
#else
|
||||
static void PopulateProviders ()
|
||||
{
|
||||
#if MONO_FEATURE_APPLETLS
|
||||
var appleTlsEntry = new Tuple<Guid,String> (AppleTlsId, typeof (Mono.AppleTls.AppleTlsProvider).FullName);
|
||||
#endif
|
||||
var legacyEntry = new Tuple<Guid,String> (LegacyId, typeof (Mono.Net.Security.LegacyTlsProvider).FullName);
|
||||
providerRegistration.Add ("legacy", legacyEntry);
|
||||
|
||||
Tuple<Guid,String> btlsEntry = null;
|
||||
#if MONO_FEATURE_BTLS
|
||||
if (IsBtlsSupported ()) {
|
||||
btlsEntry = new Tuple<Guid,String> (BtlsId, typeof (Mono.Btls.MonoBtlsProvider).FullName);
|
||||
providerRegistration.Add ("btls", btlsEntry);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MONO_FEATURE_APPLETLS
|
||||
if (Platform.IsMacOS)
|
||||
providerRegistration.Add ("default", appleTlsEntry);
|
||||
else
|
||||
#endif
|
||||
#if MONO_FEATURE_BTLS
|
||||
if (btlsEntry != null)
|
||||
providerRegistration.Add ("default", btlsEntry);
|
||||
else
|
||||
#endif
|
||||
providerRegistration.Add ("default", legacyEntry);
|
||||
|
||||
#if MONO_FEATURE_APPLETLS
|
||||
providerRegistration.Add ("apple", appleTlsEntry);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if MONO_FEATURE_BTLS
|
||||
[MethodImpl (MethodImplOptions.InternalCall)]
|
||||
internal extern static bool IsBtlsSupported ();
|
||||
#endif
|
||||
|
||||
#if MONODROID
|
||||
static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
|
||||
{
|
||||
#if MONODROID
|
||||
MSI.MonoTlsProvider provider = null;
|
||||
var type = Environment.GetEnvironmentVariable ("XA_TLS_PROVIDER");
|
||||
switch (type) {
|
||||
@@ -281,24 +315,40 @@ namespace Mono.Net.Security
|
||||
default:
|
||||
throw new NotSupportedException (string.Format ("Invalid TLS Provider: `{0}'.", provider));
|
||||
}
|
||||
}
|
||||
|
||||
#elif ONLY_APPLETLS || MONOTOUCH || XAMMAC
|
||||
static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
|
||||
{
|
||||
return new AppleTlsProvider ();
|
||||
}
|
||||
#else
|
||||
static MSI.MonoTlsProvider CreateDefaultProviderImpl ()
|
||||
{
|
||||
var variable = Environment.GetEnvironmentVariable ("MONO_TLS_PROVIDER");
|
||||
if (string.IsNullOrEmpty (variable))
|
||||
variable = "default";
|
||||
var type = Environment.GetEnvironmentVariable ("MONO_TLS_PROVIDER");
|
||||
if (string.IsNullOrEmpty (type))
|
||||
type = "default";
|
||||
|
||||
return LookupProvider (variable, true);
|
||||
}
|
||||
switch (type) {
|
||||
case "default":
|
||||
#if MONO_FEATURE_APPLETLS
|
||||
if (Platform.IsMacOS)
|
||||
goto case "apple";
|
||||
#endif
|
||||
#if MONO_FEATURE_BTLS
|
||||
if (IsBtlsSupported ())
|
||||
goto case "btls";
|
||||
#endif
|
||||
goto case "legacy";
|
||||
#if MONO_FEATURE_APPLETLS
|
||||
case "apple":
|
||||
return new AppleTlsProvider ();
|
||||
#endif
|
||||
#if MONO_FEATURE_BTLS
|
||||
case "btls":
|
||||
return new MonoBtlsProvider ();
|
||||
#endif
|
||||
case "legacy":
|
||||
return new Mono.Net.Security.LegacyTlsProvider ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
return LookupProvider (type, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#region Mono.Security visible API
|
||||
|
||||
|
@@ -52,7 +52,7 @@ namespace Mono.Net.Security
|
||||
{
|
||||
class MonoTlsStream
|
||||
{
|
||||
#if SECURITY_DEP
|
||||
#if SECURITY_DEP
|
||||
readonly MonoTlsProvider provider;
|
||||
readonly NetworkStream networkStream;
|
||||
readonly HttpWebRequest request;
|
||||
@@ -99,9 +99,11 @@ namespace Mono.Net.Security
|
||||
#endif
|
||||
}
|
||||
|
||||
internal Stream CreateStream (byte[] buffer)
|
||||
internal async Task<Stream> CreateStream (WebConnectionTunnel tunnel, CancellationToken cancellationToken)
|
||||
{
|
||||
#if SECURITY_DEP
|
||||
var socket = networkStream.InternalSocket;
|
||||
WebConnection.Debug ($"MONO TLS STREAM CREATE STREAM: {socket.ID}");
|
||||
sslStream = provider.CreateSslStream (networkStream, false, settings);
|
||||
|
||||
try {
|
||||
@@ -112,16 +114,21 @@ namespace Mono.Net.Security
|
||||
host = host.Substring (0, pos);
|
||||
}
|
||||
|
||||
sslStream.AuthenticateAsClient (
|
||||
await sslStream.AuthenticateAsClientAsync (
|
||||
host, request.ClientCertificates,
|
||||
(SslProtocols)ServicePointManager.SecurityProtocol,
|
||||
ServicePointManager.CheckCertificateRevocationList);
|
||||
ServicePointManager.CheckCertificateRevocationList).ConfigureAwait (false);
|
||||
|
||||
status = WebExceptionStatus.Success;
|
||||
} catch {
|
||||
status = WebExceptionStatus.SecureChannelFailure;
|
||||
} catch (Exception ex) {
|
||||
WebConnection.Debug ($"MONO TLS STREAM ERROR: {socket.ID} {socket.CleanedUp} {ex.Message}");
|
||||
if (socket.CleanedUp)
|
||||
status = WebExceptionStatus.RequestCanceled;
|
||||
else
|
||||
status = WebExceptionStatus.SecureChannelFailure;
|
||||
throw;
|
||||
} finally {
|
||||
WebConnection.Debug ($"MONO TLS STREAM CREATE STREAM DONE: {socket.ID} {socket.CleanedUp}");
|
||||
if (CertificateValidationFailed)
|
||||
status = WebExceptionStatus.TrustFailure;
|
||||
|
||||
@@ -134,8 +141,8 @@ namespace Mono.Net.Security
|
||||
}
|
||||
|
||||
try {
|
||||
if (buffer != null)
|
||||
sslStream.Write (buffer, 0, buffer.Length);
|
||||
if (tunnel?.Data != null)
|
||||
await sslStream.WriteAsync (tunnel.Data, 0, tunnel.Data.Length, cancellationToken).ConfigureAwait (false);
|
||||
} catch {
|
||||
status = WebExceptionStatus.SendFailure;
|
||||
sslStream = null;
|
||||
|
@@ -1 +1 @@
|
||||
5f6a3e96a03fd839708cd965990030483ed1179d
|
||||
4c1d88b51c1ca6902aa3ee4c56a4bbf6c7ac20c6
|
@@ -14,7 +14,18 @@ namespace System.Net
|
||||
|
||||
if (secureString == null || secureString.Length == 0)
|
||||
return String.Empty;
|
||||
|
||||
#if MONO
|
||||
try
|
||||
{
|
||||
bstr = Marshal.SecureStringToGlobalAllocUnicode(secureString);
|
||||
plainString = Marshal.PtrToStringUni(bstr);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bstr != IntPtr.Zero)
|
||||
Marshal.ZeroFreeGlobalAllocUnicode(bstr);
|
||||
}
|
||||
#else
|
||||
try
|
||||
{
|
||||
bstr = Marshal.SecureStringToBSTR(secureString);
|
||||
@@ -25,6 +36,7 @@ namespace System.Net
|
||||
if (bstr != IntPtr.Zero)
|
||||
Marshal.ZeroFreeBSTR(bstr);
|
||||
}
|
||||
#endif
|
||||
return plainString;
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ namespace System.CodeDom.Compiler
|
||||
[ConfigurationCollection (typeof (Compiler), AddItemName = "compiler", CollectionType = ConfigurationElementCollectionType.BasicMap)]
|
||||
internal sealed class CompilerCollection : ConfigurationElementCollection
|
||||
{
|
||||
static readonly string defaultCompilerVersion = "3.5";
|
||||
static readonly string defaultCompilerVersion = "4.0";
|
||||
static ConfigurationPropertyCollection properties;
|
||||
static List <CompilerInfo> compiler_infos;
|
||||
static Dictionary <string, CompilerInfo> compiler_languages;
|
||||
@@ -50,30 +50,15 @@ namespace System.CodeDom.Compiler
|
||||
properties = new ConfigurationPropertyCollection ();
|
||||
compiler_infos = new List <CompilerInfo> ();
|
||||
compiler_languages = new Dictionary <string, CompilerInfo> (16, StringComparer.OrdinalIgnoreCase);
|
||||
compiler_extensions = new Dictionary <string, CompilerInfo> (6, StringComparer.OrdinalIgnoreCase);
|
||||
compiler_extensions = new Dictionary <string, CompilerInfo> (4, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
CompilerInfo compiler = new CompilerInfo (null, "Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
new [] { ".cs" }, new [] { "c#", "cs", "csharp" });
|
||||
CompilerInfo compiler = new CompilerInfo (null, "Microsoft.CSharp.CSharpCodeProvider, " + Consts.AssemblySystem,
|
||||
new [] { "c#", "cs", "csharp" }, new [] { ".cs" });
|
||||
compiler.ProviderOptions ["CompilerVersion"] = defaultCompilerVersion;
|
||||
AddCompilerInfo (compiler);
|
||||
|
||||
compiler = new CompilerInfo (null, "Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
new [] { ".vb" }, new [] { "vb", "vbs", "visualbasic", "vbscript" });
|
||||
compiler.ProviderOptions ["CompilerVersion"] = defaultCompilerVersion;
|
||||
AddCompilerInfo (compiler);
|
||||
|
||||
compiler = new CompilerInfo (null, "Microsoft.JScript.JScriptCodeProvider, Microsoft.JScript, Version=8.0.1100.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
|
||||
new [] { ".js" }, new [] { "js", "jscript", "javascript" });
|
||||
compiler.ProviderOptions ["CompilerVersion"] = defaultCompilerVersion;
|
||||
AddCompilerInfo (compiler);
|
||||
|
||||
compiler = new CompilerInfo (null, "Microsoft.VJSharp.VJSharpCodeProvider, VJSharpCodeProvider, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
|
||||
new [] { ".jsl", ".java" }, new [] { "vj#", "vjs", "vjsharp" });
|
||||
compiler.ProviderOptions ["CompilerVersion"] = defaultCompilerVersion;
|
||||
AddCompilerInfo (compiler);
|
||||
|
||||
compiler = new CompilerInfo (null, "Microsoft.VisualC.CppCodeProvider, CppCodeProvider, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
|
||||
new [] { ".h" }, new [] { "c++", "mc", "cpp" });
|
||||
compiler = new CompilerInfo (null, "Microsoft.VisualBasic.VBCodeProvider, " + Consts.AssemblySystem,
|
||||
new [] { "vb", "vbs", "visualbasic", "vbscript" }, new [] { ".vb" });
|
||||
compiler.ProviderOptions ["CompilerVersion"] = defaultCompilerVersion;
|
||||
AddCompilerInfo (compiler);
|
||||
}
|
||||
|
@@ -78,9 +78,13 @@ namespace System.Configuration {
|
||||
public void Reload ()
|
||||
{
|
||||
#if (CONFIGURATION_DEP)
|
||||
foreach (SettingsProvider provider in Providers) {
|
||||
// IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
|
||||
CacheValuesByProvider(provider);
|
||||
/* Clear out the old property values so they will be reloaded on request */
|
||||
if (PropertyValues != null) {
|
||||
PropertyValues.Clear();
|
||||
}
|
||||
foreach(SettingsProperty prop in Properties) {
|
||||
/* emit PropertyChanged for every property */
|
||||
OnPropertyChanged(this, new PropertyChangedEventArgs(prop.Name));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -88,13 +92,31 @@ namespace System.Configuration {
|
||||
public void Reset()
|
||||
{
|
||||
#if (CONFIGURATION_DEP)
|
||||
if (Properties != null) {
|
||||
foreach (SettingsProvider provider in Providers) {
|
||||
IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider;
|
||||
if (iasp != null)
|
||||
iasp.Reset (Context);
|
||||
}
|
||||
InternalSave ();
|
||||
}
|
||||
|
||||
Reload ();
|
||||
foreach (SettingsPropertyValue pv in PropertyValues)
|
||||
pv.PropertyValue = pv.Reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
public override void Save ()
|
||||
{
|
||||
var e = new CancelEventArgs ();
|
||||
|
||||
OnSettingsSaving (this, e);
|
||||
if (e.Cancel)
|
||||
return;
|
||||
|
||||
InternalSave ();
|
||||
}
|
||||
|
||||
void InternalSave ()
|
||||
{
|
||||
#if (CONFIGURATION_DEP)
|
||||
Context.CurrentSettings = this;
|
||||
@@ -111,13 +133,42 @@ namespace System.Configuration {
|
||||
provider.SetPropertyValues (Context, cache);
|
||||
}
|
||||
Context.CurrentSettings = null;
|
||||
#else
|
||||
throw new NotImplementedException("No useful Save implemented.");
|
||||
#endif
|
||||
}
|
||||
|
||||
public virtual void Upgrade()
|
||||
public virtual void Upgrade ()
|
||||
{
|
||||
#if (CONFIGURATION_DEP)
|
||||
// if there is a current property, then for each settings
|
||||
// provider in the providers collection, upgrade(ssp)
|
||||
if (Properties != null) {
|
||||
foreach (SettingsProvider provider in Providers) {
|
||||
var appSettingsProvider = provider as IApplicationSettingsProvider;
|
||||
if(appSettingsProvider != null) {
|
||||
appSettingsProvider.Upgrade (Context, GetPropertiesForProvider (provider));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reload ();
|
||||
#else
|
||||
throw new NotImplementedException ("No useful Upgrade implemented");
|
||||
#endif
|
||||
}
|
||||
|
||||
private SettingsPropertyCollection GetPropertiesForProvider (SettingsProvider provider)
|
||||
{
|
||||
SettingsPropertyCollection properties = new SettingsPropertyCollection ();
|
||||
foreach (SettingsProperty sp in Properties) {
|
||||
if (sp.Provider == provider) {
|
||||
properties.Add(sp);
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
protected virtual void OnPropertyChanged (object sender,
|
||||
PropertyChangedEventArgs e)
|
||||
{
|
||||
@@ -310,7 +361,17 @@ namespace System.Configuration {
|
||||
foreach (Attribute a in prop.GetCustomAttributes (false)) {
|
||||
/* the attributes we handle natively here */
|
||||
if (a is SettingsProviderAttribute) {
|
||||
Type provider_type = Type.GetType (((SettingsProviderAttribute)a).ProviderTypeName);
|
||||
var providerTypeName = ((SettingsProviderAttribute)a).ProviderTypeName;
|
||||
Type provider_type = Type.GetType (providerTypeName);
|
||||
if(provider_type == null) { // Type failed to find the type by name
|
||||
var typeNameParts = providerTypeName.Split('.');
|
||||
if(typeNameParts.Length > 1) { //Load the assembly that providerTypeName claims
|
||||
var assy = Assembly.Load(typeNameParts[0]);
|
||||
if(assy != null) {
|
||||
provider_type = assy.GetType(providerTypeName); //try to get the type from that Assembly
|
||||
}
|
||||
}
|
||||
}
|
||||
provider = (SettingsProvider) Activator.CreateInstance (provider_type);
|
||||
provider.Initialize (null, null);
|
||||
}
|
||||
|
@@ -819,6 +819,11 @@ namespace System.Configuration
|
||||
|
||||
public void Reset (SettingsContext context)
|
||||
{
|
||||
if (values == null) {
|
||||
SettingsPropertyCollection coll = new SettingsPropertyCollection ();
|
||||
GetPropertyValues (context, coll);
|
||||
}
|
||||
|
||||
if (values != null) {
|
||||
foreach (SettingsPropertyValue propertyValue in values) {
|
||||
// Can't use propertyValue.Property.DefaultValue
|
||||
|
@@ -45,6 +45,7 @@ namespace System.Configuration
|
||||
{
|
||||
this.property = property;
|
||||
needPropertyValue = true;
|
||||
needSerializedValue = true;
|
||||
}
|
||||
|
||||
public bool Deserialized {
|
||||
@@ -83,6 +84,8 @@ namespace System.Configuration
|
||||
propertyValue = GetDeserializedValue (serializedValue);
|
||||
if (propertyValue == null) {
|
||||
propertyValue = GetDeserializedDefaultValue ();
|
||||
serializedValue = null;
|
||||
needSerializedValue = true;
|
||||
defaulted = true;
|
||||
}
|
||||
needPropertyValue = false;
|
||||
@@ -107,9 +110,7 @@ namespace System.Configuration
|
||||
|
||||
public object SerializedValue {
|
||||
get {
|
||||
if (needSerializedValue) {
|
||||
needSerializedValue = false;
|
||||
|
||||
if ((needSerializedValue || IsDirty) && !UsingDefaultValue) {
|
||||
switch (property.SerializeAs)
|
||||
{
|
||||
case SettingsSerializeAs.String:
|
||||
@@ -143,6 +144,8 @@ namespace System.Configuration
|
||||
break;
|
||||
}
|
||||
|
||||
needSerializedValue = false;
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
return serializedValue;
|
||||
@@ -150,6 +153,7 @@ namespace System.Configuration
|
||||
set {
|
||||
serializedValue = value;
|
||||
needPropertyValue = true;
|
||||
needSerializedValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +169,7 @@ namespace System.Configuration
|
||||
dirty = true;
|
||||
defaulted = true;
|
||||
needPropertyValue = true;
|
||||
needSerializedValue = true;
|
||||
return propertyValue;
|
||||
}
|
||||
|
||||
|
@@ -127,7 +127,7 @@ namespace System.Diagnostics {
|
||||
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern IntPtr GetImpl (string category, string counter,
|
||||
string instance, string machine, out PerformanceCounterType ctype, out bool custom);
|
||||
string instance, out PerformanceCounterType ctype, out bool custom);
|
||||
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern bool GetSample (IntPtr impl, bool only_value, out CounterSample sample);
|
||||
@@ -138,6 +138,11 @@ namespace System.Diagnostics {
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern void FreeData (IntPtr impl);
|
||||
|
||||
static bool IsValidMachine (string machine)
|
||||
{ // no support for counters on other machines
|
||||
return machine == ".";
|
||||
}
|
||||
|
||||
/* the perf counter has changed, ensure it's valid and setup it to
|
||||
* be able to collect/update data
|
||||
*/
|
||||
@@ -146,7 +151,9 @@ namespace System.Diagnostics {
|
||||
// need to free the previous info
|
||||
if (impl != IntPtr.Zero)
|
||||
Close ();
|
||||
impl = GetImpl (categoryName, counterName, instanceName, machineName, out type, out is_custom);
|
||||
|
||||
if (IsValidMachine (machineName))
|
||||
impl = GetImpl (categoryName, counterName, instanceName, out type, out is_custom);
|
||||
// system counters are always readonly
|
||||
if (!is_custom)
|
||||
readOnly = true;
|
||||
|
@@ -44,27 +44,27 @@ namespace System.Diagnostics
|
||||
static extern bool CategoryDelete (string name);
|
||||
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern string CategoryHelpInternal (string category, string machine);
|
||||
static extern string CategoryHelpInternal (string category);
|
||||
|
||||
/* this icall allows a null counter and it will just search for the category */
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern bool CounterCategoryExists (string counter, string category, string machine);
|
||||
static extern bool CounterCategoryExists (string counter, string category);
|
||||
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern bool Create (string categoryName, string categoryHelp,
|
||||
PerformanceCounterCategoryType categoryType, CounterCreationData[] items);
|
||||
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern int InstanceExistsInternal (string instance, string category, string machine);
|
||||
static extern bool InstanceExistsInternal (string instance, string category);
|
||||
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern string[] GetCategoryNames (string machine);
|
||||
static extern string[] GetCategoryNames ();
|
||||
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern string[] GetCounterNames (string category, string machine);
|
||||
static extern string[] GetCounterNames (string category);
|
||||
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern string[] GetInstanceNames (string category, string machine);
|
||||
static extern string[] GetInstanceNames (string category);
|
||||
|
||||
static void CheckCategory (string categoryName) {
|
||||
if (categoryName == null)
|
||||
@@ -95,10 +95,17 @@ namespace System.Diagnostics
|
||||
this.machineName = machineName;
|
||||
}
|
||||
|
||||
static bool IsValidMachine (string machine)
|
||||
{ // no support for counters on other machines
|
||||
return machine == ".";
|
||||
}
|
||||
|
||||
// may throw InvalidOperationException, Win32Exception
|
||||
public string CategoryHelp {
|
||||
get {
|
||||
string res = CategoryHelpInternal (categoryName, machineName);
|
||||
string res = null;
|
||||
if (IsValidMachine (machineName))
|
||||
res = CategoryHelpInternal (categoryName);
|
||||
if (res != null)
|
||||
return res;
|
||||
throw new InvalidOperationException ();
|
||||
@@ -154,7 +161,8 @@ namespace System.Diagnostics
|
||||
CheckCategory (categoryName);
|
||||
if (machineName == null)
|
||||
throw new ArgumentNullException ("machineName");
|
||||
return CounterCategoryExists (counterName, categoryName, machineName);
|
||||
return IsValidMachine (machineName)
|
||||
&& CounterCategoryExists (counterName, categoryName);
|
||||
}
|
||||
|
||||
[Obsolete ("Use another overload that uses PerformanceCounterCategoryType instead")]
|
||||
@@ -227,7 +235,8 @@ namespace System.Diagnostics
|
||||
public static bool Exists (string categoryName, string machineName)
|
||||
{
|
||||
CheckCategory (categoryName);
|
||||
return CounterCategoryExists (null, categoryName, machineName);
|
||||
return IsValidMachine (machineName) &&
|
||||
CounterCategoryExists (null, categoryName);
|
||||
}
|
||||
|
||||
public static PerformanceCounterCategory[] GetCategories ()
|
||||
@@ -239,7 +248,11 @@ namespace System.Diagnostics
|
||||
{
|
||||
if (machineName == null)
|
||||
throw new ArgumentNullException ("machineName");
|
||||
string[] catnames = GetCategoryNames (machineName);
|
||||
|
||||
if (!IsValidMachine (machineName))
|
||||
return Array.Empty<PerformanceCounterCategory>();
|
||||
|
||||
string[] catnames = GetCategoryNames ();
|
||||
PerformanceCounterCategory[] cats = new PerformanceCounterCategory [catnames.Length];
|
||||
for (int i = 0; i < catnames.Length; ++i)
|
||||
cats [i] = new PerformanceCounterCategory (catnames [i], machineName);
|
||||
@@ -253,7 +266,9 @@ namespace System.Diagnostics
|
||||
|
||||
public PerformanceCounter[] GetCounters (string instanceName)
|
||||
{
|
||||
string[] countnames = GetCounterNames (categoryName, machineName);
|
||||
if (!IsValidMachine (machineName))
|
||||
return Array.Empty<PerformanceCounter>();
|
||||
string[] countnames = GetCounterNames (categoryName);
|
||||
PerformanceCounter[] counters = new PerformanceCounter [countnames.Length];
|
||||
for (int i = 0; i < countnames.Length; ++i) {
|
||||
counters [i] = new PerformanceCounter (categoryName, countnames [i], instanceName, machineName);
|
||||
@@ -263,7 +278,9 @@ namespace System.Diagnostics
|
||||
|
||||
public string[] GetInstanceNames ()
|
||||
{
|
||||
return GetInstanceNames (categoryName, machineName);
|
||||
if (!IsValidMachine (machineName))
|
||||
return Array.Empty<string>();
|
||||
return GetInstanceNames (categoryName);
|
||||
}
|
||||
|
||||
public bool InstanceExists (string instanceName)
|
||||
@@ -283,12 +300,12 @@ namespace System.Diagnostics
|
||||
CheckCategory (categoryName);
|
||||
if (machineName == null)
|
||||
throw new ArgumentNullException ("machineName");
|
||||
int val = InstanceExistsInternal (instanceName, categoryName, machineName);
|
||||
if (val == 0)
|
||||
return false;
|
||||
if (val == 1)
|
||||
return true;
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
//?FIXME: machine appears to be wrong
|
||||
//if (!IsValidMachine (machineName))
|
||||
//return false;
|
||||
|
||||
return InstanceExistsInternal (instanceName, categoryName);
|
||||
}
|
||||
|
||||
[MonoTODO]
|
||||
|
@@ -47,7 +47,7 @@ using System.Text;
|
||||
using System.Timers;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace System.Net.Sockets
|
||||
namespace System.Net.Sockets
|
||||
{
|
||||
public partial class Socket : IDisposable
|
||||
{
|
||||
@@ -91,7 +91,14 @@ namespace System.Net.Sockets
|
||||
int m_IntCleanedUp;
|
||||
internal bool connect_in_progress;
|
||||
|
||||
#region Constructors
|
||||
#if MONO_WEB_DEBUG
|
||||
static int nextId;
|
||||
internal readonly int ID = ++nextId;
|
||||
#else
|
||||
internal readonly int ID;
|
||||
#endif
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
||||
public Socket (SocketInformation socketInformation)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,8 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Net
|
||||
@@ -60,16 +62,28 @@ namespace System.Net
|
||||
Stream stream;
|
||||
|
||||
// Constructors
|
||||
|
||||
internal HttpWebResponse (Uri uri, string method, WebConnectionData data, CookieContainer container)
|
||||
|
||||
internal HttpWebResponse (Uri uri, string method, HttpStatusCode status, WebHeaderCollection headers)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.method = method;
|
||||
webHeaders = data.Headers;
|
||||
version = data.Version;
|
||||
statusCode = (HttpStatusCode) data.StatusCode;
|
||||
statusDescription = data.StatusDescription;
|
||||
stream = data.stream;
|
||||
this.statusCode = status;
|
||||
this.statusDescription = HttpStatusDescription.Get (status);
|
||||
this.webHeaders = headers;
|
||||
version = HttpVersion.Version10;
|
||||
contentLength = -1;
|
||||
}
|
||||
|
||||
internal HttpWebResponse (Uri uri, string method, WebResponseStream stream, CookieContainer container)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.method = method;
|
||||
this.stream = stream;
|
||||
|
||||
webHeaders = stream.Headers ?? new WebHeaderCollection ();
|
||||
version = stream.Version;
|
||||
statusCode = stream.StatusCode;
|
||||
statusDescription = stream.StatusDescription ?? HttpStatusDescription.Get (statusCode);
|
||||
contentLength = -1;
|
||||
|
||||
try {
|
||||
@@ -86,12 +100,12 @@ namespace System.Net
|
||||
}
|
||||
|
||||
string content_encoding = webHeaders ["Content-Encoding"];
|
||||
if (content_encoding == "gzip" && (data.request.AutomaticDecompression & DecompressionMethods.GZip) != 0) {
|
||||
stream = new GZipStream (stream, CompressionMode.Decompress);
|
||||
if (content_encoding == "gzip" && (stream.Request.AutomaticDecompression & DecompressionMethods.GZip) != 0) {
|
||||
this.stream = new GZipStream (stream, CompressionMode.Decompress);
|
||||
webHeaders.Remove (HttpRequestHeader.ContentEncoding);
|
||||
}
|
||||
else if (content_encoding == "deflate" && (data.request.AutomaticDecompression & DecompressionMethods.Deflate) != 0) {
|
||||
stream = new DeflateStream (stream, CompressionMode.Decompress);
|
||||
else if (content_encoding == "deflate" && (stream.Request.AutomaticDecompression & DecompressionMethods.Deflate) != 0) {
|
||||
this.stream = new DeflateStream (stream, CompressionMode.Decompress);
|
||||
webHeaders.Remove (HttpRequestHeader.ContentEncoding);
|
||||
}
|
||||
}
|
||||
@@ -154,6 +168,8 @@ namespace System.Net
|
||||
|
||||
if (contentType == null)
|
||||
contentType = webHeaders ["Content-Type"];
|
||||
if (contentType == null)
|
||||
contentType = string.Empty;
|
||||
|
||||
return contentType;
|
||||
}
|
||||
@@ -263,17 +279,6 @@ namespace System.Net
|
||||
return (value != null) ? value : "";
|
||||
}
|
||||
|
||||
internal void ReadAll ()
|
||||
{
|
||||
WebConnectionStream wce = stream as WebConnectionStream;
|
||||
if (wce == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
wce.ReadAll ();
|
||||
} catch {}
|
||||
}
|
||||
|
||||
public override Stream GetResponseStream ()
|
||||
{
|
||||
CheckDisposed ();
|
||||
@@ -310,12 +315,9 @@ namespace System.Net
|
||||
|
||||
public override void Close ()
|
||||
{
|
||||
if (stream != null) {
|
||||
Stream st = stream;
|
||||
stream = null;
|
||||
if (st != null)
|
||||
st.Close ();
|
||||
}
|
||||
var st = Interlocked.Exchange (ref stream, null);
|
||||
if (st != null)
|
||||
st.Close ();
|
||||
}
|
||||
|
||||
void IDisposable.Dispose ()
|
||||
|
@@ -1,52 +0,0 @@
|
||||
//
|
||||
// IWebConnectionState.cs
|
||||
//
|
||||
// Author:
|
||||
// Martin Baulig <martin.baulig@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2014 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;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
interface IWebConnectionState {
|
||||
WebConnectionGroup Group {
|
||||
get;
|
||||
}
|
||||
|
||||
ServicePoint ServicePoint {
|
||||
get;
|
||||
}
|
||||
|
||||
bool Busy {
|
||||
get;
|
||||
}
|
||||
|
||||
DateTime IdleSince {
|
||||
get;
|
||||
}
|
||||
|
||||
bool TrySetBusy ();
|
||||
|
||||
void SetIdle ();
|
||||
}
|
||||
}
|
@@ -38,20 +38,15 @@ using System.Net.Sockets;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Net
|
||||
namespace System.Net
|
||||
{
|
||||
public class ServicePoint
|
||||
{
|
||||
readonly Uri uri;
|
||||
int connectionLimit;
|
||||
int maxIdleTime;
|
||||
int currentConnections;
|
||||
DateTime idleSince;
|
||||
DateTime lastDnsResolve;
|
||||
Version protocolVersion;
|
||||
IPHostEntry host;
|
||||
bool usesProxy;
|
||||
Dictionary<string,WebConnectionGroup> groups;
|
||||
bool sendContinue = true;
|
||||
bool useConnect;
|
||||
object hostE = new object ();
|
||||
@@ -60,21 +55,22 @@ namespace System.Net
|
||||
bool tcp_keepalive;
|
||||
int tcp_keepalive_time;
|
||||
int tcp_keepalive_interval;
|
||||
Timer idleTimer;
|
||||
|
||||
// Constructors
|
||||
|
||||
internal ServicePoint (Uri uri, int connectionLimit, int maxIdleTime)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.connectionLimit = connectionLimit;
|
||||
this.maxIdleTime = maxIdleTime;
|
||||
this.currentConnections = 0;
|
||||
this.idleSince = DateTime.UtcNow;
|
||||
this.uri = uri;
|
||||
|
||||
Scheduler = new ServicePointScheduler (this, connectionLimit, maxIdleTime);
|
||||
}
|
||||
|
||||
|
||||
internal ServicePointScheduler Scheduler {
|
||||
get;
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
|
||||
public Uri Address {
|
||||
get { return uri; }
|
||||
}
|
||||
@@ -84,15 +80,13 @@ namespace System.Net
|
||||
return new NotImplementedException ();
|
||||
}
|
||||
|
||||
public BindIPEndPoint BindIPEndPointDelegate
|
||||
{
|
||||
public BindIPEndPoint BindIPEndPointDelegate {
|
||||
get { return endPointCallback; }
|
||||
set { endPointCallback = value; }
|
||||
}
|
||||
|
||||
|
||||
[MonoTODO]
|
||||
public int ConnectionLeaseTimeout
|
||||
{
|
||||
public int ConnectionLeaseTimeout {
|
||||
get {
|
||||
throw GetMustImplement ();
|
||||
}
|
||||
@@ -100,54 +94,39 @@ namespace System.Net
|
||||
throw GetMustImplement ();
|
||||
}
|
||||
}
|
||||
|
||||
public int ConnectionLimit {
|
||||
get { return connectionLimit; }
|
||||
set {
|
||||
if (value <= 0)
|
||||
throw new ArgumentOutOfRangeException ();
|
||||
|
||||
connectionLimit = value;
|
||||
}
|
||||
public int ConnectionLimit {
|
||||
get { return Scheduler.ConnectionLimit; }
|
||||
set { Scheduler.ConnectionLimit = value; }
|
||||
}
|
||||
|
||||
|
||||
public string ConnectionName {
|
||||
get { return uri.Scheme; }
|
||||
}
|
||||
|
||||
public int CurrentConnections {
|
||||
get {
|
||||
return currentConnections;
|
||||
return Scheduler.CurrentConnections;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime IdleSince {
|
||||
get {
|
||||
return idleSince.ToLocalTime ();
|
||||
return Scheduler.IdleSince.ToLocalTime ();
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxIdleTime {
|
||||
get { return maxIdleTime; }
|
||||
set {
|
||||
if (value < Timeout.Infinite || value > Int32.MaxValue)
|
||||
throw new ArgumentOutOfRangeException ();
|
||||
|
||||
lock (this) {
|
||||
maxIdleTime = value;
|
||||
if (idleTimer != null)
|
||||
idleTimer.Change (maxIdleTime, maxIdleTime);
|
||||
}
|
||||
}
|
||||
get { return Scheduler.MaxIdleTime; }
|
||||
set { Scheduler.MaxIdleTime = value; }
|
||||
}
|
||||
|
||||
|
||||
public virtual Version ProtocolVersion {
|
||||
get { return protocolVersion; }
|
||||
}
|
||||
|
||||
[MonoTODO]
|
||||
public int ReceiveBufferSize
|
||||
{
|
||||
public int ReceiveBufferSize {
|
||||
get {
|
||||
throw GetMustImplement ();
|
||||
}
|
||||
@@ -155,7 +134,7 @@ namespace System.Net
|
||||
throw GetMustImplement ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool SupportsPipelining {
|
||||
get { return HttpVersion.Version11.Equals (protocolVersion); }
|
||||
}
|
||||
@@ -172,8 +151,10 @@ namespace System.Net
|
||||
}
|
||||
|
||||
internal bool SendContinue {
|
||||
get { return sendContinue &&
|
||||
(protocolVersion == null || protocolVersion == HttpVersion.Version11); }
|
||||
get {
|
||||
return sendContinue &&
|
||||
(protocolVersion == null || protocolVersion == HttpVersion.Version11);
|
||||
}
|
||||
set { sendContinue = value; }
|
||||
}
|
||||
// Methods
|
||||
@@ -197,25 +178,25 @@ namespace System.Net
|
||||
if (!tcp_keepalive)
|
||||
return;
|
||||
|
||||
byte [] bytes = new byte [12];
|
||||
PutBytes (bytes, (uint) (tcp_keepalive ? 1 : 0), 0);
|
||||
PutBytes (bytes, (uint) tcp_keepalive_time, 4);
|
||||
PutBytes (bytes, (uint) tcp_keepalive_interval, 8);
|
||||
byte[] bytes = new byte[12];
|
||||
PutBytes (bytes, (uint)(tcp_keepalive ? 1 : 0), 0);
|
||||
PutBytes (bytes, (uint)tcp_keepalive_time, 4);
|
||||
PutBytes (bytes, (uint)tcp_keepalive_interval, 8);
|
||||
socket.IOControl (IOControlCode.KeepAliveValues, bytes, null);
|
||||
}
|
||||
|
||||
static void PutBytes (byte [] bytes, uint v, int offset)
|
||||
static void PutBytes (byte[] bytes, uint v, int offset)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
bytes [offset] = (byte) (v & 0x000000ff);
|
||||
bytes [offset + 1] = (byte) ((v & 0x0000ff00) >> 8);
|
||||
bytes [offset + 2] = (byte) ((v & 0x00ff0000) >> 16);
|
||||
bytes [offset + 3] = (byte) ((v & 0xff000000) >> 24);
|
||||
bytes[offset] = (byte)(v & 0x000000ff);
|
||||
bytes[offset + 1] = (byte)((v & 0x0000ff00) >> 8);
|
||||
bytes[offset + 2] = (byte)((v & 0x00ff0000) >> 16);
|
||||
bytes[offset + 3] = (byte)((v & 0xff000000) >> 24);
|
||||
} else {
|
||||
bytes [offset + 3] = (byte) (v & 0x000000ff);
|
||||
bytes [offset + 2] = (byte) ((v & 0x0000ff00) >> 8);
|
||||
bytes [offset + 1] = (byte) ((v & 0x00ff0000) >> 16);
|
||||
bytes [offset] = (byte) ((v & 0xff000000) >> 24);
|
||||
bytes[offset + 3] = (byte)(v & 0x000000ff);
|
||||
bytes[offset + 2] = (byte)((v & 0x0000ff00) >> 8);
|
||||
bytes[offset + 1] = (byte)((v & 0x00ff0000) >> 16);
|
||||
bytes[offset] = (byte)((v & 0xff000000) >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,107 +212,7 @@ namespace System.Net
|
||||
set { useConnect = value; }
|
||||
}
|
||||
|
||||
WebConnectionGroup GetConnectionGroup (string name)
|
||||
{
|
||||
if (name == null)
|
||||
name = "";
|
||||
|
||||
/*
|
||||
* Optimization:
|
||||
*
|
||||
* In the vast majority of cases, we only have one single WebConnectionGroup per ServicePoint, so we
|
||||
* don't need to allocate a dictionary.
|
||||
*
|
||||
*/
|
||||
|
||||
WebConnectionGroup group;
|
||||
if (groups != null && groups.TryGetValue (name, out group))
|
||||
return group;
|
||||
|
||||
group = new WebConnectionGroup (this, name);
|
||||
group.ConnectionClosed += (s, e) => currentConnections--;
|
||||
|
||||
if (groups == null)
|
||||
groups = new Dictionary<string, WebConnectionGroup> ();
|
||||
groups.Add (name, group);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
void RemoveConnectionGroup (WebConnectionGroup group)
|
||||
{
|
||||
if (groups == null || groups.Count == 0)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
groups.Remove (group.Name);
|
||||
}
|
||||
|
||||
bool CheckAvailableForRecycling (out DateTime outIdleSince)
|
||||
{
|
||||
outIdleSince = DateTime.MinValue;
|
||||
|
||||
TimeSpan idleTimeSpan;
|
||||
List<WebConnectionGroup> groupList = null, removeList = null;
|
||||
lock (this) {
|
||||
if (groups == null || groups.Count == 0) {
|
||||
idleSince = DateTime.MinValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
idleTimeSpan = TimeSpan.FromMilliseconds (maxIdleTime);
|
||||
|
||||
/*
|
||||
* WebConnectionGroup.TryRecycle() must run outside the lock, so we need to
|
||||
* copy the group dictionary if it exists.
|
||||
*
|
||||
* In most cases, we only have a single connection group, so we can simply store
|
||||
* that in a local variable instead of copying a collection.
|
||||
*
|
||||
*/
|
||||
|
||||
groupList = new List<WebConnectionGroup> (groups.Values);
|
||||
}
|
||||
|
||||
foreach (var group in groupList) {
|
||||
if (!group.TryRecycle (idleTimeSpan, ref outIdleSince))
|
||||
continue;
|
||||
if (removeList == null)
|
||||
removeList = new List<WebConnectionGroup> ();
|
||||
removeList.Add (group);
|
||||
}
|
||||
|
||||
lock (this) {
|
||||
idleSince = outIdleSince;
|
||||
|
||||
if (removeList != null && groups != null) {
|
||||
foreach (var group in removeList)
|
||||
if (groups.ContainsKey (group.Name))
|
||||
RemoveConnectionGroup (group);
|
||||
}
|
||||
|
||||
if (groups != null && groups.Count == 0)
|
||||
groups = null;
|
||||
|
||||
if (groups == null) {
|
||||
if (idleTimer != null) {
|
||||
idleTimer.Dispose ();
|
||||
idleTimer = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void IdleTimerCallback (object obj)
|
||||
{
|
||||
DateTime dummy;
|
||||
CheckAvailableForRecycling (out dummy);
|
||||
}
|
||||
|
||||
private bool HasTimedOut
|
||||
{
|
||||
private bool HasTimedOut {
|
||||
get {
|
||||
int timeout = ServicePointManager.DnsRefreshTimeout;
|
||||
return timeout != Timeout.Infinite &&
|
||||
@@ -339,8 +220,7 @@ namespace System.Net
|
||||
}
|
||||
}
|
||||
|
||||
internal IPHostEntry HostEntry
|
||||
{
|
||||
internal IPHostEntry HostEntry {
|
||||
get {
|
||||
lock (hostE) {
|
||||
string uriHost = uri.Host;
|
||||
@@ -356,7 +236,7 @@ namespace System.Net
|
||||
}
|
||||
|
||||
// Creates IPHostEntry
|
||||
host = new IPHostEntry();
|
||||
host = new IPHostEntry ();
|
||||
host.AddressList = new IPAddress[] { IPAddress.Parse (uriHost) };
|
||||
return host;
|
||||
}
|
||||
@@ -382,41 +262,18 @@ namespace System.Net
|
||||
protocolVersion = version;
|
||||
}
|
||||
|
||||
internal EventHandler SendRequest (HttpWebRequest request, string groupName)
|
||||
internal void SendRequest (WebOperation operation, string groupName)
|
||||
{
|
||||
WebConnection cnc;
|
||||
|
||||
lock (this) {
|
||||
bool created;
|
||||
WebConnectionGroup cncGroup = GetConnectionGroup (groupName);
|
||||
cnc = cncGroup.GetConnection (request, out created);
|
||||
if (created) {
|
||||
++currentConnections;
|
||||
if (idleTimer == null)
|
||||
idleTimer = new Timer (IdleTimerCallback, null, maxIdleTime, maxIdleTime);
|
||||
}
|
||||
Scheduler.SendRequest (operation, groupName);
|
||||
}
|
||||
|
||||
return cnc.SendRequest (request);
|
||||
}
|
||||
|
||||
public bool CloseConnectionGroup (string connectionGroupName)
|
||||
{
|
||||
WebConnectionGroup cncGroup = null;
|
||||
|
||||
lock (this) {
|
||||
cncGroup = GetConnectionGroup (connectionGroupName);
|
||||
if (cncGroup != null) {
|
||||
RemoveConnectionGroup (cncGroup);
|
||||
}
|
||||
return Scheduler.CloseConnectionGroup (connectionGroupName);
|
||||
}
|
||||
|
||||
// WebConnectionGroup.Close() must *not* be called inside the lock
|
||||
if (cncGroup != null) {
|
||||
cncGroup.Close ();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
|
646
mcs/class/System/System.Net/ServicePointScheduler.cs
Normal file
646
mcs/class/System/System.Net/ServicePointScheduler.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,232 +0,0 @@
|
||||
//
|
||||
// SimpleAsyncResult.cs
|
||||
//
|
||||
// Authors:
|
||||
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
|
||||
// Martin Baulig (martin.baulig@xamarin.com)
|
||||
//
|
||||
// (C) 2003 Ximian, Inc (http://www.ximian.com)
|
||||
// Copyright (c) 2014 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.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
delegate void SimpleAsyncCallback (SimpleAsyncResult result);
|
||||
|
||||
class SimpleAsyncResult : IAsyncResult
|
||||
{
|
||||
ManualResetEvent handle;
|
||||
bool synch;
|
||||
bool isCompleted;
|
||||
readonly SimpleAsyncCallback cb;
|
||||
object state;
|
||||
bool callbackDone;
|
||||
Exception exc;
|
||||
object locker = new object ();
|
||||
|
||||
SimpleAsyncResult (SimpleAsyncCallback cb)
|
||||
{
|
||||
this.cb = cb;
|
||||
}
|
||||
|
||||
protected SimpleAsyncResult (AsyncCallback cb, object state)
|
||||
{
|
||||
this.state = state;
|
||||
this.cb = result => {
|
||||
if (cb != null)
|
||||
cb (this);
|
||||
};
|
||||
}
|
||||
|
||||
public static void Run (Func<SimpleAsyncResult, bool> func, SimpleAsyncCallback callback)
|
||||
{
|
||||
var result = new SimpleAsyncResult (callback);
|
||||
try {
|
||||
if (!func (result))
|
||||
result.SetCompleted (true);
|
||||
} catch (Exception ex) {
|
||||
result.SetCompleted (true, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RunWithLock (object locker, Func<SimpleAsyncResult, bool> func, SimpleAsyncCallback callback)
|
||||
{
|
||||
Run (inner => {
|
||||
bool running = func (inner);
|
||||
if (running)
|
||||
Monitor.Exit (locker);
|
||||
return running;
|
||||
}, inner => {
|
||||
if (inner.GotException) {
|
||||
if (inner.synch)
|
||||
Monitor.Exit (locker);
|
||||
callback (inner);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!inner.synch)
|
||||
Monitor.Enter (locker);
|
||||
|
||||
callback (inner);
|
||||
} finally {
|
||||
Monitor.Exit (locker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void Reset_internal ()
|
||||
{
|
||||
callbackDone = false;
|
||||
exc = null;
|
||||
lock (locker) {
|
||||
isCompleted = false;
|
||||
if (handle != null)
|
||||
handle.Reset ();
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetCompleted (bool synch, Exception e)
|
||||
{
|
||||
SetCompleted_internal (synch, e);
|
||||
DoCallback_private ();
|
||||
}
|
||||
|
||||
internal void SetCompleted (bool synch)
|
||||
{
|
||||
SetCompleted_internal (synch);
|
||||
DoCallback_private ();
|
||||
}
|
||||
|
||||
void SetCompleted_internal (bool synch, Exception e)
|
||||
{
|
||||
this.synch = synch;
|
||||
exc = e;
|
||||
lock (locker) {
|
||||
isCompleted = true;
|
||||
if (handle != null)
|
||||
handle.Set ();
|
||||
}
|
||||
}
|
||||
|
||||
protected void SetCompleted_internal (bool synch)
|
||||
{
|
||||
SetCompleted_internal (synch, null);
|
||||
}
|
||||
|
||||
void DoCallback_private ()
|
||||
{
|
||||
if (callbackDone)
|
||||
return;
|
||||
callbackDone = true;
|
||||
if (cb == null)
|
||||
return;
|
||||
cb (this);
|
||||
}
|
||||
|
||||
protected void DoCallback_internal ()
|
||||
{
|
||||
if (!callbackDone && cb != null) {
|
||||
callbackDone = true;
|
||||
cb (this);
|
||||
}
|
||||
}
|
||||
|
||||
internal void WaitUntilComplete ()
|
||||
{
|
||||
if (IsCompleted)
|
||||
return;
|
||||
|
||||
AsyncWaitHandle.WaitOne ();
|
||||
}
|
||||
|
||||
internal bool WaitUntilComplete (int timeout, bool exitContext)
|
||||
{
|
||||
if (IsCompleted)
|
||||
return true;
|
||||
|
||||
return AsyncWaitHandle.WaitOne (timeout, exitContext);
|
||||
}
|
||||
|
||||
public object AsyncState {
|
||||
get { return state; }
|
||||
}
|
||||
|
||||
public WaitHandle AsyncWaitHandle {
|
||||
get {
|
||||
lock (locker) {
|
||||
if (handle == null)
|
||||
handle = new ManualResetEvent (isCompleted);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
bool? user_read_synch;
|
||||
|
||||
public bool CompletedSynchronously {
|
||||
get {
|
||||
//
|
||||
// CompletedSynchronously (for System.Net networking stack) means "was the operation completed before the first time
|
||||
// that somebody asked if it was completed synchronously"? They do this because some of their asynchronous operations
|
||||
// (particularly those in the Socket class) will avoid the cost of capturing and transferring the ExecutionContext
|
||||
// to the callback thread by checking CompletedSynchronously, and calling the callback from within BeginXxx instead of
|
||||
// on the completion port thread if the native winsock call completes quickly.
|
||||
//
|
||||
// TODO: racy
|
||||
if (user_read_synch != null)
|
||||
return user_read_synch.Value;
|
||||
|
||||
user_read_synch = synch;
|
||||
return user_read_synch.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool CompletedSynchronouslyPeek {
|
||||
get {
|
||||
return synch;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCompleted {
|
||||
get {
|
||||
lock (locker) {
|
||||
return isCompleted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal bool GotException {
|
||||
get { return (exc != null); }
|
||||
}
|
||||
|
||||
internal Exception Exception {
|
||||
get { return exc; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,132 +0,0 @@
|
||||
//
|
||||
// System.Net.WebAsyncResult
|
||||
//
|
||||
// Authors:
|
||||
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
|
||||
//
|
||||
// (C) 2003 Ximian, Inc (http://www.ximian.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.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
class WebAsyncResult : SimpleAsyncResult
|
||||
{
|
||||
int nbytes;
|
||||
IAsyncResult innerAsyncResult;
|
||||
HttpWebResponse response;
|
||||
Stream writeStream;
|
||||
byte [] buffer;
|
||||
int offset;
|
||||
int size;
|
||||
public bool EndCalled;
|
||||
public bool AsyncWriteAll;
|
||||
public HttpWebRequest AsyncObject;
|
||||
|
||||
public WebAsyncResult (AsyncCallback cb, object state)
|
||||
: base (cb, state)
|
||||
{
|
||||
}
|
||||
|
||||
public WebAsyncResult (HttpWebRequest request, AsyncCallback cb, object state)
|
||||
: base (cb, state)
|
||||
{
|
||||
this.AsyncObject = request;
|
||||
}
|
||||
|
||||
public WebAsyncResult (AsyncCallback cb, object state, byte [] buffer, int offset, int size)
|
||||
: base (cb, state)
|
||||
{
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
internal void Reset ()
|
||||
{
|
||||
this.nbytes = 0;
|
||||
this.response = null;
|
||||
this.buffer = null;
|
||||
this.offset = 0;
|
||||
this.size = 0;
|
||||
Reset_internal ();
|
||||
}
|
||||
|
||||
internal void SetCompleted (bool synch, int nbytes)
|
||||
{
|
||||
this.nbytes = nbytes;
|
||||
SetCompleted_internal (synch);
|
||||
}
|
||||
|
||||
internal void SetCompleted (bool synch, Stream writeStream)
|
||||
{
|
||||
this.writeStream = writeStream;
|
||||
SetCompleted_internal (synch);
|
||||
}
|
||||
|
||||
internal void SetCompleted (bool synch, HttpWebResponse response)
|
||||
{
|
||||
this.response = response;
|
||||
SetCompleted_internal (synch);
|
||||
}
|
||||
|
||||
internal void DoCallback ()
|
||||
{
|
||||
DoCallback_internal ();
|
||||
}
|
||||
|
||||
internal int NBytes {
|
||||
get { return nbytes; }
|
||||
set { nbytes = value; }
|
||||
}
|
||||
|
||||
internal IAsyncResult InnerAsyncResult {
|
||||
get { return innerAsyncResult; }
|
||||
set { innerAsyncResult = value; }
|
||||
}
|
||||
|
||||
internal Stream WriteStream {
|
||||
get { return writeStream; }
|
||||
}
|
||||
|
||||
internal HttpWebResponse Response {
|
||||
get { return response; }
|
||||
}
|
||||
|
||||
internal byte [] Buffer {
|
||||
get { return buffer; }
|
||||
}
|
||||
|
||||
internal int Offset {
|
||||
get { return offset; }
|
||||
}
|
||||
|
||||
internal int Size {
|
||||
get { return size; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
155
mcs/class/System/System.Net/WebCompletionSource.cs
Normal file
155
mcs/class/System/System.Net/WebCompletionSource.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
//
|
||||
// WebCompletionSource.cs
|
||||
//
|
||||
// Author:
|
||||
// Martin Baulig <mabaul@microsoft.com>
|
||||
//
|
||||
// Copyright (c) 2018 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;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.ExceptionServices;
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
class WebCompletionSource<T>
|
||||
{
|
||||
TaskCompletionSource<Result> completion;
|
||||
Result currentResult;
|
||||
|
||||
public WebCompletionSource (bool runAsync = true)
|
||||
{
|
||||
completion = new TaskCompletionSource<Result> (
|
||||
runAsync ?
|
||||
TaskCreationOptions.RunContinuationsAsynchronously :
|
||||
TaskCreationOptions.None);
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide a non-blocking way of getting the current status.
|
||||
*
|
||||
* We are using `TaskCreationOptions.RunContinuationsAsynchronously`
|
||||
* to prevent any user continuations from being run during the
|
||||
* `TrySet*()` methods - to make these safe to be called while holding
|
||||
* internal locks.
|
||||
*
|
||||
*/
|
||||
internal Result CurrentResult => currentResult;
|
||||
|
||||
internal Status CurrentStatus => currentResult?.Status ?? Status.Running;
|
||||
|
||||
internal Task Task => completion.Task;
|
||||
|
||||
public bool TrySetCompleted (T argument)
|
||||
{
|
||||
var result = new Result (argument);
|
||||
if (Interlocked.CompareExchange (ref currentResult, result, null) != null)
|
||||
return false;
|
||||
return completion.TrySetResult (result);
|
||||
}
|
||||
|
||||
public bool TrySetCompleted ()
|
||||
{
|
||||
var result = new Result (Status.Completed, null);
|
||||
if (Interlocked.CompareExchange (ref currentResult, result, null) != null)
|
||||
return false;
|
||||
return completion.TrySetResult (result);
|
||||
}
|
||||
|
||||
public bool TrySetCanceled ()
|
||||
{
|
||||
return TrySetCanceled (new OperationCanceledException ());
|
||||
}
|
||||
|
||||
public bool TrySetCanceled (OperationCanceledException error)
|
||||
{
|
||||
var result = new Result (Status.Canceled, ExceptionDispatchInfo.Capture (error));
|
||||
if (Interlocked.CompareExchange (ref currentResult, result, null) != null)
|
||||
return false;
|
||||
return completion.TrySetResult (result);
|
||||
}
|
||||
|
||||
public bool TrySetException (Exception error)
|
||||
{
|
||||
var result = new Result (Status.Faulted, ExceptionDispatchInfo.Capture (error));
|
||||
if (Interlocked.CompareExchange (ref currentResult, result, null) != null)
|
||||
return false;
|
||||
return completion.TrySetResult (result);
|
||||
}
|
||||
|
||||
public void ThrowOnError ()
|
||||
{
|
||||
if (!completion.Task.IsCompleted)
|
||||
return;
|
||||
completion.Task.Result.Error?.Throw ();
|
||||
}
|
||||
|
||||
public async Task<T> WaitForCompletion ()
|
||||
{
|
||||
var result = await completion.Task.ConfigureAwait (false);
|
||||
if (result.Status == Status.Completed)
|
||||
return (T)result.Argument;
|
||||
// This will always throw once we get here.
|
||||
result.Error.Throw ();
|
||||
throw new InvalidOperationException ("Should never happen.");
|
||||
}
|
||||
|
||||
internal enum Status : int {
|
||||
Running,
|
||||
Completed,
|
||||
Canceled,
|
||||
Faulted
|
||||
}
|
||||
|
||||
internal class Result
|
||||
{
|
||||
public Status Status {
|
||||
get;
|
||||
}
|
||||
|
||||
public bool Success => Status == Status.Completed;
|
||||
|
||||
public ExceptionDispatchInfo Error {
|
||||
get;
|
||||
}
|
||||
|
||||
public T Argument {
|
||||
get;
|
||||
}
|
||||
|
||||
public Result (T argument)
|
||||
{
|
||||
Status = Status.Completed;
|
||||
Argument = argument;
|
||||
}
|
||||
|
||||
public Result (Status state, ExceptionDispatchInfo error)
|
||||
{
|
||||
Status = state;
|
||||
Error = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WebCompletionSource : WebCompletionSource<object>
|
||||
{
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user